Re: [PATCH] Provide a dirname() function when NO_LIBGEN_H=YesPlease
From: Ramsay Jones <hidden>
Date: 2016-06-15 23:06:44
Hi Johannes, On 30/09/15 15:50, Johannes Schindelin wrote:
When there is no `libgen.h` to our disposal, we miss the `dirname()` function. So far, we only had one user of that function: credential-cache--daemon (which was only compiled when Unix sockets are available, anyway). But now we also have `builtin/am.c` as user, so we need it.
Yes, many moons ago (on my old 32-bit laptop) when I was still 'working' with MinGW I noticed this same thing while looking into providing a win32 emulation of unix sockets. So, I had to look into this at the same time. Since this didn't progress, I didn't mention the libgen issue. Anyway, I still have a 'test-libgen.c' file (attached) from back then that contains some tests. I don't quite recall what the final state of this code was, but it was intended to test _existing_ libgen implementations as well as provide a 'git' version which would work on MinGW, cygwin and linux. Note that some of the existing implementations didn't all agree on what the tests should report! I don't remember if I looked at the POSIX spec or not. So, I don't know how useful it will be - if nothing else, there are some tests! :-D HTH Ramsay Jones
quoted hunk ↗ jump to hunk
Since `dirname()` is a sibling of `basename()`, we simply put our very own `gitdirname()` implementation next to `gitbasename()` and use it if `NO_LIBGEN_H` has been set. Signed-off-by: Johannes Schindelin <redacted> --- I stumbled over the compile warning when upgrading Git for Windows to 2.6.0. There was a left-over NO_LIBGEN_H=YesPlease (which we no longer need in Git for Windows 2.x), but it did point to the fact that we use `dirname()` in builtin/am.c now, so we better have a fall-back implementation for platforms without libgen.h. I tested this implementation a bit, but I still would appreciate a few eye-balls to go over it. compat/basename.c | 26 ++++++++++++++++++++++++++ git-compat-util.h | 2 ++ 2 files changed, 28 insertions(+)diff --git a/compat/basename.c b/compat/basename.c index d8f8a3c..10dba38 100644 --- a/compat/basename.c +++ b/compat/basename.c@@ -13,3 +13,29 @@ char *gitbasename (char *path) } return (char *)base; } + +char *gitdirname(char *path) +{ + char *p = path, *slash, c; + + /* Skip over the disk name in MSDOS pathnames. */ + if (has_dos_drive_prefix(p)) + p += 2; + /* POSIX.1-2001 says dirname("/") should return "/" */ + slash = is_dir_sep(*p) ? ++p : NULL; + while ((c = *(p++))) + if (is_dir_sep(c)) { + char *tentative = p - 1; + + /* POSIX.1-2001 says to ignore trailing slashes */ + while (is_dir_sep(*p)) + p++; + if (*p) + slash = tentative; + } + + if (!slash) + return "."; + *slash = '\0'; + return path; +}diff --git a/git-compat-util.h b/git-compat-util.h index f649e81..8b01aa5 100644 --- a/git-compat-util.h +++ b/git-compat-util.h@@ -253,6 +253,8 @@ struct itimerval { #else #define basename gitbasename extern char *gitbasename(char *); +#define dirname gitdirname +extern char *gitdirname(char *); #endif #ifndef NO_ICONV
Attachments
- test-libgen.c [text/x-csrc] 6506 bytes · preview