Sat Oct 31 14:40:35 2020 UTC ()
make(1): extract ParseVarnameLong from Var_Parse


(rillig)
diff -r1.622 -r1.623 src/usr.bin/make/var.c

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

--- src/usr.bin/make/var.c 2020/10/31 14:12:01 1.622
+++ src/usr.bin/make/var.c 2020/10/31 14:40:34 1.623
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.622 2020/10/31 14:12:01 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.623 2020/10/31 14:40:34 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.
@@ -119,27 +119,27 @@ @@ -119,27 +119,27 @@
119#include <sys/types.h> 119#include <sys/types.h>
120#include <regex.h> 120#include <regex.h>
121#endif 121#endif
122#include <inttypes.h> 122#include <inttypes.h>
123#include <limits.h> 123#include <limits.h>
124#include <time.h> 124#include <time.h>
125 125
126#include "make.h" 126#include "make.h"
127#include "dir.h" 127#include "dir.h"
128#include "job.h" 128#include "job.h"
129#include "metachar.h" 129#include "metachar.h"
130 130
131/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ 131/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
132MAKE_RCSID("$NetBSD: var.c,v 1.622 2020/10/31 14:12:01 rillig Exp $"); 132MAKE_RCSID("$NetBSD: var.c,v 1.623 2020/10/31 14:40:34 rillig Exp $");
133 133
134#define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1) 134#define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1)
135#define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2) 135#define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2)
136#define VAR_DEBUG3(fmt, arg1, arg2, arg3) DEBUG3(VAR, fmt, arg1, arg2, arg3) 136#define VAR_DEBUG3(fmt, arg1, arg2, arg3) DEBUG3(VAR, fmt, arg1, arg2, arg3)
137#define VAR_DEBUG4(fmt, arg1, arg2, arg3, arg4) DEBUG4(VAR, fmt, arg1, arg2, arg3, arg4) 137#define VAR_DEBUG4(fmt, arg1, arg2, arg3, arg4) DEBUG4(VAR, fmt, arg1, arg2, arg3, arg4)
138 138
139ENUM_FLAGS_RTTI_3(VarEvalFlags, 139ENUM_FLAGS_RTTI_3(VarEvalFlags,
140 VARE_UNDEFERR, VARE_WANTRES, VARE_ASSIGN); 140 VARE_UNDEFERR, VARE_WANTRES, VARE_ASSIGN);
141 141
142/* 142/*
143 * This lets us tell if we have replaced the original environ 143 * This lets us tell if we have replaced the original environ
144 * (which we cannot free). 144 * (which we cannot free).
145 */ 145 */
@@ -3497,26 +3497,165 @@ ParseVarnameShort(char const startc, con @@ -3497,26 +3497,165 @@ ParseVarnameShort(char const startc, con
3497 if (DEBUG(LINT) && *out_FALSE_val == var_Error) { 3497 if (DEBUG(LINT) && *out_FALSE_val == var_Error) {
3498 Parse_Error(PARSE_FATAL, "Variable \"%s\" is undefined", name); 3498 Parse_Error(PARSE_FATAL, "Variable \"%s\" is undefined", name);
3499 *out_FALSE_res = VPR_UNDEF_MSG; 3499 *out_FALSE_res = VPR_UNDEF_MSG;
3500 return FALSE; 3500 return FALSE;
3501 } 3501 }
3502 *out_FALSE_res = eflags & VARE_UNDEFERR ? VPR_UNDEF_SILENT : VPR_OK; 3502 *out_FALSE_res = eflags & VARE_UNDEFERR ? VPR_UNDEF_SILENT : VPR_OK;
3503 return FALSE; 3503 return FALSE;
3504 } 3504 }
3505 3505
3506 *out_TRUE_var = v; 3506 *out_TRUE_var = v;
3507 return TRUE; 3507 return TRUE;
3508} 3508}
3509 3509
 3510/* Parse a long variable name enclosed in braces or parentheses such as $(VAR)
 3511 * or ${VAR}, up to the closing brace or parenthesis, or in the case of
 3512 * ${VAR:Modifiers}, up to the ':' that starts the modifiers.
 3513 * Return whether to continue parsing. */
 3514static Boolean
 3515ParseVarnameLong(
 3516 const char **const pp,
 3517 char const startc,
 3518 GNode *const ctxt,
 3519 VarEvalFlags const eflags,
 3520
 3521 VarParseResult *const out_FALSE_res,
 3522 const char **const out_FALSE_val,
 3523 void **const out_FALSE_freePtr,
 3524
 3525 char *const out_TRUE_endc,
 3526 const char **const out_TRUE_p,
 3527 Var **const out_TRUE_v,
 3528 Boolean *const out_TRUE_haveModifier,
 3529 const char **const out_TRUE_extraModifiers,
 3530 Boolean *const out_TRUE_dynamic,
 3531 VarExprFlags *const out_TRUE_exprFlags
 3532) {
 3533 size_t namelen;
 3534 char *varname;
 3535 Var *v;
 3536 Boolean haveModifier;
 3537 Boolean dynamic = FALSE;
 3538
 3539 const char *const start = *pp;
 3540 char endc = startc == '(' ? ')' : '}';
 3541
 3542 const char *p = start + 2;
 3543 varname = ParseVarname(&p, startc, endc, ctxt, eflags, &namelen);
 3544
 3545 if (*p == ':') {
 3546 haveModifier = TRUE;
 3547 } else if (*p == endc) {
 3548 haveModifier = FALSE;
 3549 } else {
 3550 Parse_Error(PARSE_FATAL, "Unclosed variable \"%s\"", varname);
 3551 *pp = p;
 3552 free(varname);
 3553 *out_FALSE_val = var_Error;
 3554 *out_FALSE_res = VPR_PARSE_MSG;
 3555 return FALSE;
 3556 }
 3557
 3558 v = VarFind(varname, ctxt, TRUE);
 3559
 3560 /* At this point, p points just after the variable name,
 3561 * either at ':' or at endc. */
 3562
 3563 /*
 3564 * Check also for bogus D and F forms of local variables since we're
 3565 * in a local context and the name is the right length.
 3566 */
 3567 if (v == NULL && ctxt != VAR_CMDLINE && ctxt != VAR_GLOBAL &&
 3568 namelen == 2 && (varname[1] == 'F' || varname[1] == 'D') &&
 3569 strchr("@%?*!<>", varname[0]) != NULL)
 3570 {
 3571 /*
 3572 * Well, it's local -- go look for it.
 3573 */
 3574 char name[] = { varname[0], '\0' };
 3575 v = VarFind(name, ctxt, 0);
 3576
 3577 if (v != NULL) {
 3578 if (varname[1] == 'D') {
 3579 *out_TRUE_extraModifiers = "H:";
 3580 } else { /* F */
 3581 *out_TRUE_extraModifiers = "T:";
 3582 }
 3583 }
 3584 }
 3585
 3586 if (v == NULL) {
 3587 dynamic = VarIsDynamic(ctxt, varname, namelen);
 3588
 3589 if (!haveModifier) {
 3590 p++; /* skip endc */
 3591 *pp = p;
 3592 if (dynamic) {
 3593 char *pstr = bmake_strsedup(start, p);
 3594 free(varname);
 3595 *out_FALSE_res = VPR_OK;
 3596 *out_FALSE_freePtr = pstr;
 3597 *out_FALSE_val = pstr;
 3598 return FALSE;
 3599 }
 3600
 3601 if ((eflags & VARE_UNDEFERR) && (eflags & VARE_WANTRES) &&
 3602 DEBUG(LINT))
 3603 {
 3604 Parse_Error(PARSE_FATAL, "Variable \"%s\" is undefined",
 3605 varname);
 3606 free(varname);
 3607 *out_FALSE_res = VPR_UNDEF_MSG;
 3608 *out_FALSE_val = var_Error;
 3609 return FALSE;
 3610 }
 3611
 3612 if (eflags & VARE_UNDEFERR) {
 3613 free(varname);
 3614 *out_FALSE_res = VPR_UNDEF_SILENT;
 3615 *out_FALSE_val = var_Error;
 3616 return FALSE;
 3617 }
 3618
 3619 free(varname);
 3620 *out_FALSE_res = VPR_OK;
 3621 *out_FALSE_val = varUndefined;
 3622 return FALSE;
 3623 }
 3624
 3625 /* The variable expression is based on an undefined variable.
 3626 * Nevertheless it needs a Var, for modifiers that access the
 3627 * variable name, such as :L or :?.
 3628 *
 3629 * Most modifiers leave this expression in the "undefined" state
 3630 * (VEF_UNDEF), only a few modifiers like :D, :U, :L, :P turn this
 3631 * undefined expression into a defined expression (VEF_DEF).
 3632 *
 3633 * At the end, after applying all modifiers, if the expression
 3634 * is still undefined, Var_Parse will return an empty string
 3635 * instead of the actually computed value. */
 3636 v = VarNew(varname, varname, "", 0);
 3637 *out_TRUE_exprFlags = VEF_UNDEF;
 3638 } else
 3639 free(varname);
 3640
 3641 *out_TRUE_endc = endc;
 3642 *out_TRUE_p = p;
 3643 *out_TRUE_v = v;
 3644 *out_TRUE_haveModifier = haveModifier;
 3645 *out_TRUE_dynamic = dynamic;
 3646 return TRUE;
 3647}
 3648
