[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Bug in builtin function abspath
From: |
Andreas Büning |
Subject: |
Bug in builtin function abspath |
Date: |
Fri, 26 May 2006 21:52:05 +0200 |
Hello!
make 3.81 has a new builtin function 'abspath' which doesn't support
drive letters. I mailed this to the bug-make mailing list but I got
redirected here by the maintainer:
---------------------------------------------
%% Andreas Büning <address@hidden> writes:
> ab> In July 2005 I sent an email to this list because the new builtin
> ab> function abspath does not support drive letters. I also sent a patch
> ab> to fix this. The last information I got about this issue was the
> ab> following email (24th of July, 2005) by Paul Smith stating that he
> ab> wanted to find a different solution:
> You need to work with the folks on the address@hidden mailing list to
> resolve these issues and come up with a patch which is acceptable to
> those folks (and to me... which mainly means it doesn't impact the POSIX
> versions much or at all).
---------------------------------------------
I attached a patch which works for me. I'm using OS/2, not Windows, so
if any code is added to the w32 subdirectory it won't solve the problem
for me.
Btw, I haven't subscribed to this list, so please cc all answers to me.
Thank you!
Andreas Büning
--- old/make-3.81/function.c Sat Apr 1 08:36:40 2006
+++ gnu/make-3.81/function.c Fri May 26 20:38:16 2006
@@ -1875,6 +1875,22 @@
#endif
+
+/* Return 1 if NAME is a relative file name and contains no drive letter */
+static int
+is_relpath (const char *name)
+{
+#if HAVE_DOS_PATHS
+ if (isalpha((unsigned char) name[0]) && name[1] == ':') {
+ /* it's a drive letter */
+ return 0;
+ }
+#endif
+
+ return !IS_PATHSEP(name[0]);
+}
+
+
/* Return the absolute name of file NAME which does not contain any `.',
`..' components nor any repeated path separators ('/'). */
@@ -1884,12 +1900,16 @@
char *dest;
const char *start, *end, *apath_limit;
+#if HAVE_DOS_PATHS
+ char *apath_orig = apath;
+#endif
+
if (name[0] == '\0' || apath == NULL)
return NULL;
apath_limit = apath + GET_PATH_MAX;
- if (name[0] != '/')
+ if (is_relpath(name))
{
/* It is unlikely we would make it until here but just to make sure. */
if (!starting_directory)
@@ -1901,8 +1921,35 @@
}
else
{
+#if HAVE_DOS_PATHS
+ if (name[1] == ':')
+ { /* it's a drive letter */
+ apath[0] = name[0];
+ apath[1] = ':';
+ /* "hide" the drive letter so that we don't have to care about it
below */
+ apath += 2;
+ name += 2; /* also "remove" the drive letter from name */
+ }
+
+ dest = apath;
+
+ /* We have to consider also names like "c:foo/bar". Unfortunately, this
is
+ not a "real" absolute filename and it's not simple to find out its
absolute
+ equivalent. For now we keep it as is.
+ note: apath[0] != '/' in this case! */
+ if (IS_PATHSEP(name[0]))
+ {
+ apath[0] = '/';
+ dest++;
+ }
+ else
+ {
+
+ }
+#else
apath[0] = '/';
dest = apath + 1;
+#endif
}
for (start = end = name; *start != '\0'; start = end)
@@ -1910,11 +1957,11 @@
unsigned long len;
/* Skip sequence of multiple path-separators. */
- while (*start == '/')
+ while (IS_PATHSEP(*start))
++start;
/* Find end of path component. */
- for (end = start; *end != '\0' && *end != '/'; ++end)
+ for (end = start; *end != '\0' && !IS_PATHSEP(*end); ++end)
;
len = end - start;
@@ -1926,13 +1973,28 @@
else if (len == 2 && start[0] == '.' && start[1] == '.')
{
/* Back up to previous component, ignore if at root already. */
+#if HAVE_DOS_PATHS
+ /* note that apath[0] != '/' in some very special case */
+ while(dest > apath + 1 && (--dest)[-1] != '/');
+
+ if (dest == apath + 1 && apath[0] != '/')
+ {
+ /* We can not (yet) handle this case, any volunteers to implement
a solution? ;-) */
+ return NULL;
+ }
+
+#else
if (dest > apath + 1)
while ((--dest)[-1] != '/');
+#endif
}
else
{
- if (dest[-1] != '/')
- *dest++ = '/';
+#if HAVE_DOS_PATHS
+ if (dest != apath)
+#endif
+ if (dest[-1] != '/')
+ *dest++ = '/';
if (dest + len >= apath_limit)
return NULL;
@@ -1948,6 +2010,10 @@
--dest;
*dest = '\0';
+
+#if HAVE_DOS_PATHS
+ apath = apath_orig;
+#endif
return apath;
}
- Bug in builtin function abspath,
Andreas Büning <=
- Re: Bug in builtin function abspath, Eli Zaretskii, 2006/05/26
- Re: Bug in builtin function abspath, Andreas Büning, 2006/05/27
- Re: Bug in builtin function abspath, Eli Zaretskii, 2006/05/27
- Re: Bug in builtin function abspath, Andreas Büning, 2006/05/27
- Re: Bug in builtin function abspath, Eli Zaretskii, 2006/05/27
- Re: Bug in builtin function abspath, Alessandro Vesely, 2006/05/28
- Re: Bug in builtin function abspath, Eli Zaretskii, 2006/05/28
- Re: Bug in builtin function abspath, Alessandro Vesely, 2006/05/29
- Re: Bug in builtin function abspath, Eli Zaretskii, 2006/05/29
- Re: Bug in builtin function abspath, Eli Zaretskii, 2006/05/29