Sun Jul 26 22:43:17 2020 UTC ()
make(1): extract code for dynamic variable names out of Var_Parse


(rillig)
diff -r1.334 -r1.335 src/usr.bin/make/var.c

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

--- src/usr.bin/make/var.c 2020/07/26 22:19:11 1.334
+++ src/usr.bin/make/var.c 2020/07/26 22:43:16 1.335
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.334 2020/07/26 22:19:11 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.335 2020/07/26 22:43:16 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.334 2020/07/26 22:19:11 rillig Exp $"; 72static char rcsid[] = "$NetBSD: var.c,v 1.335 2020/07/26 22:43:16 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.334 2020/07/26 22:19:11 rillig Exp $"); 79__RCSID("$NetBSD: var.c,v 1.335 2020/07/26 22:43:16 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 *
@@ -3348,26 +3348,65 @@ bad_modifier: @@ -3348,26 +3348,65 @@ bad_modifier:
3348 Error("Bad modifier `:%.*s' for %s", 3348 Error("Bad modifier `:%.*s' for %s",
3349 (int)strcspn(p, ":)}"), p, st.v->name); 3349 (int)strcspn(p, ":)}"), p, st.v->name);
3350 3350
3351cleanup: 3351cleanup:
3352 *st.lengthPtr = st.cp - st.start; 3352 *st.lengthPtr = st.cp - st.start;
3353 if (st.missing_delim != '\0') 3353 if (st.missing_delim != '\0')
3354 Error("Unclosed substitution for %s (%c missing)", 3354 Error("Unclosed substitution for %s (%c missing)",
3355 st.v->name, st.missing_delim); 3355 st.v->name, st.missing_delim);
3356 free(*st.freePtr); 3356 free(*st.freePtr);
3357 *st.freePtr = NULL; 3357 *st.freePtr = NULL;
3358 return var_Error; 3358 return var_Error;
3359} 3359}
3360 3360
 3361static Boolean
 3362VarIsDynamic(GNode *ctxt, const char *varname, size_t namelen)
 3363{
 3364 if ((namelen == 1 ||
 3365 (namelen == 2 && (varname[1] == 'F' || varname[1] == 'D'))) &&
 3366 (ctxt == VAR_CMD || ctxt == VAR_GLOBAL))
 3367 {
 3368 /*
 3369 * If substituting a local variable in a non-local context,
 3370 * assume it's for dynamic source stuff. We have to handle
 3371 * this specially and return the longhand for the variable
 3372 * with the dollar sign escaped so it makes it back to the
 3373 * caller. Only four of the local variables are treated
 3374 * specially as they are the only four that will be set
 3375 * when dynamic sources are expanded.
 3376 */
 3377 switch (varname[0]) {
 3378 case '@':
 3379 case '%':
 3380 case '*':
 3381 case '!':
 3382 return TRUE;
 3383 }
 3384 return FALSE;
 3385 }
 3386
 3387 if (namelen > 2 && varname[0] == '.' &&
 3388 isupper((unsigned char) varname[1]) &&
 3389 (ctxt == VAR_CMD || ctxt == VAR_GLOBAL))
 3390 {
 3391 return strcmp(varname, ".TARGET") == 0 ||
 3392 strcmp(varname, ".ARCHIVE") == 0 ||
 3393 strcmp(varname, ".PREFIX") == 0 ||
 3394 strcmp(varname, ".MEMBER") == 0;
 3395 }
 3396
 3397 return FALSE;
 3398}
 3399
