Mon Jul 27 22:02:26 2020 UTC ()
make(1): move modifier character out of ApplyModifiersState

It is only used in the outer part of the loop to apply the modifiers.


(rillig)
diff -r1.340 -r1.341 src/usr.bin/make/var.c

cvs diff -r1.340 -r1.341 src/usr.bin/make/var.c (expand / switch to unified diff)

--- src/usr.bin/make/var.c 2020/07/27 21:54:25 1.340
+++ src/usr.bin/make/var.c 2020/07/27 22:02:26 1.341
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.340 2020/07/27 21:54:25 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.341 2020/07/27 22:02:26 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -59,34 +59,34 @@ @@ -59,34 +59,34 @@
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE. 68 * SUCH DAMAGE.
69 */ 69 */
70 70
71#ifndef MAKE_NATIVE 71#ifndef MAKE_NATIVE
72static char rcsid[] = "$NetBSD: var.c,v 1.340 2020/07/27 21:54:25 rillig Exp $"; 72static char rcsid[] = "$NetBSD: var.c,v 1.341 2020/07/27 22:02:26 rillig Exp $";
73#else 73#else
74#include <sys/cdefs.h> 74#include <sys/cdefs.h>
75#ifndef lint 75#ifndef lint
76#if 0 76#if 0
77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
78#else 78#else
79__RCSID("$NetBSD: var.c,v 1.340 2020/07/27 21:54:25 rillig Exp $"); 79__RCSID("$NetBSD: var.c,v 1.341 2020/07/27 22:02:26 rillig Exp $");
80#endif 80#endif
81#endif /* not lint */ 81#endif /* not lint */
82#endif 82#endif
83 83
84/*- 84/*-
85 * var.c -- 85 * var.c --
86 * Variable-handling functions 86 * Variable-handling functions
87 * 87 *
88 * Interface: 88 * Interface:
89 * Var_Set Set the value of a variable in the given 89 * Var_Set Set the value of a variable in the given
90 * context. The variable is created if it doesn't 90 * context. The variable is created if it doesn't
91 * yet exist. 91 * yet exist.
92 * 92 *
@@ -2043,27 +2043,26 @@ typedef struct { @@ -2043,27 +2043,26 @@ typedef struct {
2043 Var *v; 2043 Var *v;
2044 GNode *ctxt; 2044 GNode *ctxt;
2045 VarEvalFlags eflags; 2045 VarEvalFlags eflags;
2046 int *lengthPtr; 2046 int *lengthPtr;
2047 void **freePtr; 2047 void **freePtr;
2048 2048
2049 /* read-write */ 2049 /* read-write */
2050 char *nstr; 2050 char *nstr;
2051 const char *start; 2051 const char *start;
2052 const char *cp; /* The position where parsing continues 2052 const char *cp; /* The position where parsing continues
2053 * after the current modifier. */ 2053 * after the current modifier. */
2054 char termc; /* Character which terminated scan */ 2054 char termc; /* Character which terminated scan */
2055 char missing_delim; /* For error reporting */ 2055 char missing_delim; /* For error reporting */
2056 int modifier; /* that we are processing */ 
2057 2056
2058 Byte sep; /* Word separator in expansions */ 2057 Byte sep; /* Word separator in expansions */
2059 Boolean oneBigWord; /* TRUE if we will treat the variable as a 2058 Boolean oneBigWord; /* TRUE if we will treat the variable as a
2060 * single big word, even if it contains 2059 * single big word, even if it contains
2061 * embedded spaces (as opposed to the 2060 * embedded spaces (as opposed to the
2062 * usual behaviour of treating it as 2061 * usual behaviour of treating it as
2063 * several space-separated words). */ 2062 * several space-separated words). */
2064 2063
2065 /* result */ 2064 /* result */
2066 char *newStr; /* New value to return */ 2065 char *newStr; /* New value to return */
2067} ApplyModifiersState; 2066} ApplyModifiersState;
2068 2067
2069/* we now have some modifiers with long names */ 2068/* we now have some modifiers with long names */
@@ -3070,27 +3069,27 @@ ApplyModifier_SysV(const char *mod, Appl @@ -3070,27 +3069,27 @@ ApplyModifier_SysV(const char *mod, Appl
3070 * :!<cmd>! Run cmd much the same as :sh run's the 3069 * :!<cmd>! Run cmd much the same as :sh run's the
3071 * current value of the variable. 3070 * current value of the variable.
3072 * Assignment operators (see ApplyModifier_Assign). 3071 * Assignment operators (see ApplyModifier_Assign).
3073 */ 3072 */
3074static char * 3073static char *
3075ApplyModifiers(char *nstr, const char *tstr, 3074ApplyModifiers(char *nstr, const char *tstr,
3076 int const startc, int const endc, 3075 int const startc, int const endc,
3077 Var * const v, GNode * const ctxt, VarEvalFlags const eflags, 3076 Var * const v, GNode * const ctxt, VarEvalFlags const eflags,
3078 int * const lengthPtr, void ** const freePtr) 3077 int * const lengthPtr, void ** const freePtr)
3079{ 3078{
3080 ApplyModifiersState st = { 3079 ApplyModifiersState st = {
3081 startc, endc, v, ctxt, eflags, lengthPtr, freePtr, 3080 startc, endc, v, ctxt, eflags, lengthPtr, freePtr,
3082 nstr, tstr, tstr, 3081 nstr, tstr, tstr,
3083 '\0', '\0', 0, ' ', FALSE, NULL 3082 '\0', '\0', ' ', FALSE, NULL
3084 }; 3083 };
3085 3084
3086 const char *p = tstr; 3085 const char *p = tstr;
3087 while (*p != '\0' && *p != endc) { 3086 while (*p != '\0' && *p != endc) {
3088 3087
3089 if (*p == '$') { 3088 if (*p == '$') {
3090 /* 3089 /*
3091 * We may have some complex modifiers in a variable. 3090 * We may have some complex modifiers in a variable.
3092 */ 3091 */
3093 void *freeIt; 3092 void *freeIt;
3094 const char *rval; 3093 const char *rval;
3095 int rlen; 3094 int rlen;
3096 int c; 3095 int c;
@@ -3134,27 +3133,28 @@ ApplyModifiers(char *nstr, const char *t @@ -3134,27 +3133,28 @@ ApplyModifiers(char *nstr, const char *t
3134 else if (*p == '\0' && endc != '\0') { 3133 else if (*p == '\0' && endc != '\0') {
3135 Error("Unclosed variable specification after complex " 3134 Error("Unclosed variable specification after complex "
3136 "modifier (expecting '%c') for %s", st.endc, st.v->name); 3135 "modifier (expecting '%c') for %s", st.endc, st.v->name);
3137 goto out; 3136 goto out;
3138 } 3137 }
3139 continue; 3138 continue;
3140 } 3139 }
3141 apply_mods: 3140 apply_mods:
3142 if (DEBUG(VAR)) { 3141 if (DEBUG(VAR)) {
3143 fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", st.v->name, 3142 fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", st.v->name,
3144 *p, st.nstr); 3143 *p, st.nstr);
3145 } 3144 }
3146 st.newStr = var_Error; 3145 st.newStr = var_Error;
3147 switch ((st.modifier = *p)) { 3146 char modifier = *p;
 3147 switch (modifier) {
3148 case ':': 3148 case ':':
3149 { 3149 {
3150 int res = ApplyModifier_Assign(p, &st); 3150 int res = ApplyModifier_Assign(p, &st);
3151 if (res == 'b') 3151 if (res == 'b')
3152 goto bad_modifier; 3152 goto bad_modifier;
3153 if (res == 'c') 3153 if (res == 'c')
3154 goto cleanup; 3154 goto cleanup;
3155 if (res == 'd') 3155 if (res == 'd')
3156 goto default_case; 3156 goto default_case;
3157 break; 3157 break;
3158 } 3158 }
3159 case '@': 3159 case '@':
3160 if (!ApplyModifier_Loop(p, &st)) 3160 if (!ApplyModifier_Loop(p, &st))
@@ -3220,27 +3220,27 @@ ApplyModifiers(char *nstr, const char *t @@ -3220,27 +3220,27 @@ ApplyModifiers(char *nstr, const char *t
3220 case '?': 3220 case '?':
3221 if (!ApplyModifier_IfElse(p, &st)) 3221 if (!ApplyModifier_IfElse(p, &st))
3222 goto cleanup; 3222 goto cleanup;
3223 break; 3223 break;
3224#ifndef NO_REGEX 3224#ifndef NO_REGEX
3225 case 'C': 3225 case 'C':
3226 if (!ApplyModifier_Regex(p, &st)) 3226 if (!ApplyModifier_Regex(p, &st))
3227 goto cleanup; 3227 goto cleanup;
3228 break; 3228 break;
3229#endif 3229#endif
3230 case 'q': 3230 case 'q':
3231 case 'Q': 3231 case 'Q':
3232 if (p[1] == st.endc || p[1] == ':') { 3232 if (p[1] == st.endc || p[1] == ':') {
3233 st.newStr = VarQuote(st.nstr, st.modifier == 'q'); 3233 st.newStr = VarQuote(st.nstr, modifier == 'q');
3234 st.cp = p + 1; 3234 st.cp = p + 1;
3235 st.termc = *st.cp; 3235 st.termc = *st.cp;
3236 break; 3236 break;
3237 } 3237 }
3238 goto default_case; 3238 goto default_case;
3239 case 'T': 3239 case 'T':
3240 if (p[1] == st.endc || p[1] == ':') { 3240 if (p[1] == st.endc || p[1] == ':') {
3241 st.newStr = ModifyWords(st.ctxt, st.sep, st.oneBigWord, 3241 st.newStr = ModifyWords(st.ctxt, st.sep, st.oneBigWord,
3242 st.nstr, ModifyWord_Tail, NULL); 3242 st.nstr, ModifyWord_Tail, NULL);
3243 st.cp = p + 1; 3243 st.cp = p + 1;
3244 st.termc = *st.cp; 3244 st.termc = *st.cp;
3245 break; 3245 break;
3246 } 3246 }
@@ -3316,43 +3316,43 @@ ApplyModifiers(char *nstr, const char *t @@ -3316,43 +3316,43 @@ ApplyModifiers(char *nstr, const char *t
3316 { 3316 {
3317 Error("Unknown modifier '%c'", *p); 3317 Error("Unknown modifier '%c'", *p);
3318 for (st.cp = p + 1; 3318 for (st.cp = p + 1;
3319 *st.cp != ':' && *st.cp != st.endc && *st.cp != '\0'; 3319 *st.cp != ':' && *st.cp != st.endc && *st.cp != '\0';
3320 st.cp++) 3320 st.cp++)
3321 continue; 3321 continue;
3322 st.termc = *st.cp; 3322 st.termc = *st.cp;
3323 st.newStr = var_Error; 3323 st.newStr = var_Error;
3324 } 3324 }
3325 } 3325 }
3326 } 3326 }
3327 if (DEBUG(VAR)) { 3327 if (DEBUG(VAR)) {
3328 fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n", 3328 fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n",
3329 st.v->name, st.modifier, st.newStr); 3329 st.v->name, modifier, st.newStr);
3330 } 3330 }
3331 3331
3332 if (st.newStr != st.nstr) { 3332 if (st.newStr != st.nstr) {
3333 if (*st.freePtr) { 3333 if (*st.freePtr) {
3334 free(st.nstr); 3334 free(st.nstr);
3335 *st.freePtr = NULL; 3335 *st.freePtr = NULL;
3336 } 3336 }
3337 st.nstr = st.newStr; 3337 st.nstr = st.newStr;
3338 if (st.nstr != var_Error && st.nstr != varNoError) { 3338 if (st.nstr != var_Error && st.nstr != varNoError) {
3339 *st.freePtr = st.nstr; 3339 *st.freePtr = st.nstr;
3340 } 3340 }
3341 } 3341 }
3342 if (st.termc == '\0' && st.endc != '\0') { 3342 if (st.termc == '\0' && st.endc != '\0') {
3343 Error("Unclosed variable specification (expecting '%c') " 3343 Error("Unclosed variable specification (expecting '%c') "
3344 "for \"%s\" (value \"%s\") modifier %c", 3344 "for \"%s\" (value \"%s\") modifier %c",
3345 st.endc, st.v->name, st.nstr, st.modifier); 3345 st.endc, st.v->name, st.nstr, modifier);
3346 } else if (st.termc == ':') { 3346 } else if (st.termc == ':') {
3347 st.cp++; 3347 st.cp++;
3348 } 3348 }
3349 p = st.cp; 3349 p = st.cp;
3350 } 3350 }
3351out: 3351out:
3352 *st.lengthPtr = p - st.start; 3352 *st.lengthPtr = p - st.start;
3353 return st.nstr; 3353 return st.nstr;
3354 3354
3355bad_modifier: 3355bad_modifier:
3356 Error("Bad modifier `:%.*s' for %s", 3356 Error("Bad modifier `:%.*s' for %s",
3357 (int)strcspn(p, ":)}"), p, st.v->name); 3357 (int)strcspn(p, ":)}"), p, st.v->name);
3358 3358