Sun Mar 14 20:12:16 2021 UTC ()
make: separate parsing and evaluating for modifier '::='

No functional change.


(rillig)
diff -r1.880 -r1.881 src/usr.bin/make/var.c

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

--- src/usr.bin/make/var.c 2021/03/14 20:09:26 1.880
+++ src/usr.bin/make/var.c 2021/03/14 20:12:16 1.881
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.880 2021/03/14 20:09:26 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.881 2021/03/14 20:12: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.
@@ -130,27 +130,27 @@ @@ -130,27 +130,27 @@
130#include <regex.h> 130#include <regex.h>
131#endif 131#endif
132#include <errno.h> 132#include <errno.h>
133#include <inttypes.h> 133#include <inttypes.h>
134#include <limits.h> 134#include <limits.h>
135#include <time.h> 135#include <time.h>
136 136
137#include "make.h" 137#include "make.h"
138#include "dir.h" 138#include "dir.h"
139#include "job.h" 139#include "job.h"
140#include "metachar.h" 140#include "metachar.h"
141 141
142/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ 142/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
143MAKE_RCSID("$NetBSD: var.c,v 1.880 2021/03/14 20:09:26 rillig Exp $"); 143MAKE_RCSID("$NetBSD: var.c,v 1.881 2021/03/14 20:12:16 rillig Exp $");
144 144
145typedef enum VarFlags { 145typedef enum VarFlags {
146 VFL_NONE = 0, 146 VFL_NONE = 0,
147 147
148 /* 148 /*
149 * The variable's value is currently being used by Var_Parse or 149 * The variable's value is currently being used by Var_Parse or
150 * Var_Subst. This marker is used to avoid endless recursion. 150 * Var_Subst. This marker is used to avoid endless recursion.
151 */ 151 */
152 VFL_IN_USE = 1 << 0, 152 VFL_IN_USE = 1 << 0,
153 153
154 /* 154 /*
155 * The variable comes from the environment. 155 * The variable comes from the environment.
156 * These variables are not registered in any GNode, therefore they 156 * These variables are not registered in any GNode, therefore they
@@ -3362,69 +3362,67 @@ ApplyModifier_IfElse(const char **pp, Ap @@ -3362,69 +3362,67 @@ ApplyModifier_IfElse(const char **pp, Ap
3362 * it was not already set. 3362 * it was not already set.
3363 * ::+=<str> Appends <str> to variable. 3363 * ::+=<str> Appends <str> to variable.
3364 * ::!=<cmd> Assigns output of <cmd> as the new value of 3364 * ::!=<cmd> Assigns output of <cmd> as the new value of
3365 * variable. 3365 * variable.
3366 */ 3366 */
3367static ApplyModifierResult 3367static ApplyModifierResult
3368ApplyModifier_Assign(const char **pp, ApplyModifiersState *st) 3368ApplyModifier_Assign(const char **pp, ApplyModifiersState *st)
3369{ 3369{
3370 Expr *expr = st->expr; 3370 Expr *expr = st->expr;
3371 GNode *scope; 3371 GNode *scope;
3372 char *val; 3372 char *val;
3373 VarParseResult res; 3373 VarParseResult res;
3374 3374
3375 /* TODO: separate parsing from evaluating */ 
3376 
3377 const char *mod = *pp; 3375 const char *mod = *pp;
3378 const char *op = mod + 1; 3376 const char *op = mod + 1;
3379 3377
3380 if (op[0] == '=') 3378 if (op[0] == '=')
3381 goto ok; 3379 goto ok;
3382 if ((op[0] == '!' || op[0] == '+' || op[0] == '?') && op[1] == '=') 3380 if ((op[0] == '!' || op[0] == '+' || op[0] == '?') && op[1] == '=')
3383 goto ok; 3381 goto ok;
3384 return AMR_UNKNOWN; /* "::<unrecognised>" */ 3382 return AMR_UNKNOWN; /* "::<unrecognised>" */
3385 3383
3386ok: 3384ok:
3387 if (expr->var->name.str[0] == '\0') { 3385 if (expr->var->name.str[0] == '\0') {
3388 *pp = mod + 1; 3386 *pp = mod + 1;
3389 return AMR_BAD; 3387 return AMR_BAD;
3390 } 3388 }
3391 3389
3392 scope = expr->scope; /* scope where v belongs */ 
3393 if (expr->defined == DEF_REGULAR && expr->scope != SCOPE_GLOBAL) { 
3394 Var *gv = VarFind(expr->var->name.str, expr->scope, FALSE); 
3395 if (gv == NULL) 
3396 scope = SCOPE_GLOBAL; 
3397 else 
3398 VarFreeEnv(gv); 
3399 } 
3400 
3401 switch (op[0]) { 3390 switch (op[0]) {
3402 case '+': 3391 case '+':
3403 case '?': 3392 case '?':
3404 case '!': 3393 case '!':
3405 *pp = mod + 3; 3394 *pp = mod + 3;
3406 break; 3395 break;
3407 default: 3396 default:
3408 *pp = mod + 2; 3397 *pp = mod + 2;
3409 break; 3398 break;
3410 } 3399 }
3411 3400
3412 res = ParseModifierPart(pp, st->endc, expr->eflags, st, &val); 3401 res = ParseModifierPart(pp, st->endc, expr->eflags, st, &val);
3413 if (res != VPR_OK) 3402 if (res != VPR_OK)
3414 return AMR_CLEANUP; 3403 return AMR_CLEANUP;
3415 3404
3416 (*pp)--; /* Go back to the st->endc. */ 3405 (*pp)--; /* Go back to the st->endc. */
3417 3406
 3407 scope = expr->scope; /* scope where v belongs */
 3408 if (expr->defined == DEF_REGULAR && expr->scope != SCOPE_GLOBAL) {
 3409 Var *gv = VarFind(expr->var->name.str, expr->scope, FALSE);
 3410 if (gv == NULL)
 3411 scope = SCOPE_GLOBAL;
 3412 else
 3413 VarFreeEnv(gv);
 3414 }
 3415
3418 /* XXX: Expanding the variable name at this point sounds wrong. */ 3416 /* XXX: Expanding the variable name at this point sounds wrong. */
3419 if (expr->eflags & VARE_WANTRES) { 3417 if (expr->eflags & VARE_WANTRES) {
3420 switch (op[0]) { 3418 switch (op[0]) {
3421 case '+': 3419 case '+':
3422 Var_AppendExpand(scope, expr->var->name.str, val); 3420 Var_AppendExpand(scope, expr->var->name.str, val);
3423 break; 3421 break;
3424 case '!': { 3422 case '!': {
3425 const char *errfmt; 3423 const char *errfmt;
3426 char *cmd_output = Cmd_Exec(val, &errfmt); 3424 char *cmd_output = Cmd_Exec(val, &errfmt);
3427 if (errfmt != NULL) 3425 if (errfmt != NULL)
3428 Error(errfmt, val); 3426 Error(errfmt, val);
3429 else 3427 else
3430 Var_SetExpand(scope, 3428 Var_SetExpand(scope,