Hello! The builtin function abspath does not consider drive letters. Therefore, I think it will break not only on OS/2 but also on DOS or Win* systems. And I suspect it won't work on VMS, too.
I've written a patch to handle drive letters. If anybody has a better solution, please let me know. Just for curiosity: I found this bug after I was told that a specific Makefile worked with 3.81 beta 1 but not 3.81 beta 3. That Makefile defines abspath as abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1))) but this definition seems to be ignored by 3.81 beta 3? (I don't understand what that line is exactly doing, though). Andreas -------------------------------------------- --- old/make-3.81beta3/function.c Mon Jun 27 03:01:06 2005 +++ gnu/make-3.81beta3/function.c Sun Jul 24 16:02:08 2005 @@ -1758,6 +1758,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 ('/'). */ @@ -1767,12 +1783,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) @@ -1784,8 +1804,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) @@ -1793,11 +1840,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; @@ -1809,13 +1856,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; @@ -1831,6 +1893,10 @@ --dest; *dest = '\0'; + +#if HAVE_DOS_PATHS + apath = apath_orig; +#endif return apath; } -------------------------------------------- _______________________________________________ Bug-make mailing list Bug-make@gnu.org http://lists.gnu.org/mailman/listinfo/bug-make