| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: var.c,v 1.349 2020/07/27 23:37:37 rillig Exp $ */ | | 1 | /* $NetBSD: var.c,v 1.350 2020/07/27 23:56:15 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 |
72 | static char rcsid[] = "$NetBSD: var.c,v 1.349 2020/07/27 23:37:37 rillig Exp $"; | | 72 | static char rcsid[] = "$NetBSD: var.c,v 1.350 2020/07/27 23:56:15 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 |
77 | static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; | | 77 | static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; |
78 | #else | | 78 | #else |
79 | __RCSID("$NetBSD: var.c,v 1.349 2020/07/27 23:37:37 rillig Exp $"); | | 79 | __RCSID("$NetBSD: var.c,v 1.350 2020/07/27 23:56:15 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 | * |
| @@ -2026,50 +2026,56 @@ VarStrftime(const char *fmt, int zulu, t | | | @@ -2026,50 +2026,56 @@ VarStrftime(const char *fmt, int zulu, t |
2026 | { | | 2026 | { |
2027 | char buf[BUFSIZ]; | | 2027 | char buf[BUFSIZ]; |
2028 | | | 2028 | |
2029 | if (!utc) | | 2029 | if (!utc) |
2030 | time(&utc); | | 2030 | time(&utc); |
2031 | if (!*fmt) | | 2031 | if (!*fmt) |
2032 | fmt = "%c"; | | 2032 | fmt = "%c"; |
2033 | strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc)); | | 2033 | strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc)); |
2034 | | | 2034 | |
2035 | buf[sizeof(buf) - 1] = '\0'; | | 2035 | buf[sizeof(buf) - 1] = '\0'; |
2036 | return bmake_strdup(buf); | | 2036 | return bmake_strdup(buf); |
2037 | } | | 2037 | } |
2038 | | | 2038 | |
| | | 2039 | /* The ApplyModifier functions all work in the same way. |
| | | 2040 | * They parse the modifier (often until the next colon) and store the |
| | | 2041 | * updated position for the parser into st->next. |
| | | 2042 | * They take the st->val and generate st->newVal from it. |
| | | 2043 | * On success, they set st->termc to *st->next, redundantly. |
| | | 2044 | * On failure, many of them update st->missing_delim. |
| | | 2045 | */ |
2039 | typedef struct { | | 2046 | typedef struct { |
2040 | /* const parameters */ | | | |
2041 | int startc; /* '\0' or '{' or '(' */ | | 2047 | int startc; /* '\0' or '{' or '(' */ |
2042 | int endc; | | 2048 | int endc; |
2043 | Var *v; | | 2049 | Var *v; |
2044 | GNode *ctxt; | | 2050 | GNode *ctxt; |
2045 | VarEvalFlags eflags; | | 2051 | VarEvalFlags eflags; |
2046 | | | 2052 | |
2047 | /* read-write */ | | 2053 | char *val; /* The value of the expression before the |
2048 | char *val; | | 2054 | * modifier is applied */ |
| | | 2055 | char *newVal; /* The new value after applying the modifier |
| | | 2056 | * to the expression */ |
2049 | const char *next; /* The position where parsing continues | | 2057 | const char *next; /* The position where parsing continues |
2050 | * after the current modifier. */ | | 2058 | * after the current modifier. */ |
2051 | char termc; /* Character which terminated scan */ | | 2059 | char termc; /* Character which terminated scan */ |
2052 | char missing_delim; /* For error reporting */ | | 2060 | char missing_delim; /* For error reporting */ |
2053 | | | 2061 | |
2054 | Byte sep; /* Word separator in expansions */ | | 2062 | Byte sep; /* Word separator in expansions */ |
2055 | Boolean oneBigWord; /* TRUE if we will treat the variable as a | | 2063 | Boolean oneBigWord; /* TRUE if we will treat the variable as a |
2056 | * single big word, even if it contains | | 2064 | * single big word, even if it contains |
2057 | * embedded spaces (as opposed to the | | 2065 | * embedded spaces (as opposed to the |
2058 | * usual behaviour of treating it as | | 2066 | * usual behaviour of treating it as |
2059 | * several space-separated words). */ | | 2067 | * several space-separated words). */ |
2060 | | | 2068 | |
2061 | /* result */ | | | |
2062 | char *newVal; /* New value to return */ | | | |
2063 | } ApplyModifiersState; | | 2069 | } ApplyModifiersState; |
2064 | | | 2070 | |
2065 | /* we now have some modifiers with long names */ | | 2071 | /* we now have some modifiers with long names */ |
2066 | static Boolean | | 2072 | static Boolean |
2067 | ModMatch(const char *mod, const char *modname, char endc) | | 2073 | ModMatch(const char *mod, const char *modname, char endc) |
2068 | { | | 2074 | { |
2069 | size_t n = strlen(modname); | | 2075 | size_t n = strlen(modname); |
2070 | return strncmp(mod, modname, n) == 0 && | | 2076 | return strncmp(mod, modname, n) == 0 && |
2071 | (mod[n] == endc || mod[n] == ':'); | | 2077 | (mod[n] == endc || mod[n] == ':'); |
2072 | } | | 2078 | } |
2073 | | | 2079 | |
2074 | static inline Boolean | | 2080 | static inline Boolean |
2075 | ModMatchEq(const char *mod, const char *modname, char endc) | | 2081 | ModMatchEq(const char *mod, const char *modname, char endc) |
| @@ -3060,27 +3066,27 @@ ApplyModifier_SysV(const char *mod, Appl | | | @@ -3060,27 +3066,27 @@ ApplyModifier_SysV(const char *mod, Appl |
3060 | * the form '${x:P}'. | | 3066 | * the form '${x:P}'. |
3061 | * :!<cmd>! Run cmd much the same as :sh run's the | | 3067 | * :!<cmd>! Run cmd much the same as :sh run's the |
3062 | * current value of the variable. | | 3068 | * current value of the variable. |
3063 | * Assignment operators (see ApplyModifier_Assign). | | 3069 | * Assignment operators (see ApplyModifier_Assign). |
3064 | */ | | 3070 | */ |
3065 | static char * | | 3071 | static char * |
3066 | ApplyModifiers(char *val, const char * const tstr, | | 3072 | ApplyModifiers(char *val, const char * const tstr, |
3067 | int const startc, int const endc, | | 3073 | int const startc, int const endc, |
3068 | Var * const v, GNode * const ctxt, VarEvalFlags const eflags, | | 3074 | Var * const v, GNode * const ctxt, VarEvalFlags const eflags, |
3069 | int * const lengthPtr, void ** const freePtr) | | 3075 | int * const lengthPtr, void ** const freePtr) |
3070 | { | | 3076 | { |
3071 | ApplyModifiersState st = { | | 3077 | ApplyModifiersState st = { |
3072 | startc, endc, v, ctxt, eflags, | | 3078 | startc, endc, v, ctxt, eflags, |
3073 | val, tstr, '\0', '\0', ' ', FALSE, NULL | | 3079 | val, NULL, NULL, '\0', '\0', ' ', FALSE |
3074 | }; | | 3080 | }; |
3075 | | | 3081 | |
3076 | const char *p = tstr; | | 3082 | const char *p = tstr; |
3077 | while (*p != '\0' && *p != endc) { | | 3083 | while (*p != '\0' && *p != endc) { |
3078 | | | 3084 | |
3079 | if (*p == '$') { | | 3085 | if (*p == '$') { |
3080 | /* | | 3086 | /* |
3081 | * We may have some complex modifiers in a variable. | | 3087 | * We may have some complex modifiers in a variable. |
3082 | */ | | 3088 | */ |
3083 | void *freeIt; | | 3089 | void *freeIt; |
3084 | const char *rval; | | 3090 | const char *rval; |
3085 | int rlen; | | 3091 | int rlen; |
3086 | int c; | | 3092 | int c; |