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(1): remove duplicate code for parsing a va...



details:   https://anonhg.NetBSD.org/src/rev/98a1b6d69c29
branches:  trunk
changeset: 976821:98a1b6d69c29
user:      rillig <rillig%NetBSD.org@localhost>
date:      Sun Oct 04 19:36:32 2020 +0000

description:
make(1): remove duplicate code for parsing a variable name

diffstat:

 usr.bin/make/main.c    |   12 ++-
 usr.bin/make/nonints.h |   23 ++++++-
 usr.bin/make/parse.c   |  146 ++++++++++++++++++++----------------------------
 3 files changed, 87 insertions(+), 94 deletions(-)

diffs (truncated from 339 to 300 lines):

diff -r 40501a4368ed -r 98a1b6d69c29 usr.bin/make/main.c
--- a/usr.bin/make/main.c       Sun Oct 04 19:32:48 2020 +0000
+++ b/usr.bin/make/main.c       Sun Oct 04 19:36:32 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: main.c,v 1.365 2020/10/04 08:22:59 rillig Exp $        */
+/*     $NetBSD: main.c,v 1.366 2020/10/04 19:36:32 rillig Exp $        */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -122,7 +122,7 @@
 #endif
 
 /*     "@(#)main.c     8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: main.c,v 1.365 2020/10/04 08:22:59 rillig Exp $");
+MAKE_RCSID("$NetBSD: main.c,v 1.366 2020/10/04 19:36:32 rillig Exp $");
 #if defined(MAKE_NATIVE) && !defined(lint)
 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
            "The Regents of the University of California.  "
@@ -673,9 +673,10 @@
         * perform them if so. Else take them to be targets and stuff them
         * on the end of the "create" list.
         */
-       for (; argc > 1; ++argv, --argc)
-               if (Parse_IsVar(argv[1])) {
-                       Parse_DoVar(argv[1], VAR_CMD);
+       for (; argc > 1; ++argv, --argc) {
+               VarAssign var;
+               if (Parse_IsVar(argv[1], &var)) {
+                       Parse_DoVar(&var, VAR_CMD);
                } else {
                        if (!*argv[1])
                                Punt("illegal (null) argument.");
@@ -683,6 +684,7 @@
                                goto rearg;
                        Lst_Append(create, bmake_strdup(argv[1]));
                }
+       }
 
        return;
 noarg:
diff -r 40501a4368ed -r 98a1b6d69c29 usr.bin/make/nonints.h
--- a/usr.bin/make/nonints.h    Sun Oct 04 19:32:48 2020 +0000
+++ b/usr.bin/make/nonints.h    Sun Oct 04 19:36:32 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nonints.h,v 1.136 2020/10/04 14:40:13 rillig Exp $     */
+/*     $NetBSD: nonints.h,v 1.137 2020/10/04 19:36:32 rillig Exp $     */
 
 /*-
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -120,9 +120,26 @@
 char *cached_realpath(const char *, char *);
 
 /* parse.c */
+
+typedef enum VarAssignOp {
+    VAR_NORMAL,                        /* = */
+    VAR_SUBST,                 /* := */
+    VAR_SHELL,                 /* != or :sh= */
+    VAR_APPEND,                        /* += */
+    VAR_DEFAULT                        /* ?= */
+} VarAssignOp;
+
+typedef struct VarAssign {
+    const char *name;          /* unexpanded */
+    const char *nameEndDraft;  /* before operator adjustment */
+    const char *eq;            /* the '=' of the assignment operator */
+    VarAssignOp op;
+    const char *value;         /* unexpanded */
+} VarAssign;
+
 void Parse_Error(int, const char *, ...) MAKE_ATTR_PRINTFLIKE(2, 3);
-Boolean Parse_IsVar(const char *);
-void Parse_DoVar(const char *, GNode *);
+Boolean Parse_IsVar(const char *, VarAssign *out_var);
+void Parse_DoVar(VarAssign *, GNode *);
 void Parse_AddIncludeDir(const char *);
 void Parse_File(const char *, int);
 void Parse_Init(void);
diff -r 40501a4368ed -r 98a1b6d69c29 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c      Sun Oct 04 19:32:48 2020 +0000
+++ b/usr.bin/make/parse.c      Sun Oct 04 19:36:32 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parse.c,v 1.355 2020/10/04 19:21:13 rillig Exp $       */
+/*     $NetBSD: parse.c,v 1.356 2020/10/04 19:36:32 rillig Exp $       */
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -131,7 +131,7 @@
 #include "pathnames.h"
 
 /*     "@(#)parse.c    8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.355 2020/10/04 19:21:13 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.356 2020/10/04 19:36:32 rillig Exp $");
 
 /* types and constants */
 
@@ -204,14 +204,6 @@
     Attribute          /* Generic attribute */
 } ParseSpecial;
 
-typedef enum VarAssignOp {
-    VAR_NORMAL,                        /* = */
-    VAR_SUBST,                 /* := */
-    VAR_SHELL,                 /* != or :sh= */
-    VAR_APPEND,                        /* += */
-    VAR_DEFAULT                        /* ?= */
-} VarAssignOp;
-
 /* result data */
 
 /*
@@ -1672,15 +1664,15 @@
        Lst_Free(curTargs);
 }
 
-/* See if the given string is a variable assignment, consisting of a
- * single-word variable name, optional whitespace, an assignment operator,
- * optional whitespace and the variable value.
+/* Parse a variable assignment, consisting of a single-word variable name,
+ * optional whitespace, an assignment operator, optional whitespace and the
+ * variable value.
  *
  * Used for both lines in a file and command line arguments. */
 Boolean
