| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: var.c,v 1.382 2020/08/01 16:27:03 rillig Exp $ */ | | 1 | /* $NetBSD: var.c,v 1.383 2020/08/01 17:29:00 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.382 2020/08/01 16:27:03 rillig Exp $"; | | 72 | static char rcsid[] = "$NetBSD: var.c,v 1.383 2020/08/01 17:29:00 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.382 2020/08/01 16:27:03 rillig Exp $"); | | 79 | __RCSID("$NetBSD: var.c,v 1.383 2020/08/01 17:29:00 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 | * |
| @@ -2998,47 +2998,47 @@ ApplyModifier_SysV(const char *mod, Appl | | | @@ -2998,47 +2998,47 @@ ApplyModifier_SysV(const char *mod, Appl |
2998 | * space-separated words. | | 2998 | * space-separated words. |
2999 | * (Mnemonic: many small 'w'ords.) | | 2999 | * (Mnemonic: many small 'w'ords.) |
3000 | * :[index] Select a single word from the value. | | 3000 | * :[index] Select a single word from the value. |
3001 | * :[start..end] Select multiple words from the value. | | 3001 | * :[start..end] Select multiple words from the value. |
3002 | * :[*] or :[0] Select the entire value, as a single | | 3002 | * :[*] or :[0] Select the entire value, as a single |
3003 | * word. Equivalent to :tW. | | 3003 | * word. Equivalent to :tW. |
3004 | * :[@] Select the entire value, as multiple | | 3004 | * :[@] Select the entire value, as multiple |
3005 | * words. Undoes the effect of :[*]. | | 3005 | * words. Undoes the effect of :[*]. |
3006 | * Equivalent to :tw. | | 3006 | * Equivalent to :tw. |
3007 | * :[#] Returns the number of words in the value. | | 3007 | * :[#] Returns the number of words in the value. |
3008 | * | | 3008 | * |
3009 | * :?<true-value>:<false-value> | | 3009 | * :?<true-value>:<false-value> |
3010 | * If the variable evaluates to true, return | | 3010 | * If the variable evaluates to true, return |
3011 | * true value, else return the second value. | | 3011 | * true-value, else return false-value. |
3012 | * :lhs=rhs Like :S, but the rhs goes to the end of | | 3012 | * :lhs=rhs Similar to :S, but the rhs goes to the end of |
3013 | * the invocation. | | 3013 | * the invocation, including any ':'. |
3014 | * :sh Treat the current value as a command | | 3014 | * :sh Treat the current value as a command |
3015 | * to be run, new value is its output. | | 3015 | * to be run, new value is its output. |
3016 | * The following added so we can handle ODE makefiles. | | 3016 | * The following added so we can handle ODE makefiles. |
3017 | * :@<tmpvar>@<newval>@ | | 3017 | * :@<tmpvar>@<newval>@ |
3018 | * Assign a temporary local variable <tmpvar> | | 3018 | * Assign a temporary global variable <tmpvar> |
3019 | * to the current value of each word in turn | | 3019 | * to the current value of each word in turn |
3020 | * and replace each word with the result of | | 3020 | * and replace each word with the result of |
3021 | * evaluating <newval> | | 3021 | * evaluating <newval> |
3022 | * :D<newval> Use <newval> as value if variable defined | | 3022 | * :D<newval> Use <newval> as value if variable defined |
3023 | * :U<newval> Use <newval> as value if variable undefined | | 3023 | * :U<newval> Use <newval> as value if variable undefined |
3024 | * :L Use the name of the variable as the value. | | 3024 | * :L Use the name of the variable as the value. |
3025 | * :P Use the path of the node that has the same | | 3025 | * :P Use the path of the node that has the same |
3026 | * name as the variable as the value. This | | 3026 | * name as the variable as the value. This |
3027 | * basically includes an implied :L so that | | 3027 | * basically includes an implied :L so that |
3028 | * the common method of refering to the path | | 3028 | * the common method of refering to the path |
3029 | * of your dependent 'x' in a rule is to use | | 3029 | * of your dependent 'x' in a rule is to use |
3030 | * the form '${x:P}'. | | 3030 | * the form '${x:P}'. |
3031 | * :!<cmd>! Run cmd much the same as :sh run's the | | 3031 | * :!<cmd>! Run cmd much the same as :sh runs the |
3032 | * current value of the variable. | | 3032 | * current value of the variable. |
3033 | * Assignment operators (see ApplyModifier_Assign). | | 3033 | * Assignment operators (see ApplyModifier_Assign). |
3034 | */ | | 3034 | */ |
3035 | static char * | | 3035 | static char * |
3036 | ApplyModifiers( | | 3036 | ApplyModifiers( |
3037 | const char **pp, /* the parsing position, updated upon return */ | | 3037 | const char **pp, /* the parsing position, updated upon return */ |
3038 | char *val, /* the current value of the variable */ | | 3038 | char *val, /* the current value of the variable */ |
3039 | int const startc, /* '(' or '{' or '\0' */ | | 3039 | int const startc, /* '(' or '{' or '\0' */ |
3040 | int const endc, /* ')' or '}' or '\0' */ | | 3040 | int const endc, /* ')' or '}' or '\0' */ |
3041 | Var * const v, /* the variable may have its flags changed */ | | 3041 | Var * const v, /* the variable may have its flags changed */ |
3042 | GNode * const ctxt, /* for looking up and modifying variables */ | | 3042 | GNode * const ctxt, /* for looking up and modifying variables */ |
3043 | VarEvalFlags const eflags, | | 3043 | VarEvalFlags const eflags, |
3044 | void ** const freePtr /* free this after using the return value */ | | 3044 | void ** const freePtr /* free this after using the return value */ |
| @@ -3100,27 +3100,27 @@ ApplyModifiers( | | | @@ -3100,27 +3100,27 @@ ApplyModifiers( |
3100 | Error("Unclosed variable specification after complex " | | 3100 | Error("Unclosed variable specification after complex " |
3101 | "modifier (expecting '%c') for %s", st.endc, st.v->name); | | 3101 | "modifier (expecting '%c') for %s", st.endc, st.v->name); |
3102 | goto out; | | 3102 | goto out; |
3103 | } | | 3103 | } |
3104 | continue; | | 3104 | continue; |
3105 | } | | 3105 | } |
3106 | apply_mods: | | 3106 | apply_mods: |
3107 | if (DEBUG(VAR)) { | | 3107 | if (DEBUG(VAR)) { |
3108 | fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", st.v->name, | | 3108 | fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", st.v->name, |
3109 | *p, st.val); | | 3109 | *p, st.val); |
3110 | } | | 3110 | } |
3111 | st.newVal = var_Error; /* default value, in case of errors */ | | 3111 | st.newVal = var_Error; /* default value, in case of errors */ |
3112 | st.next = NULL; /* fail fast if an ApplyModifier forgets to set this */ | | 3112 | st.next = NULL; /* fail fast if an ApplyModifier forgets to set this */ |
3113 | ApplyModifierResult res = 0; | | 3113 | ApplyModifierResult res = AMR_BAD; /* just a safe fallback */ |
3114 | char modifier = *p; | | 3114 | char modifier = *p; |
3115 | switch (modifier) { | | 3115 | switch (modifier) { |
3116 | case ':': | | 3116 | case ':': |
3117 | res = ApplyModifier_Assign(p, &st); | | 3117 | res = ApplyModifier_Assign(p, &st); |
3118 | break; | | 3118 | break; |
3119 | case '@': | | 3119 | case '@': |
3120 | res = ApplyModifier_Loop(p, &st); | | 3120 | res = ApplyModifier_Loop(p, &st); |
3121 | break; | | 3121 | break; |
3122 | case '_': | | 3122 | case '_': |
3123 | res = ApplyModifier_Remember(p, &st); | | 3123 | res = ApplyModifier_Remember(p, &st); |
3124 | break; | | 3124 | break; |
3125 | case 'D': | | 3125 | case 'D': |
3126 | case 'U': | | 3126 | case 'U': |