On Wed, Jun 25, 2008 at 9:37 PM, Eli Zaretskii <[EMAIL PROTECTED]> wrote:
>> Date: Wed, 25 Jun 2008 20:19:39 +0400
>> From: "Vitaly Murashev" <[EMAIL PROTECTED]>
>>
>> I found a bug in GNU Make 3.81 on MS Windows. So let me discuss it and
>> suggest a patch.
>
> Thanks.  Your code is generally OK, but, unless I'm missing something,
> it has a few deficiencies:
>
>  . It doesn't add an explicit drive letter to file names such as
>    "/foo/bar", and generally treats such names incorrectly.

You are right, and i suppose that the best way is to keep original GNU
Make behavior intact for this case.
E.g. "/foo/bar" must be treated as full qualified path even on MS Windows.
And my fix must affects only paths which are not prefixed with '/'.

>
>  . It doesn't produce fully qualified file names from drive-relative
>    names such as "d:foo/bar".

Not really. My patch produces the same output for "d:foo/bar"
and for "d:/foo/bar", the result is "d:/foo/bar"

>
>  . It assumes Windows file names use only `/' as directory separator
>    character, while in reality there could be `\' as well.

Yes, it does, but before my patch it assumes the same. And as i can
understand it is a common behavior for GNU Make. Even the 'current
directory'-variable internally uses '/' as a path separator. So i
don't like to fix this issue.
- - - - -

Please note, that the main goal of my patch is to fix code like this:

DIR_HERE = $(abspath $(dir $(lastword $(MAKEFILE_LIST))))

This code on MS Windows works incorrectly if it is invoked inside a
makefile which has been included from another makefile via full
qualified path to it. For example, we have two makefiles in the same
directory:
"d:\devl\test\makefile" and "d:\devl\test\test.mak"

'makefile' has the next code:
---
DIR_HERE = $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
$(info makefile, DIR_HERE=$(DIR_HERE))
include $(DIR_HERE)/test.mak
---

'test.mak' has the next code:
---
$(info test.mak, DIR_HERE=$(DIR_HERE))
---

Output without my patch:
---
D:\devl\test>make
makefile, DIR_HERE=D:/devl/test
test.mak, DIR_HERE=D:/devl/test/D:/devl/test
make: *** No targets.  Stop.
---

Output with my patch:
---
D:\devl\test>make_msvc.net2003.exe
makefile, DIR_HERE=D:/devl/test
test.mak, DIR_HERE=D:/devl/test
make_msvc.net2003.exe: *** No targets.  Stop.
---

Reworked patch is in attachment.
Thanks.
--- function.c	2006-04-01 11:36:40.000000000 +0400
+++ function.c.fixed	2008-06-26 14:23:24.000000000 +0400
@@ -1883,13 +1883,18 @@
 {
   char *dest;
   const char *start, *end, *apath_limit;
+  int prefix_offset = 1;
 
   if (name[0] == '\0' || apath == NULL)
     return NULL;
 
   apath_limit = apath + GET_PATH_MAX;
 
-  if (name[0] != '/')
+  if (name[0] != '/'
+#ifdef WINDOWS32
+     && name[1] != ':'
+#endif
+  )
     {
       /* It is unlikely we would make it until here but just to make sure. */
       if (!starting_directory)
@@ -1901,8 +1906,22 @@
     }
   else
     {
-      apath[0] = '/';
-      dest = apath + 1;
+#ifdef WINDOWS32
+      if(name[1] == ':')
+      {
+        apath[0] = name[0];
+        apath[1] = ':';
+        apath[2] = '/';
+        dest = apath + 3;
+        prefix_offset = 3;
+        name += 2;
+      }
+      else
+#endif
+      {
+        apath[0] = '/';
+        dest = apath + 1;
+      }
     }
 
   for (start = end = name; *start != '\0'; start = end)
@@ -1926,7 +1945,7 @@
       else if (len == 2 && start[0] == '.' && start[1] == '.')
 	{
 	  /* Back up to previous component, ignore if at root already.  */
-	  if (dest > apath + 1)
+	  if (dest > apath + prefix_offset)
 	    while ((--dest)[-1] != '/');
 	}
       else
_______________________________________________
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make

Reply via email to