Mon Jul 27 23:56:15 2020 UTC ()
make(1): document and reorder ApplyModifiersState


(rillig)
diff -r1.349 -r1.350 src/usr.bin/make/var.c

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

--- src/usr.bin/make/var.c 2020/07/27 23:37:37 1.349
+++ src/usr.bin/make/var.c 2020/07/27 23:56:15 1.350
@@ -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
72static char rcsid[] = "$NetBSD: var.c,v 1.349 2020/07/27 23:37:37 rillig Exp $"; 72static 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
77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 77static 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 */
2039typedef struct { 2046typedef 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 */
2066static Boolean 2072static Boolean
2067ModMatch(const char *mod, const char *modname, char endc) 2073ModMatch(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
2074static inline Boolean 2080static inline Boolean
2075ModMatchEq(const char *mod, const char *modname, char endc) 2081ModMatchEq(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 */
3065static char * 3071static char *
3066ApplyModifiers(char *val, const char * const tstr, 3072ApplyModifiers(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;