This is a discussion on Re: patch(1) w/paths containing spaces within the mailing.openbsd.tech forums, part of the OpenBSD category; --> On Tue, 26 Oct 2004 08:54:13 +0200 (CEST) Otto Moerbeek <otto@drijf.net> wrote: > > > - cvs also uses ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| On Tue, 26 Oct 2004 08:54:13 +0200 (CEST) Otto Moerbeek <otto@drijf.net> wrote: > > > - cvs also uses a slightly different date string plus a "<tab>revision" > > > > Yes, but patch parses the filename from the "Index:" line from > > cvs-generated diffs, so I don't think this matters. > > The Index: line is optional, and thins are also dependent if filenames > mentioned do exist or not. Check > <http://www.opengroup.org/onlinepubs/000095399/utilities/patch.html> (you > are wrong if you think standards are there to make life simple) Okay > I have this diff in my tree, which is supposed to handle any funny > character in pathnames _except_ tabs. I was not able to find a simple, > robust way to handle tabs. The approach I took made some assumptions that won't really work, now that I think about it. I think your handling of tabs is the simplest solution so far, but I think any other space character should break the loop, not just a tab when one is present. So maybe this, Index: util.c ================================================== ================= RCS file: /cvs/src/usr.bin/patch/util.c,v retrieving revision 1.28 diff -u -p -r1.28 util.c --- util.c 5 Aug 2004 21:47:24 -0000 1.28 +++ util.c 27 Oct 2004 04:18:20 -0000 @@ -333,7 +333,7 @@ char * fetchname(const char *at, bool *exists, int strip_leading) { char *fullname, *name, *t; - int sleading; + int sleading, tab; struct stat filestat; if (at == NULL || *at == '\0') @@ -349,8 +349,10 @@ fetchname(const char *at, bool *exists, return NULL; name = fullname = t = savestr(at); + tab = strchr(t, '\t') != NULL; /* Strip off up to `strip_leading' path components and NUL terminate. */ - for (sleading = strip_leading; *t != '\0' && !isspace(*t); t++) { + for (sleading = strip_leading; *t != '\0' && (!isspace(*t) || + (tab && *t == ' ')); t++) { if (t[0] == '/' && t[1] != '/' && t[1] != '\0') if (--sleading >= 0) name = t + 1; It obviously fails on the following two cases, but I would like to think they are not very common. --- a really/long and/strange filename.txt Sun Oct 24 20:51:25 2004 +++ t/b Sun Oct 24 20:51:32 2004 --- a filename Sun Oct 24 20:51:25 2004 +++ t/b Sun Oct 24 20:51:32 2004 |