3361/*- 3400/*-
3362 *----------------------------------------------------------------------- 3401 *-----------------------------------------------------------------------
3363 * Var_Parse -- 3402 * Var_Parse --
3364 * Given the start of a variable invocation (such as $v, $(VAR), 3403 * Given the start of a variable invocation (such as $v, $(VAR),
3365 * ${VAR:Mpattern}), extract the variable name, possibly some 3404 * ${VAR:Mpattern}), extract the variable name, possibly some
3366 * modifiers and find its value by applying the modifiers to the 3405 * modifiers and find its value by applying the modifiers to the
3367 * original value. 3406 * original value.
3368 * 3407 *
3369 * Input: 3408 * Input:
3370 * str The string to parse 3409 * str The string to parse
3371 * ctxt The context for the variable 3410 * ctxt The context for the variable
3372 * flags VARE_UNDEFERR if undefineds are an error 3411 * flags VARE_UNDEFERR if undefineds are an error
3373 * VARE_WANTRES if we actually want the result 3412 * VARE_WANTRES if we actually want the result
@@ -3532,59 +3571,27 @@ Var_Parse(const char * const str, GNode  @@ -3532,59 +3571,27 @@ Var_Parse(const char * const str, GNode
3532 char name[] = {varname[0], '\0' }; 3571 char name[] = {varname[0], '\0' };
3533 v = VarFind(name, ctxt, 0); 3572 v = VarFind(name, ctxt, 0);
3534 3573
3535 if (v != NULL) { 3574 if (v != NULL) {
3536 if (varname[1] == 'D') { 3575 if (varname[1] == 'D') {
3537 extramodifiers = "H:"; 3576 extramodifiers = "H:";
3538 } else { /* F */ 3577 } else { /* F */
3539 extramodifiers = "T:"; 3578 extramodifiers = "T:";
3540 } 3579 }
3541 } 3580 }
3542 } 3581 }
3543 3582
3544 if (v == NULL) { 3583 if (v == NULL) {
3545 if ((namelen == 1 || 3584 dynamic = VarIsDynamic(ctxt, varname, namelen);
3546 (namelen == 2 && (varname[1] == 'F' || varname[1] == 'D'))) && 
3547 (ctxt == VAR_CMD || ctxt == VAR_GLOBAL)) 
3548 { 
3549 /* 
3550 * If substituting a local variable in a non-local context, 
3551 * assume it's for dynamic source stuff. We have to handle 
3552 * this specially and return the longhand for the variable 
3553 * with the dollar sign escaped so it makes it back to the 
3554 * caller. Only four of the local variables are treated 
3555 * specially as they are the only four that will be set 
3556 * when dynamic sources are expanded. 
3557 */ 
3558 switch (varname[0]) { 
3559 case '@': 
3560 case '%': 
3561 case '*': 
3562 case '!': 
3563 dynamic = TRUE; 
3564 break; 
3565 } 
3566 } else if (namelen > 2 && varname[0] == '.' && 
3567 isupper((unsigned char) varname[1]) && 
3568 (ctxt == VAR_CMD || ctxt == VAR_GLOBAL)) 
3569 { 
3570 if ((strcmp(varname, ".TARGET") == 0) || 
3571 (strcmp(varname, ".ARCHIVE") == 0) || 
3572 (strcmp(varname, ".PREFIX") == 0) || 
3573 (strcmp(varname, ".MEMBER") == 0)) 
3574 { 
3575 dynamic = TRUE; 
3576 } 
3577 } 
3578 3585
3579 if (!haveModifier) { 3586 if (!haveModifier) {
3580 /* 3587 /*
3581 * No modifiers -- have specification length so we can return 3588 * No modifiers -- have specification length so we can return
3582 * now. 3589 * now.
3583 */ 3590 */
3584 *lengthPtr = tstr - str + 1; 3591 *lengthPtr = tstr - str + 1;
3585 if (dynamic) { 3592 if (dynamic) {
3586 char *pstr = bmake_strndup(str, *lengthPtr); 3593 char *pstr = bmake_strndup(str, *lengthPtr);
3587 *freePtr = pstr; 3594 *freePtr = pstr;
3588 Buf_Destroy(&namebuf, TRUE); 3595 Buf_Destroy(&namebuf, TRUE);
3589 return pstr; 3596 return pstr;
3590 } else { 3597 } else {