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