Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/make make: warn about malformed patterns in ':M', ':...



details:   https://anonhg.NetBSD.org/src/rev/46cca6ed1d78
branches:  trunk
changeset: 376584:46cca6ed1d78
user:      rillig <rillig%NetBSD.org@localhost>
date:      Fri Jun 23 04:56:54 2023 +0000

description:
make: warn about malformed patterns in ':M', ':N' and '.if make(...)'

These patterns shouldn't occur in practice, as their results are tricky
to predict.  Generate a warning for now, and maybe an error later.

Reviewed by sjg@.

diffstat:

 usr.bin/make/cond.c                             |  17 +++++++--
 usr.bin/make/dir.c                              |   8 ++-
 usr.bin/make/str.c                              |  43 ++++++++++++++++--------
 usr.bin/make/str.h                              |   9 ++++-
 usr.bin/make/unit-tests/cond-func-make.exp      |   1 +
 usr.bin/make/unit-tests/cond-func-make.mk       |   4 +-
 usr.bin/make/unit-tests/varmod-match-escape.exp |   2 +
 usr.bin/make/unit-tests/varmod-match-escape.mk  |   4 +-
 usr.bin/make/unit-tests/varmod-match.exp        |  12 +++++-
 usr.bin/make/unit-tests/varmod-match.mk         |  10 +++++-
 usr.bin/make/var.c                              |  16 +++++++-
 11 files changed, 93 insertions(+), 33 deletions(-)

diffs (truncated from 412 to 300 lines):

diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/cond.c
--- a/usr.bin/make/cond.c       Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/cond.c       Fri Jun 23 04:56:54 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cond.c,v 1.351 2023/06/21 04:20:20 sjg Exp $   */
+/*     $NetBSD: cond.c,v 1.352 2023/06/23 04:56:54 rillig Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -92,7 +92,7 @@
 #include "dir.h"
 
 /*     "@(#)cond.c     8.2 (Berkeley) 1/2/94"  */
-MAKE_RCSID("$NetBSD: cond.c,v 1.351 2023/06/21 04:20:20 sjg Exp $");
+MAKE_RCSID("$NetBSD: cond.c,v 1.352 2023/06/23 04:56:54 rillig Exp $");
 
 /*
  * Conditional expressions conform to this grammar:
@@ -295,10 +295,19 @@ static bool
 FuncMake(const char *targetPattern)
 {
        StringListNode *ln;
+       bool warned = false;
 
-       for (ln = opts.create.first; ln != NULL; ln = ln->next)
-               if (Str_Match(ln->datum, targetPattern))
+       for (ln = opts.create.first; ln != NULL; ln = ln->next) {
+               StrMatchResult res = Str_Match(ln->datum, targetPattern);
+               if (res.error != NULL && !warned) {
+                       warned = true;
+                       Parse_Error(PARSE_WARNING,
+                           "%s in pattern argument '%s' to function 'make'",
+                           res.error, targetPattern);
+               }
+               if (res.matched)
                        return true;
+       }
        return false;
 }
 
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/dir.c
--- a/usr.bin/make/dir.c        Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/dir.c        Fri Jun 23 04:56:54 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dir.c,v 1.281 2023/06/22 09:09:08 rillig Exp $ */
+/*     $NetBSD: dir.c,v 1.282 2023/06/23 04:56:54 rillig Exp $ */
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -138,7 +138,7 @@
 #include "job.h"
 
 /*     "@(#)dir.c      8.2 (Berkeley) 1/2/94"  */
-MAKE_RCSID("$NetBSD: dir.c,v 1.281 2023/06/22 09:09:08 rillig Exp $");
+MAKE_RCSID("$NetBSD: dir.c,v 1.282 2023/06/23 04:56:54 rillig Exp $");
 
 /*
  * A search path is a list of CachedDir structures. A CachedDir has in it the
@@ -668,8 +668,10 @@ DirMatchFiles(const char *pattern, Cache
        HashIter_InitSet(&hi, &dir->files);
        while (HashIter_Next(&hi) != NULL) {
                const char *base = hi.entry->key;
+               StrMatchResult res = Str_Match(base, pattern);
+               /* TODO: handle errors from res.error */
 
-               if (!Str_Match(base, pattern))
+               if (!res.matched)
                        continue;
 
                /*
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/str.c
--- a/usr.bin/make/str.c        Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/str.c        Fri Jun 23 04:56:54 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: str.c,v 1.97 2023/06/22 16:59:17 rillig Exp $  */
+/*     $NetBSD: str.c,v 1.98 2023/06/23 04:56:54 rillig Exp $  */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -71,7 +71,7 @@
 #include "make.h"
 
 /*     "@(#)str.c      5.8 (Berkeley) 6/1/90"  */
-MAKE_RCSID("$NetBSD: str.c,v 1.97 2023/06/22 16:59:17 rillig Exp $");
+MAKE_RCSID("$NetBSD: str.c,v 1.98 2023/06/23 04:56:54 rillig Exp $");
 
 
 static HashTable interned_strings;
