Sun Jul 26 18:47:02 2020 UTC ()
make(1): reorder arguments of ParseModifierPart

First the input parameters, then additional data, then special arguments.


(rillig)
diff -r1.323 -r1.324 src/usr.bin/make/var.c

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

--- src/usr.bin/make/var.c 2020/07/26 18:11:12 1.323
+++ src/usr.bin/make/var.c 2020/07/26 18:47:02 1.324
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.323 2020/07/26 18:11:12 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.324 2020/07/26 18:47:02 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.323 2020/07/26 18:11:12 rillig Exp $"; 72static char rcsid[] = "$NetBSD: var.c,v 1.324 2020/07/26 18:47:02 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.323 2020/07/26 18:11:12 rillig Exp $"); 79__RCSID("$NetBSD: var.c,v 1.324 2020/07/26 18:47:02 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 *
@@ -1776,64 +1776,67 @@ VarRange(const char *str, int ac) @@ -1776,64 +1776,67 @@ VarRange(const char *str, int ac)
1776 Buf_AddByte(&buf, ' '); 1776 Buf_AddByte(&buf, ' ');
1777 Buf_AddInt(&buf, 1 + i); 1777 Buf_AddInt(&buf, 1 + i);
1778 } 1778 }
1779 1779
1780 free(as); 1780 free(as);
1781 free(av); 1781 free(av);
1782 1782
1783 return Buf_Destroy(&buf, FALSE); 1783 return Buf_Destroy(&buf, FALSE);
1784} 1784}
1785 1785
1786 1786
1787/*- 1787/*-
1788 * Parse a text part of a modifier such as the "from" and "to" in :S/from/to/ 1788 * Parse a text part of a modifier such as the "from" and "to" in :S/from/to/
1789 * or the :@ modifier. Nested variables in the text are expanded unless 1789 * or the :@ modifier, until the next unescaped delimiter. The delimiter, as
1790 * VARE_NOSUBST is set. 1790 * well as the backslash or the dollar, can be escaped with a backslash.
1791 * 1791 *
1792 * The text part is parsed until the next delimiter. To escape the delimiter, 1792 * Return the parsed (and possibly expanded) string, or NULL if no delimiter
1793 * a backslash or a dollar, put a backslash before it. 1793 * was found.
1794 * 1794 *
1795 * Return the expanded string or NULL if the delimiter was missing. 1795 * Nested variables in the text are expanded unless VARE_NOSUBST is set.
1796 * 1796 *
1797 * If pattern is specified, handle escaped ampersands and replace unescaped 1797 * If out_length is specified, store the length of the returned string, just
1798 * ampersands with the lhs of the pattern (for the :S modifier). 1798 * to save another strlen call.
1799 * 
1800 * If out_length is specified, return the string length of the buffer 
1801 * (except on parse errors). 
1802 * 1799 *
1803 * If out_pflags is specified and the last character of the pattern is a $, 1800 * If out_pflags is specified and the last character of the pattern is a $,
1804 * set the VARP_ANCHOR_END bit of mpflags. 1801 * set the VARP_ANCHOR_END bit of mpflags (for the first part of the :S
 1802 * modifier).
 1803 *
 1804 * If subst is specified, handle escaped ampersands and replace unescaped
 1805 * ampersands with the lhs of the pattern (for the second part of the :S
 1806 * modifier).
1805 */ 1807 */
1806static char * 1808static char *
1807ParseModifierPart(GNode *ctxt, const char **tstr, int delim, 1809ParseModifierPart(const char **tstr, int delim, VarEvalFlags eflags,
1808 VarEvalFlags eflags, VarPatternFlags *out_pflags, 1810 GNode *ctxt, size_t *out_length,
1809 size_t *out_length, ModifyWord_SubstArgs *subst) 1811 VarPatternFlags *out_pflags, ModifyWord_SubstArgs *subst)
1810{ 1812{
1811 const char *cp; 1813 const char *cp;
1812 char *rstr; 1814 char *rstr;
1813 Buffer buf; 1815 Buffer buf;
1814 VarEvalFlags errnum = eflags & VARE_UNDEFERR; 1816 VarEvalFlags errnum = eflags & VARE_UNDEFERR;
1815 1817
1816 Buf_Init(&buf, 0); 1818 Buf_Init(&buf, 0);
1817 1819
1818 /* 1820 /*
1819 * Skim through until the matching delimiter is found; 1821 * Skim through until the matching delimiter is found;
1820 * pick up variable substitutions on the way. Also allow 1822 * pick up variable substitutions on the way. Also allow
1821 * backslashes to quote the delimiter, $, and \, but don't 1823 * backslashes to quote the delimiter, $, and \, but don't
1822 * touch other backslashes. 1824 * touch other backslashes.
1823 */ 1825 */
1824 for (cp = *tstr; *cp != '\0' && *cp != delim; cp++) { 1826 for (cp = *tstr; *cp != '\0' && *cp != delim; cp++) {
1825 Boolean is_escaped = cp[0] == '\\' && (cp[1] == delim || 1827 Boolean is_escaped = cp[0] == '\\' && (
1826 cp[1] == '\\' || cp[1] == '$' || (subst != NULL && cp[1] == '&')); 1828 cp[1] == delim || cp[1] == '\\' || cp[1] == '$' ||
 1829 (cp[1] == '&' && subst != NULL));
1827 if (is_escaped) { 1830 if (is_escaped) {
1828 Buf_AddByte(&buf, cp[1]); 1831 Buf_AddByte(&buf, cp[1]);
1829 cp++; 1832 cp++;
1830 } else if (*cp == '$') { 1833 } else if (*cp == '$') {
1831 if (cp[1] == delim) { /* Unescaped $ at end of pattern */ 1834 if (cp[1] == delim) { /* Unescaped $ at end of pattern */
1832 if (out_pflags != NULL) 1835 if (out_pflags != NULL)
1833 *out_pflags |= VARP_ANCHOR_END; 1836 *out_pflags |= VARP_ANCHOR_END;
1834 else 1837 else
1835 Buf_AddByte(&buf, *cp); 1838 Buf_AddByte(&buf, *cp);
1836 } else { 1839 } else {
1837 if (eflags & VARE_WANTRES) { 1840 if (eflags & VARE_WANTRES) {
1838 char *cp2; 1841 char *cp2;
1839 int len; 1842 int len;
@@ -2064,37 +2067,35 @@ typedef struct { @@ -2064,37 +2067,35 @@ typedef struct {
2064#define STRMOD_MATCHX(s, want, n) \ 2067#define STRMOD_MATCHX(s, want, n) \
2065 (strncmp(s, want, n) == 0 && \ 2068 (strncmp(s, want, n) == 0 && \
2066 (s[n] == st->endc || s[n] == ':' || s[n] == '=')) 2069 (s[n] == st->endc || s[n] == ':' || s[n] == '='))
2067#define CHARMOD_MATCH(c) (c == st->endc || c == ':') 2070#define CHARMOD_MATCH(c) (c == st->endc || c == ':')
2068 2071
2069/* :@var@...${var}...@ */ 2072/* :@var@...${var}...@ */
2070static Boolean 2073static Boolean
2071ApplyModifier_Loop(const char *mod, ApplyModifiersState *st) { 2074ApplyModifier_Loop(const char *mod, ApplyModifiersState *st) {
2072 ModifyWord_LoopArgs args; 2075 ModifyWord_LoopArgs args;
2073 2076
2074 args.ctx = st->ctxt; 2077 args.ctx = st->ctxt;
2075 st->cp = mod + 1; 2078 st->cp = mod + 1;
2076 char delim = '@'; 2079 char delim = '@';
2077 args.tvar = ParseModifierPart(st->ctxt, &st->cp, delim, 2080 args.tvar = ParseModifierPart(&st->cp, delim, st->eflags & ~VARE_WANTRES,
2078 st->eflags & ~VARE_WANTRES, 2081 st->ctxt, NULL, NULL, NULL);
2079 NULL, NULL, NULL); 
2080 if (args.tvar == NULL) { 2082 if (args.tvar == NULL) {
2081 st->missing_delim = delim; 2083 st->missing_delim = delim;
2082 return FALSE; 2084 return FALSE;
2083 } 2085 }
2084 2086
2085 args.str = ParseModifierPart(st->ctxt, &st->cp, delim, 2087 args.str = ParseModifierPart(&st->cp, delim, st->eflags & ~VARE_WANTRES,
2086 st->eflags & ~VARE_WANTRES, 2088 st->ctxt, NULL, NULL, NULL);
2087 NULL, NULL, NULL); 
2088 if (args.str == NULL) { 2089 if (args.str == NULL) {
2089 st->missing_delim = delim; 2090 st->missing_delim = delim;
2090 return FALSE; 2091 return FALSE;
2091 } 2092 }
2092 2093
2093 st->termc = *st->cp; 2094 st->termc = *st->cp;
2094 2095
2095 args.eflags = st->eflags & (VARE_UNDEFERR | VARE_WANTRES); 2096 args.eflags = st->eflags & (VARE_UNDEFERR | VARE_WANTRES);
2096 int prev_sep = st->sep; 2097 int prev_sep = st->sep;
2097 st->sep = ' '; /* XXX: this is inconsistent */ 2098 st->sep = ' '; /* XXX: this is inconsistent */
2098 st->newStr = ModifyWords(st->ctxt, st->sep, st->oneBigWord, st->nstr, 2099 st->newStr = ModifyWords(st->ctxt, st->sep, st->oneBigWord, st->nstr,
2099 ModifyWord_Loop, &args); 2100 ModifyWord_Loop, &args);
2100 st->sep = prev_sep; 2101 st->sep = prev_sep;
@@ -2243,27 +2244,27 @@ ApplyModifier_Path(const char *mod, Appl @@ -2243,27 +2244,27 @@ ApplyModifier_Path(const char *mod, Appl
2243 } 2244 }
2244 if (!st->newStr) 2245 if (!st->newStr)
2245 st->newStr = bmake_strdup(st->v->name); 2246 st->newStr = bmake_strdup(st->v->name);
2246 st->cp = mod + 1; 2247 st->cp = mod + 1;
2247 st->termc = *st->cp; 2248 st->termc = *st->cp;
2248} 2249}
2249 2250
2250/* :!cmd! */ 2251/* :!cmd! */
2251static Boolean 2252static Boolean
2252ApplyModifier_Exclam(const char *mod, ApplyModifiersState *st) 2253ApplyModifier_Exclam(const char *mod, ApplyModifiersState *st)
2253{ 2254{
2254 st->cp = mod + 1; 2255 st->cp = mod + 1;
2255 char delim = '!'; 2256 char delim = '!';
2256 char *cmd = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags, 2257 char *cmd = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2257 NULL, NULL, NULL); 2258 NULL, NULL, NULL);
2258 if (cmd == NULL) { 2259 if (cmd == NULL) {
2259 st->missing_delim = delim; 2260 st->missing_delim = delim;
2260 return FALSE; 2261 return FALSE;
2261 } 2262 }
2262 2263
2263 const char *emsg = NULL; 2264 const char *emsg = NULL;
2264 if (st->eflags & VARE_WANTRES) 2265 if (st->eflags & VARE_WANTRES)
2265 st->newStr = Cmd_Exec(cmd, &emsg); 2266 st->newStr = Cmd_Exec(cmd, &emsg);
2266 else 2267 else
2267 st->newStr = varNoError; 2268 st->newStr = varNoError;
2268 free(cmd); 2269 free(cmd);
2269 2270
@@ -2389,36 +2390,36 @@ ApplyModifier_Subst(const char * const m @@ -2389,36 +2390,36 @@ ApplyModifier_Subst(const char * const m
2389 2390
2390 st->cp = mod + 2; 2391 st->cp = mod + 2;
2391 2392
2392 /* 2393 /*
2393 * If pattern begins with '^', it is anchored to the 2394 * If pattern begins with '^', it is anchored to the
2394 * start of the word -- skip over it and flag pattern. 2395 * start of the word -- skip over it and flag pattern.
2395 */ 2396 */
2396 args.pflags = 0; 2397 args.pflags = 0;
2397 if (*st->cp == '^') { 2398 if (*st->cp == '^') {
2398 args.pflags |= VARP_ANCHOR_START; 2399 args.pflags |= VARP_ANCHOR_START;
2399 st->cp++; 2400 st->cp++;
2400 } 2401 }
2401 2402
2402 char *lhs = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags, 2403 char *lhs = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2403 &args.pflags, &args.lhsLen, NULL); 2404 &args.lhsLen, &args.pflags, NULL);
2404 if (lhs == NULL) { 2405 if (lhs == NULL) {
2405 st->missing_delim = delim; 2406 st->missing_delim = delim;
2406 return FALSE; 2407 return FALSE;
2407 } 2408 }
2408 args.lhs = lhs; 2409 args.lhs = lhs;
2409 2410
2410 char *rhs = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags, 2411 char *rhs = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2411 NULL, &args.rhsLen, &args); 2412 &args.rhsLen, NULL, &args);
2412 if (rhs == NULL) { 2413 if (rhs == NULL) {
2413 st->missing_delim = delim; 2414 st->missing_delim = delim;
2414 return FALSE; 2415 return FALSE;
2415 } 2416 }
2416 args.rhs = rhs; 2417 args.rhs = rhs;
2417 2418
2418 /* 2419 /*
2419 * Check for global substitution. If 'g' after the final 2420 * Check for global substitution. If 'g' after the final
2420 * delimiter, substitution is global and is marked that 2421 * delimiter, substitution is global and is marked that
2421 * way. 2422 * way.
2422 */ 2423 */
2423 for (;; st->cp++) { 2424 for (;; st->cp++) {
2424 switch (*st->cp) { 2425 switch (*st->cp) {
@@ -2448,35 +2449,35 @@ ApplyModifier_Subst(const char * const m @@ -2448,35 +2449,35 @@ ApplyModifier_Subst(const char * const m
2448 2449
2449/* :C,from,to, */ 2450/* :C,from,to, */
2450static Boolean 2451static Boolean
2451ApplyModifier_Regex(const char *mod, ApplyModifiersState *st) 2452ApplyModifier_Regex(const char *mod, ApplyModifiersState *st)
2452{ 2453{
2453 ModifyWord_SubstRegexArgs args; 2454 ModifyWord_SubstRegexArgs args;
2454 2455
2455 args.pflags = 0; 2456 args.pflags = 0;
2456 Boolean oneBigWord = st->oneBigWord; 2457 Boolean oneBigWord = st->oneBigWord;
2457 char delim = mod[1]; 2458 char delim = mod[1];
2458 2459
2459 st->cp = mod + 2; 2460 st->cp = mod + 2;
2460 2461
2461 char *re = ParseModifierPart(st->ctxt, &st->cp, delim, 2462 char *re = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2462 st->eflags, NULL, NULL, NULL); 2463 NULL, NULL, NULL);
2463 if (re == NULL) { 2464 if (re == NULL) {
2464 st->missing_delim = delim; 2465 st->missing_delim = delim;
2465 return FALSE; 2466 return FALSE;
2466 } 2467 }
2467 2468
2468 args.replace = ParseModifierPart(st->ctxt, &st->cp, delim, 2469 args.replace = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2469 st->eflags, NULL, NULL, NULL); 2470 NULL, NULL, NULL);
2470 if (args.replace == NULL) { 2471 if (args.replace == NULL) {
2471 free(re); 2472 free(re);
2472 st->missing_delim = delim; 2473 st->missing_delim = delim;
2473 return FALSE; 2474 return FALSE;
2474 } 2475 }
2475 2476
2476 for (;; st->cp++) { 2477 for (;; st->cp++) {
2477 switch (*st->cp) { 2478 switch (*st->cp) {
2478 case 'g': 2479 case 'g':
2479 args.pflags |= VARP_SUB_GLOBAL; 2480 args.pflags |= VARP_SUB_GLOBAL;
2480 continue; 2481 continue;
2481 case '1': 2482 case '1':
2482 args.pflags |= VARP_SUB_ONE; 2483 args.pflags |= VARP_SUB_ONE;
@@ -2610,29 +2611,29 @@ ApplyModifier_To(const char *mod, ApplyM @@ -2610,29 +2611,29 @@ ApplyModifier_To(const char *mod, ApplyM
2610 st->cp = mod + 2; 2611 st->cp = mod + 2;
2611 st->termc = *st->cp; 2612 st->termc = *st->cp;
2612 } else { 2613 } else {
2613 /* Found ":t<unrecognised>:" or ":t<unrecognised><endc>". */ 2614 /* Found ":t<unrecognised>:" or ":t<unrecognised><endc>". */
2614 return FALSE; 2615 return FALSE;
2615 } 2616 }
2616 return TRUE; 2617 return TRUE;
2617} 2618}
2618 2619
2619/* :[#], :[1], etc. */ 2620/* :[#], :[1], etc. */
2620static int 2621static int
2621ApplyModifier_Words(const char *mod, ApplyModifiersState *st) 2622ApplyModifier_Words(const char *mod, ApplyModifiersState *st)
2622{ 2623{
2623 st->cp = mod + 1; /* point to char after '[' */ 2624 st->cp = mod + 1; /* point to char after '[' */
2624 char delim = ']'; /* look for closing ']' */ 2625 char delim = ']'; /* look for closing ']' */
2625 char *estr = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags, 2626 char *estr = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2626 NULL, NULL, NULL); 2627 NULL, NULL, NULL);
2627 if (estr == NULL) { 2628 if (estr == NULL) {
2628 st->missing_delim = delim; 2629 st->missing_delim = delim;
2629 return 'c'; 2630 return 'c';
2630 } 2631 }
2631 2632
2632 /* now st->cp points just after the closing ']' */ 2633 /* now st->cp points just after the closing ']' */
2633 if (st->cp[0] != ':' && st->cp[0] != st->endc) 2634 if (st->cp[0] != ':' && st->cp[0] != st->endc)
2634 goto bad_modifier; /* Found junk after ']' */ 2635 goto bad_modifier; /* Found junk after ']' */
2635 2636
2636 if (estr[0] == '\0') 2637 if (estr[0] == '\0')
2637 goto bad_modifier; /* empty square brackets in ":[]". */ 2638 goto bad_modifier; /* empty square brackets in ":[]". */
2638 2639
@@ -2750,36 +2751,36 @@ ApplyModifier_IfElse(const char *mod, Ap @@ -2750,36 +2751,36 @@ ApplyModifier_IfElse(const char *mod, Ap
2750 VarEvalFlags then_eflags = st->eflags & ~VARE_WANTRES; 2751 VarEvalFlags then_eflags = st->eflags & ~VARE_WANTRES;
2751 VarEvalFlags else_eflags = st->eflags & ~VARE_WANTRES; 2752 VarEvalFlags else_eflags = st->eflags & ~VARE_WANTRES;
2752 2753
2753 if (st->eflags & VARE_WANTRES) { 2754 if (st->eflags & VARE_WANTRES) {
2754 cond_rc = Cond_EvalExpression(NULL, st->v->name, &value, 0, FALSE); 2755 cond_rc = Cond_EvalExpression(NULL, st->v->name, &value, 0, FALSE);
2755 if (cond_rc != COND_INVALID && value) 2756 if (cond_rc != COND_INVALID && value)
2756 then_eflags |= VARE_WANTRES; 2757 then_eflags |= VARE_WANTRES;
2757 if (cond_rc != COND_INVALID && !value) 2758 if (cond_rc != COND_INVALID && !value)
2758 else_eflags |= VARE_WANTRES; 2759 else_eflags |= VARE_WANTRES;
2759 } 2760 }
2760 2761
2761 st->cp = mod + 1; 2762 st->cp = mod + 1;
2762 char delim = ':'; 2763 char delim = ':';
2763 char *then_expr = ParseModifierPart( 2764 char *then_expr = ParseModifierPart(&st->cp, delim, then_eflags, st->ctxt,
2764 st->ctxt, &st->cp, delim, then_eflags, NULL, NULL, NULL); 2765 NULL, NULL, NULL);
2765 if (then_expr == NULL) { 2766 if (then_expr == NULL) {
2766 st->missing_delim = delim; 2767 st->missing_delim = delim;
2767 return FALSE; 2768 return FALSE;
2768 } 2769 }
2769 2770
2770 delim = st->endc; /* BRCLOSE or PRCLOSE */ 2771 delim = st->endc; /* BRCLOSE or PRCLOSE */
2771 char *else_expr = ParseModifierPart( 2772 char *else_expr = ParseModifierPart(&st->cp, delim, else_eflags, st->ctxt,
2772 st->ctxt, &st->cp, delim, else_eflags, NULL, NULL, NULL); 2773 NULL, NULL, NULL);
2773 if (else_expr == NULL) { 2774 if (else_expr == NULL) {
2774 st->missing_delim = delim; 2775 st->missing_delim = delim;
2775 return FALSE; 2776 return FALSE;
2776 } 2777 }
2777 2778
2778 st->termc = *--st->cp; 2779 st->termc = *--st->cp;
2779 if (cond_rc == COND_INVALID) { 2780 if (cond_rc == COND_INVALID) {
2780 Error("Bad conditional expression `%s' in %s?%s:%s", 2781 Error("Bad conditional expression `%s' in %s?%s:%s",
2781 st->v->name, st->v->name, then_expr, else_expr); 2782 st->v->name, st->v->name, then_expr, else_expr);
2782 return FALSE; 2783 return FALSE;
2783 } 2784 }
2784 2785
2785 if (value) { 2786 if (value) {
@@ -2847,28 +2848,28 @@ ApplyModifier_Assign(const char *mod, Ap @@ -2847,28 +2848,28 @@ ApplyModifier_Assign(const char *mod, Ap
2847 2848
2848 switch (op[0]) { 2849 switch (op[0]) {
2849 case '+': 2850 case '+':
2850 case '?': 2851 case '?':
2851 case '!': 2852 case '!':
2852 st->cp = mod + 3; 2853 st->cp = mod + 3;
2853 break; 2854 break;
2854 default: 2855 default:
2855 st->cp = mod + 2; 2856 st->cp = mod + 2;
2856 break; 2857 break;
2857 } 2858 }
2858 2859
2859 char delim = st->startc == PROPEN ? PRCLOSE : BRCLOSE; 2860 char delim = st->startc == PROPEN ? PRCLOSE : BRCLOSE;
2860 char *val = ParseModifierPart(st->ctxt, &st->cp, delim, 2861 char *val = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2861 st->eflags, NULL, NULL, NULL); 2862 NULL, NULL, NULL);
2862 if (st->v->flags & VAR_JUNK) { 2863 if (st->v->flags & VAR_JUNK) {
2863 /* restore original name */ 2864 /* restore original name */
2864 free(st->v->name); 2865 free(st->v->name);
2865 st->v->name = sv_name; 2866 st->v->name = sv_name;
2866 } 2867 }
2867 if (val == NULL) { 2868 if (val == NULL) {
2868 st->missing_delim = delim; 2869 st->missing_delim = delim;
2869 return 'c'; 2870 return 'c';
2870 } 2871 }
2871 2872
2872 st->termc = *--st->cp; 2873 st->termc = *--st->cp;
2873 2874
2874 if (st->eflags & VARE_WANTRES) { 2875 if (st->eflags & VARE_WANTRES) {
@@ -2947,35 +2948,35 @@ ApplyModifier_SysV(const char *mod, Appl @@ -2947,35 +2948,35 @@ ApplyModifier_SysV(const char *mod, Appl
2947 /* continue looking for st->endc */ 2948 /* continue looking for st->endc */
2948 } else if (*st->cp == st->endc) 2949 } else if (*st->cp == st->endc)
2949 nest--; 2950 nest--;
2950 else if (*st->cp == st->startc) 2951 else if (*st->cp == st->startc)
2951 nest++; 2952 nest++;
2952 if (nest > 0) 2953 if (nest > 0)
2953 st->cp++; 2954 st->cp++;
2954 } 2955 }
2955 if (*st->cp != st->endc || !eqFound) 2956 if (*st->cp != st->endc || !eqFound)
2956 return 0; 2957 return 0;
2957 2958
2958 char delim = '='; 2959 char delim = '=';
2959 st->cp = mod; 2960 st->cp = mod;
2960 char *lhs = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags, 2961 char *lhs = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2961 NULL, NULL, NULL); 2962 NULL, NULL, NULL);
2962 if (lhs == NULL) { 2963 if (lhs == NULL) {
2963 st->missing_delim = delim; 2964 st->missing_delim = delim;
2964 return 'c'; 2965 return 'c';
2965 } 2966 }
2966 2967
2967 delim = st->endc; 2968 delim = st->endc;
2968 char *rhs = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags, 2969 char *rhs = ParseModifierPart(&st->cp, delim, st->eflags, st->ctxt,
2969 NULL, NULL, NULL); 2970 NULL, NULL, NULL);
2970 if (rhs == NULL) { 2971 if (rhs == NULL) {
2971 st->missing_delim = delim; 2972 st->missing_delim = delim;
2972 return 'c'; 2973 return 'c';
2973 } 2974 }
2974 2975
2975 /* 2976 /*
2976 * SYSV modifications happen through the whole 2977 * SYSV modifications happen through the whole
2977 * string. Note the pattern is anchored at the end. 2978 * string. Note the pattern is anchored at the end.
2978 */ 2979 */
2979 st->termc = *--st->cp; 2980 st->termc = *--st->cp;
2980 if (lhs[0] == '\0' && *st->nstr == '\0') { 2981 if (lhs[0] == '\0' && *st->nstr == '\0') {
2981 st->newStr = st->nstr; /* special case */ 2982 st->newStr = st->nstr; /* special case */