Fix the quoting of MAKEFLAGS as noted in rev. 1.47.
authorJoerg Sonnenberger <joerg@dragonflybsd.org>
Wed, 26 Jan 2005 09:44:21 +0000 (09:44 +0000)
committerJoerg Sonnenberger <joerg@dragonflybsd.org>
Wed, 26 Jan 2005 09:44:21 +0000 (09:44 +0000)
This still has a slight problem with trailing backslashes
on the comment line, but that will be documented in the man page.

Written-by: Harti Brandt, harti AT freebsd DOT org
usr.bin/make/main.c
usr.bin/make/nonints.h
usr.bin/make/parse.c
usr.bin/make/str.c
usr.bin/make/str.h

index 1c95882..9ed2775 100644 (file)
@@ -38,7 +38,7 @@
  * @(#) Copyright (c) 1988, 1989, 1990, 1993 The Regents of the University of California.  All rights reserved.
  * @(#)main.c  8.3 (Berkeley) 3/19/94
  * $FreeBSD: src/usr.bin/make/main.c,v 1.35.2.10 2003/12/16 08:34:11 des Exp $
- * $DragonFly: src/usr.bin/make/main.c,v 1.47 2005/01/14 11:30:16 joerg Exp $
+ * $DragonFly: src/usr.bin/make/main.c,v 1.48 2005/01/26 09:44:21 joerg Exp $
  */
 
 /*-
@@ -145,14 +145,19 @@ static char *objdir;                      /* where we chdir'ed to */
 static void
 MFLAGS_append(const char *flag, char *arg)
 {
-
        Var_Append(MAKEFLAGS, flag, VAR_GLOBAL);
-       if (arg != NULL)
-               Var_Append(MAKEFLAGS, arg, VAR_GLOBAL);
+       if (arg != NULL) {
+               char *str = MAKEFLAGS_quote(arg);
+               Var_Append(MAKEFLAGS, str, VAR_GLOBAL);
+               free(str);
+       }
 
        Var_Append("MFLAGS", flag, VAR_GLOBAL);
-       if (arg != NULL)
-               Var_Append("MFLAGS", arg, VAR_GLOBAL);
+       if (arg != NULL) {
+               char *str = MAKEFLAGS_quote(arg);
+               Var_Append("MFLAGS", str, VAR_GLOBAL);
+               free(str);
+       }
 }
 
 /*-
@@ -341,6 +346,11 @@ rearg:     while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
         */
        for (argv += optind, argc -= optind; *argv; ++argv, --argc)
                if (Parse_IsVar(*argv)) {
+                       char *ptr = MAKEFLAGS_quote(*argv);
+
+                       Var_Append(MAKEFLAGS, ptr, VAR_GLOBAL);
+                       free(ptr);
+
                        Parse_DoVar(*argv, VAR_CMD);
                } else {
                        if (!**argv)
@@ -372,7 +382,7 @@ rearg:      while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
  *     Only those that come from the various arguments.
  */
 void
-Main_ParseArgLine(char *line)
+Main_ParseArgLine(char *line, int mflags)
 {
        char **argv;                    /* Manufactured argument vector */
        int argc;                       /* Number of arguments in argv */
@@ -384,7 +394,10 @@ Main_ParseArgLine(char *line)
        if (!*line)
                return;
 
-       argv = brk_string(line, &argc, TRUE);
+       if (mflags)
+               argv = MAKEFLAGS_break(line, &argc);
+       else
+               argv = brk_string(line, &argc, TRUE);
        MainParseArgs(argc, argv);
 }
 
@@ -619,7 +632,7 @@ main(int argc, char **argv)
         * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
         * in a different format).
         */
-       Main_ParseArgLine(getenv("MAKEFLAGS"));
+       Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
 
        MainParseArgs(argc, argv);
 
index fb78579..1ff401b 100644 (file)
  *
  *     from: @(#)nonints.h     8.3 (Berkeley) 3/19/94
  * $FreeBSD: src/usr.bin/make/nonints.h,v 1.8 1999/08/28 01:03:35 peter Exp $
- * $DragonFly: src/usr.bin/make/Attic/nonints.h,v 1.25 2005/01/08 22:27:02 okumoto Exp $
+ * $DragonFly: src/usr.bin/make/Attic/nonints.h,v 1.26 2005/01/26 09:44:21 joerg Exp $
  */
 
 /* main.c */
-void Main_ParseArgLine(char *);
+void Main_ParseArgLine(char *, int);
 char *Cmd_Exec(const char *, const char **);
 #endif /* nonints_h_33c5dafb */
index e8194ef..614be27 100644 (file)
@@ -37,7 +37,7 @@
  *
  * @(#)parse.c 8.3 (Berkeley) 3/19/94
  * $FreeBSD: src/usr.bin/make/parse.c,v 1.22.2.2 2004/07/10 08:14:42 eik Exp $
- * $DragonFly: src/usr.bin/make/parse.c,v 1.39 2005/01/24 09:38:01 okumoto Exp $
+ * $DragonFly: src/usr.bin/make/parse.c,v 1.40 2005/01/26 09:44:21 joerg Exp $
  */
 
 /*-
@@ -1046,7 +1046,7 @@ ParseDoDependency(char *line)
         * set the initial character to a null-character so the loop to
         * get sources won't get anything
         */
-       Main_ParseArgLine(line);
+       Main_ParseArgLine(line, 0);
        *line = '\0';
     } else if (specType == ExShell) {
        if (Job_ParseShell(line) != SUCCESS) {
index c254496..4fc3d6f 100644 (file)
@@ -37,7 +37,7 @@
  *
  * @(#)str.c   5.8 (Berkeley) 6/1/90
  * $FreeBSD: src/usr.bin/make/str.c,v 1.12.2.2 2004/02/23 12:10:57 ru Exp $
- * $DragonFly: src/usr.bin/make/str.c,v 1.19 2005/01/24 09:38:01 okumoto Exp $
+ * $DragonFly: src/usr.bin/make/str.c,v 1.20 2005/01/26 09:44:21 joerg Exp $
  */
 
 #include <ctype.h>
@@ -229,6 +229,105 @@ done:     argv[argc] = NULL;
        return (argv);
 }
 
+/*
+ * Quote a string for appending it to MAKEFLAGS. According to Posix the
+ * kind of quoting here is implementation-defined. This quoting must ensure
+ * that the parsing of MAKEFLAGS's contents in a sub-shell yields the same
+ * options, option arguments and macro definitions as in the calling make.
+ * We simply quote all blanks, which according to Posix are space and tab
+ * in the POSIX locale. Don't use isblank because in that case makes with
+ * different locale settings could not communicate. We must also quote
+ * backslashes obviously.
+ */
+char *
+MAKEFLAGS_quote(const char *str)
+{
+       char *ret, *q;
+       const char *p;
+
+       /* assume worst case - everything has to be quoted */
+       ret = emalloc(strlen(str) * 2 + 1);
+
+       p = str;
+       q = ret;
+       while (*p != '\0') {
+               switch (*p) {
+
+                 case ' ':
+                 case '\t':
+                       *q++ = '\\';
+                       break;
+
+                 default:
+                       break;
+               }
+               *q++ = *p++;
+       }
+       *q++ = '\0';
+       return (ret);
+}
+
+char **
+MAKEFLAGS_break(const char *str, int *pargc)
+{
+       char *q, *start;
+       int len;
+
+       /* allocate room for a copy of the string */
+       if ((len = strlen(str) + 1) > curlen)
+               buffer = erealloc(buffer, curlen = len);
+
+       start = NULL;
+       *pargc = 1;
+
+       for (q = buffer;;) {
+               switch (*str) {
+                 case ' ':
+                 case '\t':
+                       /* word separator */
+                       if (start == NULL) {
+                               /* not in a word */
+                               str++;
+                               continue;
+                       }
+                       /* FALLTHRU */
+                 case '\0':
+                       if (start == NULL)
+                               goto done;
+
+                       /* finish word */
+                       *q++ = '\0';
+                       if (argmax == *pargc) {
+                               argmax *= 2;
+                               argv = erealloc(argv,
+                                   sizeof(*argv) * (argmax + 1));
+                       }
+                       argv[(*pargc)++] = start;
+                       start = NULL;
+
+                       if (*str++ == '\0')
+                               goto done;
+                       continue;
+
+                 case '\\':
+                       if (str[1] == ' ' || str[1] == '\t')
+                               /* was a quote */
+                               str++;
+                       break;
+
+                 default:
+                       break;
+               }
+               if (start == NULL)
+                       /* start of new word */
+                       start = q;
+               *q++ = *str++;
+       }
+  done:
+       argv[(*pargc)] = NULL;
+       return (argv);
+}
+
 /*
  * Str_Match --
  *
index 9b763f4..ff761da 100644 (file)
@@ -35,7 +35,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/usr.bin/make/str.h,v 1.2 2005/01/06 13:18:58 okumoto Exp $
+ * $DragonFly: src/usr.bin/make/str.h,v 1.3 2005/01/26 09:44:21 joerg Exp $
  */
 
 #include "sprite.h"
@@ -55,6 +55,8 @@ struct Buffer;
 void str_init(void);
 char *str_concat(const char *, const char *, int);
 char **brk_string(char *, int *, Boolean);
+char *MAKEFLAGS_quote(const char *);
+char **MAKEFLAGS_break(const char *, int *);
 int Str_Match(const char *, const char *);
 const char *Str_SYSVMatch(const char *, const char *, int *);
 void Str_SYSVSubst(struct Buffer *, const char *, const char *, int);