3510/*- 3649/*-
3511 *----------------------------------------------------------------------- 3650 *-----------------------------------------------------------------------
3512 * Var_Parse -- 3651 * Var_Parse --
3513 * Given the start of a variable expression (such as $v, $(VAR), 3652 * Given the start of a variable expression (such as $v, $(VAR),
3514 * ${VAR:Mpattern}), extract the variable name, possibly some 3653 * ${VAR:Mpattern}), extract the variable name, possibly some
3515 * modifiers and find its value by applying the modifiers to the 3654 * modifiers and find its value by applying the modifiers to the
3516 * original value. 3655 * original value.
3517 * 3656 *
3518 * When parsing a condition in ParseEmptyArg, pp may also point to 3657 * When parsing a condition in ParseEmptyArg, pp may also point to
3519 * the "y" of "empty(VARNAME:Modifiers)", which is syntactically 3658 * the "y" of "empty(VARNAME:Modifiers)", which is syntactically
3520 * identical. 3659 * identical.
3521 * 3660 *
3522 * Input: 3661 * Input:
@@ -3579,130 +3718,38 @@ Var_Parse(const char **pp, GNode *ctxt,  @@ -3579,130 +3718,38 @@ Var_Parse(const char **pp, GNode *ctxt,
3579 Enum_FlagsToString(eflags_str, sizeof eflags_str, eflags, 3718 Enum_FlagsToString(eflags_str, sizeof eflags_str, eflags,
3580 VarEvalFlags_ToStringSpecs)); 3719 VarEvalFlags_ToStringSpecs));
3581 3720
3582 *freePtr = NULL; 3721 *freePtr = NULL;
3583 extramodifiers = NULL; /* extra modifiers to apply first */ 3722 extramodifiers = NULL; /* extra modifiers to apply first */
3584 dynamic = FALSE; 3723 dynamic = FALSE;
3585 3724
3586 /* Appease GCC, which thinks that the variable might not be 3725 /* Appease GCC, which thinks that the variable might not be
3587 * initialized. */ 3726 * initialized. */
3588 endc = '\0'; 3727 endc = '\0';
3589 3728
3590 startc = start[1]; 3729 startc = start[1];
3591 if (startc != '(' && startc != '{') { 3730 if (startc != '(' && startc != '{') {
3592 VarParseResult res; 3731 VarParseResult res;
3593 if (!ParseVarnameShort(startc, pp, ctxt, eflags, out_val, &res, &v)) 3732 if (!ParseVarnameShort(startc, pp, ctxt, eflags, out_val, &res, &v))
3594 return res; 3733 return res;
3595 haveModifier = FALSE; 3734 haveModifier = FALSE;
3596 p = start + 1; 3735 p = start + 1;
3597 } else { 3736 } else {
3598 size_t namelen; 3737 VarParseResult res;
3599 char *varname; 3738 if (!ParseVarnameLong(pp, startc, ctxt, eflags,
3600 3739 &res, out_val, freePtr,
3601 endc = startc == '(' ? ')' : '}'; 3740 &endc, &p, &v, &haveModifier, &extramodifiers,
3602 3741 &dynamic, &exprFlags))
3603 p = start + 2; 3742 return res;
3604 varname = ParseVarname(&p, startc, endc, ctxt, eflags, &namelen); 
3605 
3606 if (*p == ':') { 
3607 haveModifier = TRUE; 
3608 } else if (*p == endc) { 
3609 haveModifier = FALSE; 
3610 } else { 
3611 Parse_Error(PARSE_FATAL, "Unclosed variable \"%s\"", varname); 
3612 *pp = p; 
3613 free(varname); 
3614 *out_val = var_Error; 
3615 return VPR_PARSE_MSG; 
3616 } 
3617 
3618 v = VarFind(varname, ctxt, TRUE); 
3619 
3620 /* At this point, p points just after the variable name, 
3621 * either at ':' or at endc. */ 
3622 
3623 /* 
3624 * Check also for bogus D and F forms of local variables since we're 
3625 * in a local context and the name is the right length. 
3626 */ 
3627 if (v == NULL && ctxt != VAR_CMDLINE && ctxt != VAR_GLOBAL && 
3628 namelen == 2 && (varname[1] == 'F' || varname[1] == 'D') && 
3629 strchr("@%?*!<>", varname[0]) != NULL) 
3630 { 
3631 /* 
3632 * Well, it's local -- go look for it. 
3633 */ 
3634 char name[] = { varname[0], '\0' }; 
3635 v = VarFind(name, ctxt, 0); 
3636 
3637 if (v != NULL) { 
3638 if (varname[1] == 'D') { 
3639 extramodifiers = "H:"; 
3640 } else { /* F */ 
3641 extramodifiers = "T:"; 
3642 } 
3643 } 
3644 } 
3645 
3646 if (v == NULL) { 
3647 dynamic = VarIsDynamic(ctxt, varname, namelen); 
3648 
3649 if (!haveModifier) { 
3650 p++; /* skip endc */ 
3651 *pp = p; 
3652 if (dynamic) { 
3653 char *pstr = bmake_strsedup(start, p); 
3654 *freePtr = pstr; 
3655 free(varname); 
3656 *out_val = pstr; 
3657 return VPR_OK; 
3658 } 
3659 
3660 if ((eflags & VARE_UNDEFERR) && (eflags & VARE_WANTRES) && 
3661 DEBUG(LINT)) 
3662 { 
3663 Parse_Error(PARSE_FATAL, "Variable \"%s\" is undefined", 
3664 varname); 
3665 free(varname); 
3666 *out_val = var_Error; 
3667 return VPR_UNDEF_MSG; 
3668 } 
3669 
3670 if (eflags & VARE_UNDEFERR) { 
3671 free(varname); 
3672 *out_val = var_Error; 
3673 return VPR_UNDEF_SILENT; 
3674 } 
3675 
3676 free(varname); 
3677 *out_val = varUndefined; 
3678 return VPR_OK; 
3679 } 
3680 
3681 /* The variable expression is based on an undefined variable. 
3682 * Nevertheless it needs a Var, for modifiers that access the 
3683 * variable name, such as :L or :?. 
3684 * 
3685 * Most modifiers leave this expression in the "undefined" state 
3686 * (VEF_UNDEF), only a few modifiers like :D, :U, :L, :P turn this 
3687 * undefined expression into a defined expression (VEF_DEF). 
3688 * 
3689 * At the end, after applying all modifiers, if the expression 
3690 * is still undefined, Var_Parse will return an empty string 
3691 * instead of the actually computed value. */ 
3692 v = VarNew(varname, varname, "", 0); 
3693 exprFlags = VEF_UNDEF; 
3694 } else 
3695 free(varname); 
3696 } 3743 }
3697 3744
3698 if (v->flags & VAR_IN_USE) 3745 if (v->flags & VAR_IN_USE)
3699 Fatal("Variable %s is recursive.", v->name); 3746 Fatal("Variable %s is recursive.", v->name);
3700 3747
3701 /* 3748 /*
3702 * Before doing any modification, we have to make sure the value 3749 * Before doing any modification, we have to make sure the value
3703 * has been fully expanded. If it looks like recursion might be 3750 * has been fully expanded. If it looks like recursion might be
3704 * necessary (there's a dollar sign somewhere in the variable's value) 3751 * necessary (there's a dollar sign somewhere in the variable's value)
3705 * we just call Var_Subst to do any other substitutions that are 3752 * we just call Var_Subst to do any other substitutions that are
3706 * necessary. Note that the value returned by Var_Subst will have 3753 * necessary. Note that the value returned by Var_Subst will have
3707 * been dynamically-allocated, so it will need freeing when we 3754 * been dynamically-allocated, so it will need freeing when we
3708 * return. 3755 * return.