| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: var.c,v 1.758 2020/12/21 00:20:58 rillig Exp $ */ | | 1 | /* $NetBSD: var.c,v 1.759 2020/12/21 00:30:13 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. |
| @@ -121,27 +121,27 @@ | | | @@ -121,27 +121,27 @@ |
121 | #include <regex.h> | | 121 | #include <regex.h> |
122 | #endif | | 122 | #endif |
123 | #include <errno.h> | | 123 | #include <errno.h> |
124 | #include <inttypes.h> | | 124 | #include <inttypes.h> |
125 | #include <limits.h> | | 125 | #include <limits.h> |
126 | #include <time.h> | | 126 | #include <time.h> |
127 | | | 127 | |
128 | #include "make.h" | | 128 | #include "make.h" |
129 | #include "dir.h" | | 129 | #include "dir.h" |
130 | #include "job.h" | | 130 | #include "job.h" |
131 | #include "metachar.h" | | 131 | #include "metachar.h" |
132 | | | 132 | |
133 | /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ | | 133 | /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ |
134 | MAKE_RCSID("$NetBSD: var.c,v 1.758 2020/12/21 00:20:58 rillig Exp $"); | | 134 | MAKE_RCSID("$NetBSD: var.c,v 1.759 2020/12/21 00:30:13 rillig Exp $"); |
135 | | | 135 | |
136 | typedef enum VarFlags { | | 136 | typedef enum VarFlags { |
137 | VAR_NONE = 0, | | 137 | VAR_NONE = 0, |
138 | | | 138 | |
139 | /* | | 139 | /* |
140 | * The variable's value is currently being used by Var_Parse or | | 140 | * The variable's value is currently being used by Var_Parse or |
141 | * Var_Subst. This marker is used to avoid endless recursion. | | 141 | * Var_Subst. This marker is used to avoid endless recursion. |
142 | */ | | 142 | */ |
143 | VAR_IN_USE = 0x01, | | 143 | VAR_IN_USE = 0x01, |
144 | | | 144 | |
145 | /* | | 145 | /* |
146 | * The variable comes from the environment. | | 146 | * The variable comes from the environment. |
147 | * These variables are not registered in any GNode, therefore they | | 147 | * These variables are not registered in any GNode, therefore they |
| @@ -2422,27 +2422,27 @@ ApplyModifier_ShellCommand(const char ** | | | @@ -2422,27 +2422,27 @@ ApplyModifier_ShellCommand(const char ** |
2422 | const char *errfmt; | | 2422 | const char *errfmt; |
2423 | VarParseResult res; | | 2423 | VarParseResult res; |
2424 | | | 2424 | |
2425 | (*pp)++; | | 2425 | (*pp)++; |
2426 | res = ParseModifierPart(pp, '!', st->eflags, st, | | 2426 | res = ParseModifierPart(pp, '!', st->eflags, st, |
2427 | &cmd, NULL, NULL, NULL); | | 2427 | &cmd, NULL, NULL, NULL); |
2428 | if (res != VPR_OK) | | 2428 | if (res != VPR_OK) |
2429 | return AMR_CLEANUP; | | 2429 | return AMR_CLEANUP; |
2430 | | | 2430 | |
2431 | errfmt = NULL; | | 2431 | errfmt = NULL; |
2432 | if (st->eflags & VARE_WANTRES) | | 2432 | if (st->eflags & VARE_WANTRES) |
2433 | st->newVal = FStr_InitOwn(Cmd_Exec(cmd, &errfmt)); | | 2433 | st->newVal = FStr_InitOwn(Cmd_Exec(cmd, &errfmt)); |
2434 | else | | 2434 | else |
2435 | st->newVal = FStr_InitOwn(bmake_strdup("")); | | 2435 | st->newVal = FStr_InitRefer(""); |
2436 | if (errfmt != NULL) | | 2436 | if (errfmt != NULL) |
2437 | Error(errfmt, cmd); /* XXX: why still return AMR_OK? */ | | 2437 | Error(errfmt, cmd); /* XXX: why still return AMR_OK? */ |
2438 | free(cmd); | | 2438 | free(cmd); |
2439 | | | 2439 | |
2440 | ApplyModifiersState_Define(st); | | 2440 | ApplyModifiersState_Define(st); |
2441 | return AMR_OK; | | 2441 | return AMR_OK; |
2442 | } | | 2442 | } |
2443 | | | 2443 | |
2444 | /* The :range modifier generates an integer sequence as long as the words. | | 2444 | /* The :range modifier generates an integer sequence as long as the words. |
2445 | * The :range=7 modifier generates an integer sequence from 1 to 7. */ | | 2445 | * The :range=7 modifier generates an integer sequence from 1 to 7. */ |
2446 | static ApplyModifierResult | | 2446 | static ApplyModifierResult |
2447 | ApplyModifier_Range(const char **pp, const char *val, ApplyModifiersState *st) | | 2447 | ApplyModifier_Range(const char **pp, const char *val, ApplyModifiersState *st) |
2448 | { | | 2448 | { |
| @@ -2889,27 +2889,27 @@ ApplyModifier_Words(const char **pp, con | | | @@ -2889,27 +2889,27 @@ ApplyModifier_Words(const char **pp, con |
2889 | &estr, NULL, NULL, NULL); | | 2889 | &estr, NULL, NULL, NULL); |
2890 | if (res != VPR_OK) | | 2890 | if (res != VPR_OK) |
2891 | return AMR_CLEANUP; | | 2891 | return AMR_CLEANUP; |
2892 | | | 2892 | |
2893 | /* now *pp points just after the closing ']' */ | | 2893 | /* now *pp points just after the closing ']' */ |
2894 | if (**pp != ':' && **pp != st->endc) | | 2894 | if (**pp != ':' && **pp != st->endc) |
2895 | goto bad_modifier; /* Found junk after ']' */ | | 2895 | goto bad_modifier; /* Found junk after ']' */ |
2896 | | | 2896 | |
2897 | if (estr[0] == '\0') | | 2897 | if (estr[0] == '\0') |
2898 | goto bad_modifier; /* empty square brackets in ":[]". */ | | 2898 | goto bad_modifier; /* empty square brackets in ":[]". */ |
2899 | | | 2899 | |
2900 | if (estr[0] == '#' && estr[1] == '\0') { /* Found ":[#]" */ | | 2900 | if (estr[0] == '#' && estr[1] == '\0') { /* Found ":[#]" */ |
2901 | if (st->oneBigWord) { | | 2901 | if (st->oneBigWord) { |
2902 | st->newVal = FStr_InitOwn(bmake_strdup("1")); | | 2902 | st->newVal = FStr_InitRefer("1"); |
2903 | } else { | | 2903 | } else { |
2904 | Buffer buf; | | 2904 | Buffer buf; |
2905 | | | 2905 | |
2906 | Words words = Str_Words(val, FALSE); | | 2906 | Words words = Str_Words(val, FALSE); |
2907 | size_t ac = words.len; | | 2907 | size_t ac = words.len; |
2908 | Words_Free(words); | | 2908 | Words_Free(words); |
2909 | | | 2909 | |
2910 | /* 3 digits + '\0' is usually enough */ | | 2910 | /* 3 digits + '\0' is usually enough */ |
2911 | Buf_InitSize(&buf, 4); | | 2911 | Buf_InitSize(&buf, 4); |
2912 | Buf_AddInt(&buf, (int)ac); | | 2912 | Buf_AddInt(&buf, (int)ac); |
2913 | st->newVal = FStr_InitOwn(Buf_Destroy(&buf, FALSE)); | | 2913 | st->newVal = FStr_InitOwn(Buf_Destroy(&buf, FALSE)); |
2914 | } | | 2914 | } |
2915 | goto ok; | | 2915 | goto ok; |
| @@ -3167,27 +3167,27 @@ ok: | | | @@ -3167,27 +3167,27 @@ ok: |
3167 | free(cmd_output); | | 3167 | free(cmd_output); |
3168 | break; | | 3168 | break; |
3169 | } | | 3169 | } |
3170 | case '?': | | 3170 | case '?': |
3171 | if (!(st->exprFlags & VEF_UNDEF)) | | 3171 | if (!(st->exprFlags & VEF_UNDEF)) |
3172 | break; | | 3172 | break; |
3173 | /* FALLTHROUGH */ | | 3173 | /* FALLTHROUGH */ |
3174 | default: | | 3174 | default: |
3175 | Var_Set(st->var->name.str, val, ctxt); | | 3175 | Var_Set(st->var->name.str, val, ctxt); |
3176 | break; | | 3176 | break; |
3177 | } | | 3177 | } |
3178 | } | | 3178 | } |
3179 | free(val); | | 3179 | free(val); |
3180 | st->newVal = FStr_InitOwn(bmake_strdup("")); | | 3180 | st->newVal = FStr_InitRefer(""); |
3181 | return AMR_OK; | | 3181 | return AMR_OK; |
3182 | } | | 3182 | } |
3183 | | | 3183 | |
3184 | /* :_=... | | 3184 | /* :_=... |
3185 | * remember current value */ | | 3185 | * remember current value */ |
3186 | static ApplyModifierResult | | 3186 | static ApplyModifierResult |
3187 | ApplyModifier_Remember(const char **pp, const char *val, | | 3187 | ApplyModifier_Remember(const char **pp, const char *val, |
3188 | ApplyModifiersState *st) | | 3188 | ApplyModifiersState *st) |
3189 | { | | 3189 | { |
3190 | const char *mod = *pp; | | 3190 | const char *mod = *pp; |
3191 | if (!ModMatchEq(mod, "_", st->endc)) | | 3191 | if (!ModMatchEq(mod, "_", st->endc)) |
3192 | return AMR_UNKNOWN; | | 3192 | return AMR_UNKNOWN; |
3193 | | | 3193 | |
| @@ -3293,27 +3293,27 @@ ApplyModifier_SysV(const char **pp, cons | | | @@ -3293,27 +3293,27 @@ ApplyModifier_SysV(const char **pp, cons |
3293 | /* :sh */ | | 3293 | /* :sh */ |
3294 | static ApplyModifierResult | | 3294 | static ApplyModifierResult |
3295 | ApplyModifier_SunShell(const char **pp, const char *val, | | 3295 | ApplyModifier_SunShell(const char **pp, const char *val, |
3296 | ApplyModifiersState *st) | | 3296 | ApplyModifiersState *st) |
3297 | { | | 3297 | { |
3298 | const char *p = *pp; | | 3298 | const char *p = *pp; |
3299 | if (p[1] == 'h' && (p[2] == st->endc || p[2] == ':')) { | | 3299 | if (p[1] == 'h' && (p[2] == st->endc || p[2] == ':')) { |
3300 | if (st->eflags & VARE_WANTRES) { | | 3300 | if (st->eflags & VARE_WANTRES) { |
3301 | const char *errfmt; | | 3301 | const char *errfmt; |
3302 | st->newVal = FStr_InitOwn(Cmd_Exec(val, &errfmt)); | | 3302 | st->newVal = FStr_InitOwn(Cmd_Exec(val, &errfmt)); |
3303 | if (errfmt != NULL) | | 3303 | if (errfmt != NULL) |
3304 | Error(errfmt, val); | | 3304 | Error(errfmt, val); |
3305 | } else | | 3305 | } else |
3306 | st->newVal = FStr_InitOwn(bmake_strdup("")); | | 3306 | st->newVal = FStr_InitRefer(""); |
3307 | *pp = p + 2; | | 3307 | *pp = p + 2; |
3308 | return AMR_OK; | | 3308 | return AMR_OK; |
3309 | } else | | 3309 | } else |
3310 | return AMR_UNKNOWN; | | 3310 | return AMR_UNKNOWN; |
3311 | } | | 3311 | } |
3312 | #endif | | 3312 | #endif |
3313 | | | 3313 | |
3314 | static void | | 3314 | static void |
3315 | LogBeforeApply(const ApplyModifiersState *st, const char *mod, char endc, | | 3315 | LogBeforeApply(const ApplyModifiersState *st, const char *mod, char endc, |
3316 | const char *val) | | 3316 | const char *val) |
3317 | { | | 3317 | { |
3318 | char eflags_str[VarEvalFlags_ToStringSize]; | | 3318 | char eflags_str[VarEvalFlags_ToStringSize]; |
3319 | char vflags_str[VarFlags_ToStringSize]; | | 3319 | char vflags_str[VarFlags_ToStringSize]; |