Bug 13042 - make(1) doesn't handle wildcards in subdirectory paths
Summary: make(1) doesn't handle wildcards in subdirectory paths
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: Simon J. Gerraty
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 1999-08-09 14:40 UTC by hyc
Modified: 2018-05-29 05:20 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description hyc 1999-08-09 14:40:01 UTC
(Yes, I'm testing on Linux. I pulled the source from the current tree on ftp.freebsd.org.)

The make program only handles wildcard expansion for simple filenames.
Dependencies of the form "dir*foo/file*bar" are not handled.

Fix: 

static int DirFindName __P((ClientData, ClientData));
-static int DirMatchFiles __P((char *, Path *, Lst));
+static int DirMatchFiles __P((char *, Lst, Path *, Lst));
 static void DirExpandCurly __P((char *, char *, Lst, Lst));
 static void DirExpandInt __P((char *, Lst, Lst));
 static int DirPrintWord __P((ClientData, ClientData));
@@ -324,16 +324,24 @@
  *-----------------------------------------------------------------------
  */
 static int
-DirMatchFiles (pattern, p, expansions)
+DirMatchFiles (pattern, path, p, expansions)
     char         *pattern;     /* Pattern to look for */
+    Lst                  path;
     Path         *p;           /* Directory to search */
     Lst                  expansions;   /* Place to store the results */
 {
     Hash_Search          search;       /* Index into the directory's table */
     Hash_Entry   *entry;       /* Current entry in the table */
     Boolean      isDot;        /* TRUE if the directory being searched is . */
+    Boolean      isWild;       /* TRUE if the pattern has wildcards */
+    char         *cp;

     isDot = (*p->name == '.' && p->name[1] == '\0');
+    isWild = Dir_HasWildcards(pattern);
+
+    if ((cp = strchr(pattern, '/'))) {
+       *cp = '\0';
+    }

     for (entry = Hash_EnumFirst(&p->files, &search);
         entry != (Hash_Entry *)NULL;
@@ -349,12 +357,27 @@
            ((entry->name[0] != '.') ||
             (pattern[0] == '.')))
        {
-           (void)Lst_AtEnd(expansions,
-                           (isDot ? estrdup(entry->name) :
+           char *s = isDot ? estrdup(entry->name) :
                             str_concat(p->name, entry->name,
-                                       STR_ADDSLASH)));
+                                       STR_ADDSLASH);
+           if (cp) {
+               LstNode ln;
+               Path *q;
+               Dir_AddDir(path, s);
+               free(s);
+               ln = Lst_Last(path);
+               q = (Path *)Lst_Datum(ln);
+               DirMatchFiles(cp+1, path, q, expansions);
+           } else {
+               (void)Lst_AtEnd(expansions, s);
+           }
+           if (!isWild)
+               break;
        }
     }
+    if (cp) {
+       *cp = '/';
+    }
     return (0);
 }

@@ -494,10 +517,11 @@
     LstNode      ln;           /* Current node */
     Path         *p;           /* Directory in the node */

+    DirMatchFiles(word, path, dot, expansions);
     if (Lst_Open(path) == SUCCESS) {
        while ((ln = Lst_Next(path)) != NILLNODE) {
            p = (Path *)Lst_Datum(ln);
-           DirMatchFiles(word, p, expansions);
+           DirMatchFiles(word, path, p, expansions);
        }
        Lst_Close(path);
     }
@@ -623,11 +647,6 @@
                DirExpandInt(word, path, expansions);
            }
        } else {
-           /*
-            * First the files in dot
-            */
-           DirMatchFiles(word, dot, expansions);
-
            /*
             * Then the files in every other directory on the path.
             */--mzVNLl2tnYqV1ZQeOdVur1DKI8zx17repyKHkZudx5youXLC
Content-Type: text/plain; name="file.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="file.diff"

--- dir.c.O     Sun Aug  8 15:33:58 1999
+++ dir.c       Mon Aug  9 05:32:19 1999
@@ -189,7 +189,7 @@
How-To-Repeat: Use a sample Makefile like:

#
foo: sub*/lib*.a
   touch foo
#
make
mkdir sub1 sub2
touch sub{1,2}/libx.a
make     <-- this should cause foo to be remade, but it doesn't.
Comment 1 Will Andrews freebsd_committer 2000-09-29 21:50:39 UTC
Responsible Changed
From-To: freebsd-bugs->will

Over to MAINTAINER.
Comment 2 Will Andrews freebsd_committer 2001-08-30 00:26:30 UTC
Responsible Changed
From-To: will->freebsd-bugs

I don't have time for make(1) anymore...
Comment 3 Baptiste Daroussin freebsd_committer 2014-06-04 17:21:20 UTC
Add bmake maintainer into CC as we have switch to bmake and I don't know if bmake is affected or not
Comment 4 Enji Cooper freebsd_committer 2015-11-10 09:37:19 UTC
This behavior still occurs; not sure if it's correct though...

$ cat pr13042.mk 
foo: sub*/lib*.a
        touch $@
$ make -f pr13042.mk                                                                                                                                              
touch foo
$ mkdir sub1 sub2
$ touch sub{1,2}/libx.a
$ make -f pr13042.mk 
`foo' is up to date.
$ make -VMAKE_VERSION
20151020
Comment 5 Eitan Adler freebsd_committer freebsd_triage 2018-05-28 19:40:53 UTC
batch change:

For bugs that match the following
-  Status Is In progress 
AND
- Untouched since 2018-01-01.
AND
- Affects Base System OR Documentation

DO:

Reset to open status.


Note:
I did a quick pass but if you are getting this email it might be worthwhile to double check to see if this bug ought to be closed.
Comment 6 Simon J. Gerraty freebsd_committer 2018-05-29 05:20:13 UTC
pre-dates switch to bmake, and the problem does not really exist if you utilize bsd.*.mk as intended.