| @@ -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" */ |
132 | MAKE_RCSID("$NetBSD: var.c,v 1.622 2020/10/31 14:12:01 rillig Exp $"); | | 132 | MAKE_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 | |
139 | ENUM_FLAGS_RTTI_3(VarEvalFlags, | | 139 | ENUM_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. */ |
| | | 3514 | static Boolean |
| | | 3515 | ParseVarnameLong( |
| | | 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. |