[PATCH] Fix GnomeVFS LS parser



OK, the GnomeVFS ls -lga parser is seriously hosed by only handling one
filename at a time, but that's a different topic.
The attached patch fixes bug 163671 [1]. It makes GnomeVFS pass all
"test-parse-ls-lga" tests, and even display files named like a time or
like a year correctly in FTP directories, which was a bit tricky, since
the FTP module didn't split the string at '\n' characters before passing
it to the parser. However, since the API suggests that
gnome_vfs_parse_ls_lga can parse multiple lines ([2]), I've preferred to
add multiline detection semantics to the latter.

[1] http://bugzilla.gnome.org/show_bug.cgi?id=163671
[2] which is - I repeat - NOT true as of writing, it only sets the first
member of the passed-in filename array

-- 
Christian Neumair <chris gnome-de org>
Index: libgnomevfs/gnome-vfs-parse-ls.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-parse-ls.c,v
retrieving revision 1.13
diff -u -p -r1.13 gnome-vfs-parse-ls.c
--- libgnomevfs/gnome-vfs-parse-ls.c	8 May 2005 13:04:05 -0000	1.13
+++ libgnomevfs/gnome-vfs-parse-ls.c	14 Oct 2005 20:39:20 -0000
@@ -360,16 +360,35 @@ vfs_parse_filemode (const char *p)
 	return res;
 }
 
+static gboolean
+is_last_column (int idx,
+		int num_cols,
+		const char *carbon,
+		int column_ptr[])
+{
+	const char *p;
+
+	if (idx + 1 == num_cols) {
+		return TRUE;
+	}
+
+	p = carbon + column_ptr[idx + 1] - 1;
+	return *p == '\r' || *p == '\n';
+}
+
 static int
 vfs_parse_filedate (int idx,
 		    char *columns[],
+		    int num_cols,
+		    const char *carbon,
+		    int column_ptr[],
 		    time_t *t)
 {	/* This thing parses from idx in columns[] array */
 
 	char *p;
 	struct tm tim;
 	int d[3];
-	int	got_year = 0;
+	int got_year = 0, got_time = 0;
 	int current_mon;
 	time_t now;
     
@@ -439,14 +458,20 @@ vfs_parse_filedate (int idx,
 	}
 
 	/* Here we expect to find time and/or year */
-    
+
 	if (is_num (columns[idx])) {
-		if (is_time (columns[idx], &tim) || (got_year = is_year (columns[idx], &tim))) {
+		if ((got_time = is_time (columns[idx], &tim)) ||
+		    (got_year = is_year (columns[idx], &tim))) {
 			idx++;
 
 			/* This is a special case for ctime () or Mon DD YYYY hh:mm */
 			if (is_num (columns[idx]) && 
-			   ((got_year = is_year (columns[idx], &tim)) || is_time (columns[idx], &tim)))
+			    !is_last_column (idx, num_cols, carbon, column_ptr) && /* ensure that we don't eat two lines at once,
+										      where the first line provides a year-like
+										      filename but no year, or a time-like filename
+										      but no time */
+			    ((!got_year && (got_year = is_year (columns[idx], &tim))) ||
+			     (!got_time && (got_time = is_time (columns[idx], &tim)))))
 				idx++; /* time & year or reverse */
 		} /* only time or date */
 	}

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]