@@ -316,13 +316,12 @@ in_range(char e1, char c, char e2)
  * Test if a string matches a pattern like "*.[ch]". The pattern matching
  * characters are '*', '?' and '[]', as in fnmatch(3).
  *
- * XXX: this function does not detect or report malformed patterns.
- *
  * See varmod-match.mk for examples and edge cases.
  */
-bool
+StrMatchResult
 Str_Match(const char *str, const char *pat)
 {
+       StrMatchResult res = { NULL, false };
        const char *fixed_str, *fixed_pat;
        bool asterisk, matched;
 
@@ -336,7 +335,7 @@ match_fixed_length:
        matched = false;
        for (; *pat != '\0' && *pat != '*'; str++, pat++) {
                if (*str == '\0')
-                       return false;
+                       return res;
 
                if (*pat == '?')        /* match any single character */
                        continue;
@@ -346,6 +345,9 @@ match_fixed_length:
                        pat += neg ? 2 : 1;
 
                        for (;;) {
+                               if (*pat == '\0')
+                                       res.error =
+                                           "Unfinished character list";
                                if (*pat == ']' || *pat == '\0') {
                                        if (neg)
                                                break;
@@ -354,8 +356,13 @@ match_fixed_length:
                                if (*pat == *str)
                                        break;
                                if (pat[1] == '-') {
-                                       if (pat[2] == '\0')
-                                               return neg;
+                                       if (pat[2] == '\0') {
+                                               res.error =
+                                                   "Unfinished character "
+                                                   "range";
+                                               res.matched = neg;
+                                               return res;
+                                       }
                                        if (in_range(pat[0], *str, pat[2]))
                                                break;
                                        pat += 2;
@@ -381,9 +388,11 @@ match_fixed_length:
 match_done:
        if (!asterisk) {
                if (!matched)
-                       return false;
-               if (*pat == '\0')
-                       return *str == '\0';
+                       return res;
+               if (*pat == '\0') {
+                       res.matched = *str == '\0';
+                       return res;
+               }
                asterisk = true;
        } else {
                if (!matched) {
@@ -391,8 +400,10 @@ match_done:
                        goto match_fixed_length;
                }
                if (*pat == '\0') {
-                       if (*str == '\0')
-                               return true;
+                       if (*str == '\0') {
+                               res.matched = true;
+                               return res;
+                       }
                        fixed_str += strlen(str);
                        goto match_fixed_length;
                }
@@ -400,8 +411,10 @@ match_done:
 
        while (*pat == '*')
                pat++;
-       if (*pat == '\0')
-               return true;
+       if (*pat == '\0') {
+               res.matched = true;
+               return res;
+       }
        fixed_str = str;
        fixed_pat = pat;
        goto match_fixed_length;
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/str.h
--- a/usr.bin/make/str.h        Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/str.h        Fri Jun 23 04:56:54 2023 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: str.h,v 1.16 2022/12/05 23:41:24 rillig Exp $  */
+/*     $NetBSD: str.h,v 1.17 2023/06/23 04:56:54 rillig Exp $  */
 
 /*
  Copyright (c) 2021 Roland Illig <rillig%NetBSD.org@localhost>
@@ -70,6 +70,11 @@ typedef struct SubstringWords {
        void *freeIt;
 } SubstringWords;
 
+typedef struct StrMatchResult {
+       const char *error;
+       bool matched;
+} StrMatchResult;
+
 
 MAKE_INLINE FStr
 FStr_Init(const char *str, void *freeIt)
@@ -336,7 +341,7 @@ SubstringWords_Free(SubstringWords w)
 char *str_concat2(const char *, const char *);
 char *str_concat3(const char *, const char *, const char *);
 
-bool Str_Match(const char *, const char *);
+StrMatchResult Str_Match(const char *, const char *);
 
 void Str_Intern_Init(void);
 void Str_Intern_End(void);
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/unit-tests/cond-func-make.exp
--- a/usr.bin/make/unit-tests/cond-func-make.exp        Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/unit-tests/cond-func-make.exp        Fri Jun 23 04:56:54 2023 +0000
@@ -1,3 +1,4 @@
+make: "cond-func-make.mk" line 24: warning: Unfinished character list in pattern argument '[' to function 'make'
 : via-cmdline
 : via-dot-makeflags
 exit status 0
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/unit-tests/cond-func-make.mk
--- a/usr.bin/make/unit-tests/cond-func-make.mk Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/unit-tests/cond-func-make.mk Fri Jun 23 04:56:54 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: cond-func-make.mk,v 1.4 2023/06/22 09:09:08 rillig Exp $
+# $NetBSD: cond-func-make.mk,v 1.5 2023/06/23 04:56:54 rillig Exp $
 #
 # Tests for the make() function in .if conditions, which tests whether
 # the argument has been passed as a target via the command line or later
@@ -20,7 +20,7 @@
 .  error
 .endif
 
-# TODO: warn about the malformed pattern
+# expect+1: warning: Unfinished character list in pattern argument '[' to function 'make'
 .if make([)
 .  error
 .endif
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/unit-tests/varmod-match-escape.exp
--- a/usr.bin/make/unit-tests/varmod-match-escape.exp   Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/unit-tests/varmod-match-escape.exp   Fri Jun 23 04:56:54 2023 +0000
@@ -34,6 +34,8 @@ make: "varmod-match-escape.mk" line 43: 
 Global: .MAKEFLAGS =  -r -k -d cv -d
 Global: .MAKEFLAGS =  -r -k -d cv -d 0
 make: "varmod-match-escape.mk" line 69: Dollar followed by nothing
+make: "varmod-match-escape.mk" line 110: warning: Unfinished character list in pattern '[A-]' of modifier ':M'
+make: "varmod-match-escape.mk" line 110: warning: Unfinished character list in pattern '[^A-]' of modifier ':M'
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/unit-tests/varmod-match-escape.mk
--- a/usr.bin/make/unit-tests/varmod-match-escape.mk    Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/unit-tests/varmod-match-escape.mk    Fri Jun 23 04:56:54 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-match-escape.mk,v 1.9 2023/06/22 20:36:24 rillig Exp $
+# $NetBSD: varmod-match-escape.mk,v 1.10 2023/06/23 04:56:54 rillig Exp $
 #
 # As of 2020-08-01, the :M and :N modifiers interpret backslashes differently,
 # depending on whether there was a variable expression somewhere before the
@@ -105,6 +105,8 @@ EXP.[^A-]]= a
 EXP.[^A-]]]=   a]
 
 .for pattern in [A-] [A-]] [A-]]] [^A-] [^A-]] [^A-]]]
+# expect+2: warning: Unfinished character list in pattern '[A-]' of modifier ':M'
+# expect+1: warning: Unfinished character list in pattern '[^A-]' of modifier ':M'
 .  if ${WORDS:M${pattern}} != ${EXP.${pattern}}
 .    warning ${pattern}: ${WORDS:M${pattern}} != ${EXP.${pattern}}
 .  endif
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/unit-tests/varmod-match.exp
--- a/usr.bin/make/unit-tests/varmod-match.exp  Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/unit-tests/varmod-match.exp  Fri Jun 23 04:56:54 2023 +0000
@@ -10,8 +10,16 @@ CondParser_Eval: ${:Ua \$ sign:M*$$*} !=
 Comparing "$" != "$"
 CondParser_Eval: ${:Ua \$ sign any-asterisk:M*\$*} != "any-asterisk"
 Comparing "any-asterisk" != "any-asterisk"
-make: "varmod-match.mk" line 161: Unknown modifier "]"
-make: "varmod-match.mk" line 161: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
+make: "varmod-match.mk" line 162: warning: Unfinished character list in pattern '[' of modifier ':M'
+make: "varmod-match.mk" line 162: Unknown modifier "]"
+make: "varmod-match.mk" line 162: Malformed conditional (${ ${:U\:} ${:U\:\:} :L:M[:]} != ":")
+make: "varmod-match.mk" line 205: warning: Unfinished character list in pattern 'a[' of modifier ':M'
+make: "varmod-match.mk" line 213: warning: Unfinished character list in pattern 'a[^' of modifier ':M'
+make: "varmod-match.mk" line 221: warning: Unfinished character list in pattern '[-x1-3' of modifier ':M'
+make: "varmod-match.mk" line 229: warning: Unfinished character list in pattern '*[-x1-3' of modifier ':M'
+make: "varmod-match.mk" line 238: warning: Unfinished character list in pattern '[^-x1-3' of modifier ':M'
+make: "varmod-match.mk" line 258: warning: Unfinished character range in pattern '[x-' of modifier ':M'
+make: "varmod-match.mk" line 270: warning: Unfinished character range in pattern '[^x-' of modifier ':M'
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1
diff -r 4b3f91c8af9a -r 46cca6ed1d78 usr.bin/make/unit-tests/varmod-match.mk
--- a/usr.bin/make/unit-tests/varmod-match.mk   Fri Jun 23 04:41:24 2023 +0000
+++ b/usr.bin/make/unit-tests/varmod-match.mk   Fri Jun 23 04:56:54 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: varmod-match.mk,v 1.14 2023/06/22 12:59:54 rillig Exp $
+# $NetBSD: varmod-match.mk,v 1.15 2023/06/23 04:56:54 rillig Exp $
 #
 # Tests for the :M variable modifier, which filters words that match the
 # given pattern.
@@ -156,6 +156,7 @@ WORDS=              a\b a[\]b ab
 .endif
 



Home | Main Index | Thread Index | Old Index