-Parse_IsVar(const char *p)
+Parse_IsVar(const char *p, VarAssign *out_var)
 {
-    Boolean wasSpace = FALSE;  /* set TRUE if found a space */
+    const char *firstSpace = NULL;
     char ch;
     int level = 0;
 
@@ -1688,6 +1680,8 @@
     while (*p == ' ' || *p == '\t')
        p++;
 
+    out_var->name = p;
+
     /* Scan for one of the assignment operators outside a variable expansion */
     while ((ch = *p++) != 0) {
        if (ch == '(' || ch == '{') {
@@ -1698,75 +1692,58 @@
            level--;
            continue;
        }
+
        if (level != 0)
            continue;
-       while (ch == ' ' || ch == '\t') {
+
+       if (ch == ' ' || ch == '\t')
+           if (firstSpace == NULL)
+               firstSpace = p - 1;
+       while (ch == ' ' || ch == '\t')
            ch = *p++;
-           wasSpace = TRUE;
-       }
+
 #ifdef SUNSHCMD
        if (ch == ':' && strncmp(p, "sh", 2) == 0) {
            p += 2;
            continue;
        }
 #endif
-       if (ch == '=')
+       if (ch == '=') {
+           out_var->eq = p - 1;
+           out_var->nameEndDraft = firstSpace != NULL ? firstSpace : p - 1;
+           out_var->op = VAR_NORMAL;
+           cpp_skip_whitespace(&p);
+           out_var->value = p;
            return TRUE;
-       if (*p == '=' && (ch == '+' || ch == ':' || ch == '?' || ch == '!'))
+       }
+       if (*p == '=' && (ch == '+' || ch == ':' || ch == '?' || ch == '!')) {
+           out_var->eq = p;
+           out_var->nameEndDraft = firstSpace != NULL ? firstSpace : p;
+           out_var->op = ch == '+' ? VAR_APPEND :
+                         ch == ':' ? VAR_SUBST :
+                         ch == '?' ? VAR_DEFAULT : VAR_SHELL;
+           p++;
+           cpp_skip_whitespace(&p);
+           out_var->value = p;
            return TRUE;
-       if (wasSpace)
+       }
+       if (firstSpace != NULL)
            return FALSE;
     }
 
     return FALSE;
 }
 
-/*
-* Parse the variable name, up to the assignment operator.
-* XXX Rather than counting () and {} we should look for $ and
-* then expand the variable.
-*/
-static const char *
-ParseVarname(const char **pp)
+static Boolean
+ParseVarassignOp(VarAssign *var,
+                const char **out_op, const char **inout_name,
+                VarAssignOp *out_type, void **inout_name_freeIt, GNode *ctxt)
 {
-    const char *p = *pp;
-    const char *nameEnd = NULL;
-    int depth;
-
-    for (depth = 0; depth > 0 || *p != '='; p++) {
-       if (*p == '(' || *p == '{') {
-           depth++;
-           continue;
-       }
-       if (*p == ')' || *p == '}') {
-           depth--;
-           continue;
-       }
-       if (depth == 0 && ch_isspace(*p)) {
-           if (nameEnd == NULL)
-               nameEnd = p;
-       }
-    }
-
-    if (nameEnd == NULL)
-       nameEnd = p;
-
-    *pp = p;
-    return nameEnd;
-}
-
-static Boolean
-ParseVarassignOp(const char *p, const char *const nameEnd, const char **out_op,
-                const char **inout_name, VarAssignOp *out_type,
-                void **inout_name_freeIt, GNode *ctxt)
-{
-    const char *op;
+    const char *op = var->eq;
     const char *name = *inout_name;
     void *name_freeIt = *inout_name_freeIt;
     VarAssignOp type;
 
-    op = p;                    /* points at the '=' */
-
     if (op > name && op[-1] == '+') {
        type = VAR_APPEND;
        op--;
@@ -1774,9 +1751,11 @@
     } else if (op > name && op[-1] == '?') {
        /* If the variable already has a value, we don't do anything. */
        Boolean exists;
+       const char *nameEnd;
 
        op--;
-       name = name_freeIt = bmake_strsedup(name, nameEnd < op ? nameEnd : op);
+       nameEnd = var->nameEndDraft < op ? var->nameEndDraft : op;
+       name = name_freeIt = bmake_strsedup(name, nameEnd);
        exists = Var_Exists(name, ctxt);
        if (exists) {
            free(name_freeIt);
@@ -1829,7 +1808,7 @@
 }
 
 static void
-VarAssign(VarAssignOp const type, const char *const name,
+VarAssign_Eval(VarAssignOp const type, const char *const name,
          const char *const uvalue, const char **out_avalue, char **out_evalue,
          GNode *ctxt)
 {
@@ -1933,7 +1912,7 @@
  *     ctxt            Context in which to do the assignment
  */
 void
-Parse_DoVar(const char *p, GNode *ctxt)
+Parse_DoVar(VarAssign *var, GNode *ctxt)
 {
     VarAssignOp type;
     const char *name;
@@ -1949,33 +1928,25 @@
      * as part of the variable name.  It is later corrected, as is the ':sh'
      * modifier. Of these two (nameEnd and op), the earlier one determines the
      * actual end of the variable name. */
-    const char *nameEnd, *op;
+    const char *op;
 
-    /*
-     * Skip to variable name
-     */
-    while (*p == ' ' || *p == '\t')
-       p++;
-
-    name = p;
+    name = var->name;
     name_freeIt = NULL;
 
-    nameEnd = ParseVarname(&p);
-
-    if (!ParseVarassignOp(p, nameEnd, &op, &name, &type, &name_freeIt, ctxt))
+    if (!ParseVarassignOp(var, &op, &name, &type, &name_freeIt, ctxt))
        return;



Home | Main Index | Thread Index | Old Index