SF.net SVN: geany: [1852] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Wed Sep 5 16:22:50 UTC 2007


Revision: 1852
          http://geany.svn.sourceforge.net/geany/?rev=1852&view=rev
Author:   ntrel
Date:     2007-09-05 09:22:50 -0700 (Wed, 05 Sep 2007)

Log Message:
-----------
Rewrite document_find_by_filename() to work when the filename
argument contains relative path elements or symlinks.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/document.c
    trunk/src/utils.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-09-04 15:39:17 UTC (rev 1851)
+++ trunk/ChangeLog	2007-09-05 16:22:50 UTC (rev 1852)
@@ -1,3 +1,10 @@
+2007-09-05  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/utils.c, src/document.c:
+   Rewrite document_find_by_filename() to work when the filename
+   argument contains relative path elements or symlinks.
+
+
 2007-09-03  Enrico Tröger  <enrico.troeger at uvena.de>
 
  * src/makefile.win32, src/ui_utils.c, src/win32.c,

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2007-09-04 15:39:17 UTC (rev 1851)
+++ trunk/src/document.c	2007-09-05 16:22:50 UTC (rev 1852)
@@ -86,27 +86,78 @@
 static gboolean update_type_keywords(ScintillaObject *sci);
 
 
-/* returns the document index which has the given filename.
- * is_tm_filename is needed when passing TagManager filenames because they are
- * dereferenced, and would not match the link filename. */
+// ignore the case of filenames and paths under WIN32, causes errors if not
+#ifdef G_OS_WIN32
+#define filenamecmp(a,b)	strcasecmp((a), (b))
+#else
+#define filenamecmp(a,b)	strcmp((a), (b))
+#endif
+
+static gint find_by_tm_filename(const gchar *filename)
+{
+	guint i;
+
+	for (i = 0; i < doc_array->len; i++)
+	{
+		TMWorkObject *tm_file = doc_list[i].tm_file;
+
+		if (tm_file == NULL || tm_file->file_name == NULL) continue;
+
+		if (filenamecmp(filename, tm_file->file_name) == 0)
+			return i;
+	}
+	return -1;
+}
+
+
+static gchar *get_real_path_from_utf8(const gchar *utf8_filename)
+{
+	gchar *locale_name = utils_get_locale_from_utf8(utf8_filename);
+	gchar *realname = tm_get_real_path(locale_name);
+
+	g_free(locale_name);
+	return realname;
+}
+
+
+/* filename is in UTF-8 for non-TagManager filenames.
+ * is_tm_filename should only be used when passing a TagManager filename,
+ * which is therefore locale-encoded and already a realpath().
+ * Returns: the document index which has the given filename. */
 gint document_find_by_filename(const gchar *filename, gboolean is_tm_filename)
 {
 	guint i;
+	gint ret = -1;
+	gchar *realname;
 
 	if (! filename) return -1;
 
-	for(i = 0; i < doc_array->len; i++)
+	if (is_tm_filename)
+		return find_by_tm_filename(filename);	// more efficient
+
+	realname = get_real_path_from_utf8(filename);	// dereference symlinks, /../ junk in path
+	if (! realname) return -1;
+
+	for (i = 0; i < doc_array->len; i++)
 	{
-		gchar *dl_fname = (is_tm_filename && doc_list[i].tm_file) ?
-							doc_list[i].tm_file->file_name : doc_list[i].file_name;
-#ifdef G_OS_WIN32
-		// ignore the case of filenames and paths under WIN32, causes errors if not
-		if (dl_fname && ! strcasecmp(dl_fname, filename)) return i;
-#else
-		if (dl_fname && utils_str_equal(dl_fname, filename)) return i;
-#endif
+		document *doc = &doc_list[i];
+		gchar *docname;
+
+		if (doc->file_name == NULL) continue;
+
+		docname = get_real_path_from_utf8(doc->file_name);
+		if (! docname) continue;
+
+		if (filenamecmp(realname, docname) == 0)
+		{
+			ret = i;
+			g_free(docname);
+			break;
+		}
+		g_free(docname);
 	}
-	return -1;
+	g_free(realname);
+	return ret;
 }
 
 
@@ -793,20 +844,16 @@
 	}
 	else
 	{
-		// filename must not be NULL when it is a new file
+		// filename must not be NULL when opening a file
 		if (filename == NULL)
 		{
 			ui_set_statusbar(_("Invalid filename"));
 			return -1;
 		}
 
+		locale_filename = g_strdup(filename);
 		// try to get the UTF-8 equivalent for the filename, fallback to filename if error
-		locale_filename = g_strdup(filename);
-#ifdef G_OS_WIN32 // on Win32 we only use locale_filename because it is already UTF8. I hope
-		utf8_filename = g_strdup(locale_filename);
-#else
 		utf8_filename = utils_get_utf8_from_locale(locale_filename);
-#endif
 
 		// if file is already open, switch to it and go
 		idx = document_find_by_filename(utf8_filename, FALSE);

Modified: trunk/src/utils.c
===================================================================
--- trunk/src/utils.c	2007-09-04 15:39:17 UTC (rev 1851)
+++ trunk/src/utils.c	2007-09-05 16:22:50 UTC (rev 1852)
@@ -623,7 +623,6 @@
 }
 
 
-/* currently unused */
 gboolean utils_is_absolute_path(const gchar *path)
 {
 	if (! path || *path == '\0')


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list