Home | History | Annotate | Line # | Download | only in make
var.c revision 1.1161
      1  1.1161    rillig /*	$NetBSD: var.c,v 1.1161 2025/04/30 06:01:07 rillig Exp $	*/
      2    1.11  christos 
      3     1.1       cgd /*
      4    1.15  christos  * Copyright (c) 1988, 1989, 1990, 1993
      5    1.15  christos  *	The Regents of the University of California.  All rights reserved.
      6    1.80       agc  *
      7    1.80       agc  * This code is derived from software contributed to Berkeley by
      8    1.80       agc  * Adam de Boor.
      9    1.80       agc  *
     10    1.80       agc  * Redistribution and use in source and binary forms, with or without
     11    1.80       agc  * modification, are permitted provided that the following conditions
     12    1.80       agc  * are met:
     13    1.80       agc  * 1. Redistributions of source code must retain the above copyright
     14    1.80       agc  *    notice, this list of conditions and the following disclaimer.
     15    1.80       agc  * 2. Redistributions in binary form must reproduce the above copyright
     16    1.80       agc  *    notice, this list of conditions and the following disclaimer in the
     17    1.80       agc  *    documentation and/or other materials provided with the distribution.
     18    1.80       agc  * 3. Neither the name of the University nor the names of its contributors
     19    1.80       agc  *    may be used to endorse or promote products derived from this software
     20    1.80       agc  *    without specific prior written permission.
     21    1.80       agc  *
     22    1.80       agc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     23    1.80       agc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24    1.80       agc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25    1.80       agc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     26    1.80       agc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27    1.80       agc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28    1.80       agc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29    1.80       agc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30    1.80       agc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31    1.80       agc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32    1.80       agc  * SUCH DAMAGE.
     33    1.80       agc  */
     34    1.80       agc 
     35    1.80       agc /*
     36     1.1       cgd  * Copyright (c) 1989 by Berkeley Softworks
     37     1.1       cgd  * All rights reserved.
     38     1.1       cgd  *
     39     1.1       cgd  * This code is derived from software contributed to Berkeley by
     40     1.1       cgd  * Adam de Boor.
     41     1.1       cgd  *
     42     1.1       cgd  * Redistribution and use in source and binary forms, with or without
     43     1.1       cgd  * modification, are permitted provided that the following conditions
     44     1.1       cgd  * are met:
     45     1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     46     1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     47     1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     48     1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     49     1.1       cgd  *    documentation and/or other materials provided with the distribution.
     50     1.1       cgd  * 3. All advertising materials mentioning features or use of this software
     51     1.1       cgd  *    must display the following acknowledgement:
     52     1.1       cgd  *	This product includes software developed by the University of
     53     1.1       cgd  *	California, Berkeley and its contributors.
     54     1.1       cgd  * 4. Neither the name of the University nor the names of its contributors
     55     1.1       cgd  *    may be used to endorse or promote products derived from this software
     56     1.1       cgd  *    without specific prior written permission.
     57     1.1       cgd  *
     58     1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     59     1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     60     1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     61     1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     62     1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63     1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64     1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65     1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66     1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67     1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68     1.1       cgd  * SUCH DAMAGE.
     69     1.1       cgd  */
     70     1.1       cgd 
     71   1.592    rillig /*
     72   1.592    rillig  * Handling of variables and the expressions formed from them.
     73   1.592    rillig  *
     74   1.592    rillig  * Variables are set using lines of the form VAR=value.  Both the variable
     75   1.592    rillig  * name and the value can contain references to other variables, by using
     76   1.592    rillig  * expressions like ${VAR}, ${VAR:Modifiers}, ${${VARNAME}} or ${VAR:${MODS}}.
     77     1.1       cgd  *
     78     1.1       cgd  * Interface:
     79   1.798    rillig  *	Var_Set
     80  1.1105    rillig  *	Var_SetExpand	Set the value of the variable, creating it if
     81   1.592    rillig  *			necessary.
     82   1.592    rillig  *
     83   1.794    rillig  *	Var_Append
     84   1.794    rillig  *	Var_AppendExpand
     85   1.794    rillig  *			Append more characters to the variable, creating it if
     86   1.592    rillig  *			necessary. A space is placed between the old value and
     87   1.592    rillig  *			the new one.
     88     1.1       cgd  *
     89   1.796    rillig  *	Var_Exists
     90   1.796    rillig  *	Var_ExistsExpand
     91   1.796    rillig  *			See if a variable exists.
     92     1.1       cgd  *
     93   1.592    rillig  *	Var_Value	Return the unexpanded value of a variable, or NULL if
     94   1.592    rillig  *			the variable is undefined.
     95   1.592    rillig  *
     96  1.1075    rillig  *	Var_Subst	Substitute all expressions in a string.
     97   1.592    rillig  *
     98  1.1075    rillig  *	Var_Parse	Parse an expression such as ${VAR:Mpattern}.
     99     1.1       cgd  *
    100  1.1105    rillig  *	Var_Delete	Delete a variable.
    101     1.1       cgd  *
    102   1.725    rillig  *	Var_ReexportVars
    103   1.725    rillig  *			Export some or even all variables to the environment
    104   1.592    rillig  *			of this process and its child processes.
    105     1.1       cgd  *
    106   1.592    rillig  *	Var_Export	Export the variable to the environment of this process
    107   1.592    rillig  *			and its child processes.
    108     1.1       cgd  *
    109   1.592    rillig  *	Var_UnExport	Don't export the variable anymore.
    110     1.1       cgd  *
    111     1.1       cgd  * Debugging:
    112   1.592    rillig  *	Var_Stats	Print out hashing statistics if in -dh mode.
    113   1.592    rillig  *
    114   1.802    rillig  *	Var_Dump	Print out all variables defined in the given scope.
    115     1.1       cgd  */
    116     1.1       cgd 
    117   1.630    rillig #include <sys/stat.h>
    118   1.630    rillig #include <sys/types.h>
    119   1.630    rillig #include <regex.h>
    120   1.631    rillig #include <errno.h>
    121   1.630    rillig #include <inttypes.h>
    122   1.630    rillig #include <limits.h>
    123   1.630    rillig #include <time.h>
    124   1.630    rillig 
    125   1.630    rillig #include "make.h"
    126   1.630    rillig #include "dir.h"
    127   1.630    rillig #include "job.h"
    128   1.630    rillig #include "metachar.h"
    129     1.1       cgd 
    130   1.512    rillig /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
    131  1.1161    rillig MAKE_RCSID("$NetBSD: var.c,v 1.1161 2025/04/30 06:01:07 rillig Exp $");
    132   1.228    rillig 
    133   1.778    rillig /*
    134   1.778    rillig  * Variables are defined using one of the VAR=value assignments.  Their
    135   1.570    rillig  * value can be queried by expressions such as $V, ${VAR}, or with modifiers
    136   1.570    rillig  * such as ${VAR:S,from,to,g:Q}.
    137   1.570    rillig  *
    138   1.802    rillig  * There are 3 kinds of variables: scope variables, environment variables,
    139   1.570    rillig  * undefined variables.
    140   1.570    rillig  *
    141  1.1105    rillig  * Scope variables are stored in GNode.vars.  The only way to undefine
    142   1.802    rillig  * a scope variable is using the .undef directive.  In particular, it must
    143   1.570    rillig  * not be possible to undefine a variable during the evaluation of an
    144   1.996    rillig  * expression, or Var.name might point nowhere.  (There is another,
    145   1.996    rillig  * unintended way to undefine a scope variable, see varmod-loop-delete.mk.)
    146   1.570    rillig  *
    147   1.977    rillig  * Environment variables are short-lived.  They are returned by VarFind, and
    148   1.977    rillig  * after using them, they must be freed using VarFreeShortLived.
    149   1.570    rillig  *
    150  1.1075    rillig  * Undefined variables occur during evaluation of expressions such
    151   1.570    rillig  * as ${UNDEF:Ufallback} in Var_Parse and ApplyModifiers.
    152   1.570    rillig  */
    153     1.1       cgd typedef struct Var {
    154   1.703    rillig 	/*
    155   1.703    rillig 	 * The name of the variable, once set, doesn't change anymore.
    156   1.802    rillig 	 * For scope variables, it aliases the corresponding HashEntry name.
    157   1.703    rillig 	 * For environment and undefined variables, it is allocated.
    158   1.703    rillig 	 */
    159   1.711    rillig 	FStr name;
    160   1.570    rillig 
    161   1.703    rillig 	/* The unexpanded value of the variable. */
    162   1.703    rillig 	Buffer val;
    163   1.902    rillig 
    164   1.902    rillig 	/* The variable came from the command line. */
    165   1.987    rillig 	bool fromCmd:1;
    166   1.902    rillig 
    167   1.902    rillig 	/*
    168   1.978    rillig 	 * The variable is short-lived.
    169   1.978    rillig 	 * These variables are not registered in any GNode, therefore they
    170   1.978    rillig 	 * must be freed after use.
    171   1.978    rillig 	 */
    172   1.987    rillig 	bool shortLived:1;
    173   1.978    rillig 
    174   1.978    rillig 	/*
    175   1.902    rillig 	 * The variable comes from the environment.
    176  1.1105    rillig 	 * Appending to its value depends on the scope, see var-op-append.mk.
    177   1.902    rillig 	 */
    178   1.987    rillig 	bool fromEnvironment:1;
    179   1.902    rillig 
    180   1.902    rillig 	/*
    181   1.902    rillig 	 * The variable value cannot be changed anymore, and the variable
    182   1.902    rillig 	 * cannot be deleted.  Any attempts to do so are silently ignored,
    183   1.902    rillig 	 * they are logged with -dv though.
    184  1.1038       sjg 	 * Use .[NO]READONLY: to adjust.
    185   1.902    rillig 	 *
    186   1.902    rillig 	 * See VAR_SET_READONLY.
    187   1.902    rillig 	 */
    188   1.987    rillig 	bool readOnly:1;
    189   1.902    rillig 
    190   1.902    rillig 	/*
    191  1.1121    rillig 	 * The variable is read-only and immune to the .NOREADONLY special
    192  1.1121    rillig 	 * target.  Any attempt to modify it results in an error.
    193  1.1121    rillig 	 */
    194  1.1121    rillig 	bool readOnlyLoud:1;
    195  1.1121    rillig 
    196  1.1121    rillig 	/*
    197  1.1035    rillig 	 * The variable is currently being accessed by Var_Parse or Var_Subst.
    198  1.1035    rillig 	 * This temporary marker is used to avoid endless recursion.
    199  1.1035    rillig 	 */
    200   1.987    rillig 	bool inUse:1;
    201   1.902    rillig 
    202   1.902    rillig 	/*
    203   1.902    rillig 	 * The variable is exported to the environment, to be used by child
    204   1.902    rillig 	 * processes.
    205   1.902    rillig 	 */
    206   1.987    rillig 	bool exported:1;
    207   1.902    rillig 
    208   1.902    rillig 	/*
    209   1.902    rillig 	 * At the point where this variable was exported, it contained an
    210   1.902    rillig 	 * unresolved reference to another variable.  Before any child
    211  1.1066    rillig 	 * process is started, it needs to be actually exported, resolving
    212  1.1066    rillig 	 * the referenced variable just in time.
    213   1.902    rillig 	 */
    214   1.987    rillig 	bool reexport:1;
    215   1.417    rillig } Var;
    216     1.1       cgd 
    217   1.710    rillig /*
    218   1.830    rillig  * Exporting variables is expensive and may leak memory, so skip it if we
    219   1.830    rillig  * can.
    220   1.710    rillig  */
    221   1.710    rillig typedef enum VarExportedMode {
    222   1.710    rillig 	VAR_EXPORTED_NONE,
    223   1.710    rillig 	VAR_EXPORTED_SOME,
    224   1.710    rillig 	VAR_EXPORTED_ALL
    225   1.710    rillig } VarExportedMode;
    226   1.710    rillig 
    227   1.713    rillig typedef enum UnexportWhat {
    228   1.830    rillig 	/* Unexport the variables given by name. */
    229   1.713    rillig 	UNEXPORT_NAMED,
    230   1.830    rillig 	/*
    231   1.830    rillig 	 * Unexport all globals previously exported, but keep the environment
    232   1.830    rillig 	 * inherited from the parent.
    233   1.830    rillig 	 */
    234   1.713    rillig 	UNEXPORT_ALL,
    235   1.830    rillig 	/*
    236   1.830    rillig 	 * Unexport all globals previously exported and clear the environment
    237   1.830    rillig 	 * inherited from the parent.
    238   1.830    rillig 	 */
    239   1.713    rillig 	UNEXPORT_ENV
    240   1.713    rillig } UnexportWhat;
    241   1.713    rillig 
    242   1.261    rillig /* Flags for pattern matching in the :S and :C modifiers */
    243   1.927    rillig typedef struct PatternFlags {
    244   1.987    rillig 	bool subGlobal:1;	/* 'g': replace as often as possible */
    245   1.987    rillig 	bool subOnce:1;		/* '1': replace only once */
    246   1.987    rillig 	bool anchorStart:1;	/* '^': match only at start of word */
    247   1.987    rillig 	bool anchorEnd:1;	/* '$': match only at end of word */
    248   1.927    rillig } PatternFlags;
    249    1.16  christos 
    250   1.830    rillig /* SepBuf builds a string from words interleaved with separators. */
    251   1.710    rillig typedef struct SepBuf {
    252   1.710    rillig 	Buffer buf;
    253   1.895    rillig 	bool needSep;
    254   1.710    rillig 	/* Usually ' ', but see the ':ts' modifier. */
    255   1.710    rillig 	char sep;
    256   1.710    rillig } SepBuf;
    257   1.710    rillig 
    258  1.1120    rillig typedef enum {
    259  1.1120    rillig 	VSK_TARGET,
    260  1.1146    rillig 	VSK_COMMAND,
    261  1.1120    rillig 	VSK_VARNAME,
    262  1.1147    rillig 	VSK_INDIRECT_MODIFIERS,
    263  1.1124    rillig 	VSK_COND,
    264  1.1124    rillig 	VSK_COND_THEN,
    265  1.1124    rillig 	VSK_COND_ELSE,
    266  1.1133    rillig 	VSK_EXPR,
    267  1.1133    rillig 	VSK_EXPR_PARSE
    268  1.1120    rillig } EvalStackElementKind;
    269  1.1120    rillig 
    270  1.1102    rillig typedef struct {
    271  1.1120    rillig 	EvalStackElementKind kind;
    272  1.1120    rillig 	const char *str;
    273  1.1128    rillig 	const FStr *value;
    274  1.1102    rillig } EvalStackElement;
    275  1.1102    rillig 
    276  1.1102    rillig typedef struct {
    277  1.1102    rillig 	EvalStackElement *elems;
    278  1.1102    rillig 	size_t len;
    279  1.1102    rillig 	size_t cap;
    280  1.1102    rillig } EvalStack;
    281   1.710    rillig 
    282  1.1088    rillig /* Whether we have replaced the original environ (which we cannot free). */
    283   1.710    rillig char **savedEnv = NULL;
    284   1.710    rillig 
    285   1.778    rillig /*
    286   1.778    rillig  * Special return value for Var_Parse, indicating a parse error.  It may be
    287   1.710    rillig  * caused by an undefined variable, a syntax error in a modifier or
    288   1.778    rillig  * something entirely different.
    289   1.778    rillig  */
    290   1.710    rillig char var_Error[] = "";
    291   1.710    rillig 
    292   1.778    rillig /*
    293   1.778    rillig  * Special return value for Var_Parse, indicating an undefined variable in
    294  1.1119    rillig  * a case where VARE_EVAL_DEFINED is not set.  This undefined variable is
    295   1.710    rillig  * typically a dynamic variable such as ${.TARGET}, whose expansion needs to
    296   1.778    rillig  * be deferred until it is defined in an actual target.
    297   1.830    rillig  *
    298  1.1119    rillig  * See VARE_EVAL_KEEP_UNDEFINED.
    299   1.778    rillig  */
    300   1.710    rillig static char varUndefined[] = "";
    301   1.710    rillig 
    302   1.710    rillig /*
    303   1.710    rillig  * Traditionally this make consumed $$ during := like any other expansion.
    304   1.710    rillig  * Other make's do not, and this make follows straight since 2016-01-09.
    305   1.710    rillig  *
    306   1.895    rillig  * This knob allows controlling the behavior:
    307   1.895    rillig  *	false to consume $$ during := assignment.
    308   1.895    rillig  *	true to preserve $$ during := assignment.
    309   1.710    rillig  */
    310   1.710    rillig #define MAKE_SAVE_DOLLARS ".MAKE.SAVE_DOLLARS"
    311   1.895    rillig static bool save_dollars = true;
    312   1.710    rillig 
    313   1.710    rillig /*
    314   1.807    rillig  * A scope collects variable names and their values.
    315   1.807    rillig  *
    316   1.807    rillig  * The main scope is SCOPE_GLOBAL, which contains the variables that are set
    317   1.807    rillig  * in the makefiles.  SCOPE_INTERNAL acts as a fallback for SCOPE_GLOBAL and
    318   1.807    rillig  * contains some internal make variables.  These internal variables can thus
    319   1.807    rillig  * be overridden, they can also be restored by undefining the overriding
    320   1.807    rillig  * variable.
    321   1.807    rillig  *
    322   1.807    rillig  * SCOPE_CMDLINE contains variables from the command line arguments.  These
    323   1.807    rillig  * override variables from SCOPE_GLOBAL.
    324   1.807    rillig  *
    325   1.807    rillig  * There is no scope for environment variables, these are generated on-the-fly
    326  1.1088    rillig  * whenever they are referenced.
    327   1.807    rillig  *
    328   1.807    rillig  * Each target has its own scope, containing the 7 target-local variables
    329  1.1006       sjg  * .TARGET, .ALLSRC, etc.  Variables set on dependency lines also go in
    330  1.1006       sjg  * this scope.
    331   1.807    rillig  */
    332   1.807    rillig 
    333   1.807    rillig GNode *SCOPE_CMDLINE;
    334   1.807    rillig GNode *SCOPE_GLOBAL;
    335   1.807    rillig GNode *SCOPE_INTERNAL;
    336   1.710    rillig 
    337   1.710    rillig static VarExportedMode var_exportedVars = VAR_EXPORTED_NONE;
    338   1.710    rillig 
    339   1.951    rillig static const char VarEvalMode_Name[][32] = {
    340  1.1119    rillig 	"parse",
    341  1.1047    rillig 	"parse-balanced",
    342   1.906    rillig 	"eval",
    343  1.1144    rillig 	"eval-defined-loud",
    344   1.906    rillig 	"eval-defined",
    345   1.906    rillig 	"eval-keep-undefined",
    346   1.906    rillig 	"eval-keep-dollar-and-undefined",
    347   1.906    rillig };
    348   1.711    rillig 
    349  1.1102    rillig static EvalStack evalStack;
    350  1.1102    rillig 
    351  1.1102    rillig 
    352  1.1120    rillig static void
    353  1.1128    rillig EvalStack_Push(EvalStackElementKind kind, const char *str, const FStr *value)
    354  1.1102    rillig {
    355  1.1102    rillig 	if (evalStack.len >= evalStack.cap) {
    356  1.1102    rillig 		evalStack.cap = 16 + 2 * evalStack.cap;
    357  1.1102    rillig 		evalStack.elems = bmake_realloc(evalStack.elems,
    358  1.1102    rillig 		    evalStack.cap * sizeof(*evalStack.elems));
    359  1.1102    rillig 	}
    360  1.1120    rillig 	evalStack.elems[evalStack.len].kind = kind;
    361  1.1120    rillig 	evalStack.elems[evalStack.len].str = str;
    362  1.1128    rillig 	evalStack.elems[evalStack.len].value = value;
    363  1.1102    rillig 	evalStack.len++;
    364  1.1102    rillig }
    365  1.1102    rillig 
    366  1.1120    rillig static void
    367  1.1102    rillig EvalStack_Pop(void)
    368  1.1102    rillig {
    369  1.1102    rillig 	assert(evalStack.len > 0);
    370  1.1102    rillig 	evalStack.len--;
    371  1.1102    rillig }
    372  1.1102    rillig 
    373  1.1152    rillig bool
    374  1.1139    rillig EvalStack_PrintDetails(void)
    375  1.1102    rillig {
    376  1.1102    rillig 	size_t i;
    377  1.1102    rillig 
    378  1.1139    rillig 	for (i = evalStack.len; i > 0; i--) {
    379  1.1124    rillig 		static const char descr[][42] = {
    380  1.1124    rillig 			"in target",
    381  1.1146    rillig 			"in command",
    382  1.1124    rillig 			"while evaluating variable",
    383  1.1147    rillig 			"while evaluating indirect modifiers",
    384  1.1124    rillig 			"while evaluating condition",
    385  1.1124    rillig 			"while evaluating then-branch of condition",
    386  1.1124    rillig 			"while evaluating else-branch of condition",
    387  1.1124    rillig 			"while evaluating",
    388  1.1133    rillig 			"while parsing",
    389  1.1124    rillig 		};
    390  1.1139    rillig 		EvalStackElement *elem = evalStack.elems + i - 1;
    391  1.1132    rillig 		EvalStackElementKind kind = elem->kind;
    392  1.1140    rillig 		const char* value = elem->value != NULL
    393  1.1140    rillig 		    && (kind == VSK_VARNAME || kind == VSK_EXPR)
    394  1.1140    rillig 		    ? elem->value->str : NULL;
    395  1.1140    rillig 
    396  1.1140    rillig 		debug_printf("\t%s \"%s%s%s\"\n", descr[kind], elem->str,
    397  1.1140    rillig 		    value != NULL ? "\" with value \"" : "",
    398  1.1140    rillig 		    value != NULL ? value : "");
    399  1.1102    rillig 	}
    400  1.1152    rillig 	return evalStack.len > 0;
    401  1.1102    rillig }
    402   1.904    rillig 
    403   1.569    rillig static Var *
    404   1.978    rillig VarNew(FStr name, const char *value,
    405   1.978    rillig        bool shortLived, bool fromEnvironment, bool readOnly)
    406   1.569    rillig {
    407   1.703    rillig 	size_t value_len = strlen(value);
    408   1.703    rillig 	Var *var = bmake_malloc(sizeof *var);
    409   1.744    rillig 	var->name = name;
    410   1.703    rillig 	Buf_InitSize(&var->val, value_len + 1);
    411   1.703    rillig 	Buf_AddBytes(&var->val, value, value_len);
    412   1.902    rillig 	var->fromCmd = false;
    413   1.978    rillig 	var->shortLived = shortLived;
    414   1.978    rillig 	var->fromEnvironment = fromEnvironment;
    415   1.902    rillig 	var->readOnly = readOnly;
    416  1.1121    rillig 	var->readOnlyLoud = false;
    417   1.902    rillig 	var->inUse = false;
    418   1.902    rillig 	var->exported = false;
    419   1.902    rillig 	var->reexport = false;
    420   1.703    rillig 	return var;
    421   1.569    rillig }
    422   1.569    rillig 
    423   1.916    rillig static Substring
    424   1.916    rillig CanonicalVarname(Substring name)
    425     1.1       cgd {
    426   1.916    rillig 
    427   1.916    rillig 	if (!(Substring_Length(name) > 0 && name.start[0] == '.'))
    428   1.916    rillig 		return name;
    429   1.916    rillig 
    430   1.916    rillig 	if (Substring_Equals(name, ".ALLSRC"))
    431   1.916    rillig 		return Substring_InitStr(ALLSRC);
    432   1.916    rillig 	if (Substring_Equals(name, ".ARCHIVE"))
    433   1.916    rillig 		return Substring_InitStr(ARCHIVE);
    434   1.916    rillig 	if (Substring_Equals(name, ".IMPSRC"))
    435   1.916    rillig 		return Substring_InitStr(IMPSRC);
    436   1.916    rillig 	if (Substring_Equals(name, ".MEMBER"))
    437   1.916    rillig 		return Substring_InitStr(MEMBER);
    438   1.916    rillig 	if (Substring_Equals(name, ".OODATE"))
    439   1.916    rillig 		return Substring_InitStr(OODATE);
    440   1.916    rillig 	if (Substring_Equals(name, ".PREFIX"))
    441   1.916    rillig 		return Substring_InitStr(PREFIX);
    442   1.916    rillig 	if (Substring_Equals(name, ".TARGET"))
    443   1.916    rillig 		return Substring_InitStr(TARGET);
    444   1.916    rillig 
    445  1.1079    rillig 	/* GNU make has an additional alias $^ == ${.ALLSRC}. */
    446  1.1079    rillig 
    447   1.916    rillig 	if (Substring_Equals(name, ".SHELL") && shellPath == NULL)
    448   1.916    rillig 		Shell_Init();
    449   1.242    rillig 
    450   1.703    rillig 	return name;
    451   1.580    rillig }
    452   1.580    rillig 
    453   1.587    rillig static Var *
    454  1.1160    rillig GNode_FindVar(GNode *scope, Substring varname, unsigned hash)
    455   1.587    rillig {
    456   1.916    rillig 	return HashTable_FindValueBySubstringHash(&scope->vars, varname, hash);
    457   1.587    rillig }
    458   1.587    rillig 
    459   1.778    rillig /*
    460   1.802    rillig  * Find the variable in the scope, and maybe in other scopes as well.
    461   1.580    rillig  *
    462   1.580    rillig  * Input:
    463   1.607    rillig  *	name		name to find, is not expanded any further
    464   1.802    rillig  *	scope		scope in which to look first
    465   1.895    rillig  *	elsewhere	true to look in other scopes as well
    466   1.580    rillig  *
    467   1.580    rillig  * Results:
    468   1.605    rillig  *	The found variable, or NULL if the variable does not exist.
    469   1.977    rillig  *	If the variable is short-lived (such as environment variables), it
    470   1.977    rillig  *	must be freed using VarFreeShortLived after use.
    471   1.580    rillig  */
    472   1.580    rillig static Var *
    473   1.916    rillig VarFindSubstring(Substring name, GNode *scope, bool elsewhere)
    474   1.580    rillig {
    475   1.703    rillig 	Var *var;
    476  1.1160    rillig 	unsigned nameHash;
    477   1.703    rillig 
    478   1.830    rillig 	/* Replace '.TARGET' with '@', likewise for other local variables. */
    479   1.703    rillig 	name = CanonicalVarname(name);
    480   1.916    rillig 	nameHash = Hash_Substring(name);
    481   1.580    rillig 
    482   1.802    rillig 	var = GNode_FindVar(scope, name, nameHash);
    483   1.703    rillig 	if (!elsewhere)
    484   1.703    rillig 		return var;
    485   1.160  christos 
    486   1.802    rillig 	if (var == NULL && scope != SCOPE_CMDLINE)
    487   1.801    rillig 		var = GNode_FindVar(SCOPE_CMDLINE, name, nameHash);
    488     1.1       cgd 
    489   1.802    rillig 	if (!opts.checkEnvFirst && var == NULL && scope != SCOPE_GLOBAL) {
    490   1.801    rillig 		var = GNode_FindVar(SCOPE_GLOBAL, name, nameHash);
    491   1.802    rillig 		if (var == NULL && scope != SCOPE_INTERNAL) {
    492   1.801    rillig 			/* SCOPE_INTERNAL is subordinate to SCOPE_GLOBAL */
    493   1.801    rillig 			var = GNode_FindVar(SCOPE_INTERNAL, name, nameHash);
    494   1.703    rillig 		}
    495   1.184       sjg 	}
    496   1.399    rillig 
    497   1.703    rillig 	if (var == NULL) {
    498  1.1105    rillig 		FStr envName = Substring_Str(name);
    499  1.1105    rillig 		const char *envValue = getenv(envName.str);
    500   1.916    rillig 		if (envValue != NULL)
    501   1.978    rillig 			return VarNew(envName, envValue, true, true, false);
    502   1.916    rillig 		FStr_Done(&envName);
    503     1.1       cgd 
    504   1.802    rillig 		if (opts.checkEnvFirst && scope != SCOPE_GLOBAL) {
    505   1.801    rillig 			var = GNode_FindVar(SCOPE_GLOBAL, name, nameHash);
    506   1.802    rillig 			if (var == NULL && scope != SCOPE_INTERNAL)
    507   1.801    rillig 				var = GNode_FindVar(SCOPE_INTERNAL, name,
    508   1.703    rillig 				    nameHash);
    509   1.703    rillig 			return var;
    510   1.703    rillig 		}
    511   1.399    rillig 
    512   1.703    rillig 		return NULL;
    513     1.1       cgd 	}
    514   1.399    rillig 
    515   1.703    rillig 	return var;
    516     1.1       cgd }
    517     1.1       cgd 
    518   1.916    rillig static Var *
    519   1.916    rillig VarFind(const char *name, GNode *scope, bool elsewhere)
    520   1.916    rillig {
    521   1.916    rillig 	return VarFindSubstring(Substring_InitStr(name), scope, elsewhere);
    522   1.916    rillig }
    523   1.916    rillig 
    524   1.977    rillig /* If the variable is short-lived, free it, including its value. */
    525   1.837    rillig static void
    526   1.977    rillig VarFreeShortLived(Var *v)
    527   1.105  christos {
    528   1.978    rillig 	if (!v->shortLived)
    529   1.837    rillig 		return;
    530   1.605    rillig 
    531   1.711    rillig 	FStr_Done(&v->name);
    532   1.837    rillig 	Buf_Done(&v->val);
    533   1.703    rillig 	free(v);
    534   1.105  christos }
    535   1.105  christos 
    536  1.1018    rillig static const char *
    537  1.1018    rillig ValueDescription(const char *value)
    538  1.1018    rillig {
    539  1.1018    rillig 	if (value[0] == '\0')
    540  1.1018    rillig 		return "# (empty)";
    541  1.1019    rillig 	if (ch_isspace(value[strlen(value) - 1]))
    542  1.1018    rillig 		return "# (ends with space)";
    543  1.1018    rillig 	return "";
    544  1.1018    rillig }
    545  1.1018    rillig 
    546   1.831    rillig /* Add a new variable of the given name and value to the given scope. */
    547   1.833    rillig static Var *
    548   1.831    rillig VarAdd(const char *name, const char *value, GNode *scope, VarSetFlags flags)
    549     1.1       cgd {
    550   1.802    rillig 	HashEntry *he = HashTable_CreateEntry(&scope->vars, name, NULL);
    551   1.831    rillig 	Var *v = VarNew(FStr_InitRefer(/* aliased to */ he->key), value,
    552   1.978    rillig 	    false, false, (flags & VAR_SET_READONLY) != 0);
    553   1.703    rillig 	HashEntry_Set(he, v);
    554  1.1018    rillig 	DEBUG4(VAR, "%s: %s = %s%s\n",
    555  1.1018    rillig 	    scope->name, name, value, ValueDescription(value));
    556   1.833    rillig 	return v;
    557     1.1       cgd }
    558     1.1       cgd 
    559   1.736    rillig /*
    560   1.802    rillig  * Remove a variable from a scope, freeing all related memory as well.
    561   1.736    rillig  * The variable name is kept as-is, it is not expanded.
    562   1.736    rillig  */
    563   1.736    rillig void
    564   1.805    rillig Var_Delete(GNode *scope, const char *varname)
    565   1.736    rillig {
    566   1.802    rillig 	HashEntry *he = HashTable_FindEntry(&scope->vars, varname);
    567   1.736    rillig 	Var *v;
    568   1.736    rillig 
    569   1.736    rillig 	if (he == NULL) {
    570  1.1085    rillig 		DEBUG2(VAR, "%s: ignoring delete '%s' as it is not found\n",
    571  1.1017    rillig 		    scope->name, varname);
    572   1.736    rillig 		return;
    573   1.736    rillig 	}
    574   1.736    rillig 
    575   1.831    rillig 	v = he->value;
    576  1.1121    rillig 	if (v->readOnlyLoud) {
    577  1.1121    rillig 		Parse_Error(PARSE_FATAL,
    578  1.1121    rillig 		    "Cannot delete \"%s\" as it is read-only",
    579  1.1121    rillig 		    v->name.str);
    580  1.1121    rillig 		return;
    581  1.1121    rillig 	}
    582  1.1056       sjg 	if (v->readOnly) {
    583  1.1085    rillig 		DEBUG2(VAR, "%s: ignoring delete '%s' as it is read-only\n",
    584  1.1056       sjg 		    scope->name, varname);
    585  1.1056       sjg 		return;
    586  1.1056       sjg 	}
    587   1.963    rillig 	if (v->inUse) {
    588   1.963    rillig 		Parse_Error(PARSE_FATAL,
    589   1.969    rillig 		    "Cannot delete variable \"%s\" while it is used",
    590   1.963    rillig 		    v->name.str);
    591   1.963    rillig 		return;
    592   1.963    rillig 	}
    593  1.1017    rillig 
    594  1.1085    rillig 	DEBUG2(VAR, "%s: delete %s\n", scope->name, varname);
    595   1.902    rillig 	if (v->exported)
    596   1.736    rillig 		unsetenv(v->name.str);
    597  1.1045    rillig 	if (strcmp(v->name.str, ".MAKE.EXPORTED") == 0)
    598   1.736    rillig 		var_exportedVars = VAR_EXPORTED_NONE;
    599  1.1017    rillig 
    600   1.736    rillig 	assert(v->name.freeIt == NULL);
    601   1.802    rillig 	HashTable_DeleteEntry(&scope->vars, he);
    602   1.784    rillig 	Buf_Done(&v->val);
    603   1.736    rillig 	free(v);
    604   1.736    rillig }
    605   1.736    rillig 
    606  1.1111    rillig #ifdef CLEANUP
    607  1.1111    rillig void
    608  1.1111    rillig Var_DeleteAll(GNode *scope)
    609  1.1111    rillig {
    610  1.1113    rillig 	HashIter hi;
    611  1.1113    rillig 	HashIter_Init(&hi, &scope->vars);
    612  1.1114    rillig 	while (HashIter_Next(&hi)) {
    613  1.1113    rillig 		Var *v = hi.entry->value;
    614  1.1113    rillig 		Buf_Done(&v->val);
    615  1.1113    rillig 		free(v);
    616  1.1111    rillig 	}
    617  1.1111    rillig }
    618  1.1111    rillig #endif
    619  1.1111    rillig 
    620   1.778    rillig /*
    621   1.762    rillig  * Undefine one or more variables from the global scope.
    622   1.762    rillig  * The argument is expanded exactly once and then split into words.
    623   1.737    rillig  */
    624   1.735    rillig void
    625   1.762    rillig Var_Undef(const char *arg)
    626   1.735    rillig {
    627   1.762    rillig 	char *expanded;
    628   1.762    rillig 	Words varnames;
    629   1.762    rillig 	size_t i;
    630   1.762    rillig 
    631   1.762    rillig 	if (arg[0] == '\0') {
    632   1.762    rillig 		Parse_Error(PARSE_FATAL,
    633   1.762    rillig 		    "The .undef directive requires an argument");
    634   1.762    rillig 		return;
    635   1.762    rillig 	}
    636   1.735    rillig 
    637  1.1119    rillig 	expanded = Var_Subst(arg, SCOPE_GLOBAL, VARE_EVAL);
    638  1.1043    rillig 	if (expanded == var_Error) {
    639  1.1043    rillig 		/* TODO: Make this part of the code reachable. */
    640   1.737    rillig 		Parse_Error(PARSE_FATAL,
    641   1.762    rillig 		    "Error in variable names to be undefined");
    642   1.762    rillig 		return;
    643   1.762    rillig 	}
    644   1.762    rillig 
    645   1.895    rillig 	varnames = Str_Words(expanded, false);
    646   1.762    rillig 	if (varnames.len == 1 && varnames.words[0][0] == '\0')
    647   1.762    rillig 		varnames.len = 0;
    648   1.762    rillig 
    649   1.762    rillig 	for (i = 0; i < varnames.len; i++) {
    650   1.762    rillig 		const char *varname = varnames.words[i];
    651   1.804    rillig 		Global_Delete(varname);
    652   1.737    rillig 	}
    653   1.735    rillig 
    654   1.762    rillig 	Words_Free(varnames);
    655   1.763    rillig 	free(expanded);
    656   1.735    rillig }
    657   1.735    rillig 
    658   1.895    rillig static bool
    659   1.598    rillig MayExport(const char *name)
    660   1.118       sjg {
    661   1.703    rillig 	if (name[0] == '.')
    662   1.895    rillig 		return false;	/* skip internals */
    663   1.703    rillig 	if (name[0] == '-')
    664   1.895    rillig 		return false;	/* skip misnamed variables */
    665   1.703    rillig 	if (name[1] == '\0') {
    666   1.703    rillig 		/*
    667   1.703    rillig 		 * A single char.
    668   1.802    rillig 		 * If it is one of the variables that should only appear in
    669   1.802    rillig 		 * local scope, skip it, else we can get Var_Subst
    670   1.703    rillig 		 * into a loop.
    671   1.703    rillig 		 */
    672   1.703    rillig 		switch (name[0]) {
    673   1.703    rillig 		case '@':
    674   1.703    rillig 		case '%':
    675   1.703    rillig 		case '*':
    676   1.703    rillig 		case '!':
    677   1.895    rillig 			return false;
    678   1.703    rillig 		}
    679   1.118       sjg 	}
    680   1.895    rillig 	return true;
    681   1.598    rillig }
    682   1.598    rillig 
    683   1.895    rillig static bool
    684  1.1100       sjg ExportVarEnv(Var *v, GNode *scope)
    685   1.776    rillig {
    686   1.776    rillig 	const char *name = v->name.str;
    687   1.777    rillig 	char *val = v->val.data;
    688   1.777    rillig 	char *expr;
    689   1.776    rillig 
    690   1.902    rillig 	if (v->exported && !v->reexport)
    691   1.895    rillig 		return false;	/* nothing to do */
    692   1.776    rillig 
    693   1.777    rillig 	if (strchr(val, '$') == NULL) {
    694   1.902    rillig 		if (!v->exported)
    695   1.776    rillig 			setenv(name, val, 1);
    696   1.895    rillig 		return true;
    697   1.776    rillig 	}
    698   1.776    rillig 
    699  1.1070    rillig 	if (v->inUse)
    700  1.1070    rillig 		return false;	/* see EMPTY_SHELL in directive-export.mk */
    701   1.776    rillig 
    702   1.777    rillig 	/* XXX: name is injected without escaping it */
    703   1.777    rillig 	expr = str_concat3("${", name, "}");
    704  1.1119    rillig 	val = Var_Subst(expr, scope, VARE_EVAL);
    705  1.1100       sjg 	if (scope != SCOPE_GLOBAL) {
    706  1.1101    rillig 		/* we will need to re-export the global version */
    707  1.1100       sjg 		v = VarFind(name, SCOPE_GLOBAL, false);
    708  1.1101    rillig 		if (v != NULL)
    709  1.1100       sjg 			v->exported = false;
    710  1.1100       sjg 	}
    711   1.777    rillig 	/* TODO: handle errors */
    712   1.777    rillig 	setenv(name, val, 1);
    713   1.777    rillig 	free(val);
    714   1.777    rillig 	free(expr);
    715   1.895    rillig 	return true;
    716   1.776    rillig }
    717   1.776    rillig 
    718   1.895    rillig static bool
    719   1.776    rillig ExportVarPlain(Var *v)
    720   1.598    rillig {
    721   1.777    rillig 	if (strchr(v->val.data, '$') == NULL) {
    722   1.777    rillig 		setenv(v->name.str, v->val.data, 1);
    723   1.902    rillig 		v->exported = true;
    724   1.902    rillig 		v->reexport = false;
    725   1.895    rillig 		return true;
    726   1.776    rillig 	}
    727   1.776    rillig 
    728   1.777    rillig 	/*
    729   1.777    rillig 	 * Flag the variable as something we need to re-export.
    730   1.777    rillig 	 * No point actually exporting it now though,
    731   1.777    rillig 	 * the child process can do it at the last minute.
    732   1.830    rillig 	 * Avoid calling setenv more often than necessary since it can leak.
    733   1.777    rillig 	 */
    734   1.902    rillig 	v->exported = true;
    735   1.902    rillig 	v->reexport = true;
    736   1.895    rillig 	return true;
    737   1.776    rillig }
    738   1.401    rillig 
    739   1.895    rillig static bool
    740   1.776    rillig ExportVarLiteral(Var *v)
    741   1.776    rillig {
    742   1.902    rillig 	if (v->exported && !v->reexport)
    743   1.895    rillig 		return false;
    744   1.401    rillig 
    745   1.902    rillig 	if (!v->exported)
    746   1.777    rillig 		setenv(v->name.str, v->val.data, 1);
    747   1.605    rillig 
    748   1.895    rillig 	return true;
    749   1.118       sjg }
    750   1.118       sjg 
    751   1.118       sjg /*
    752   1.830    rillig  * Mark a single variable to be exported later for subprocesses.
    753   1.776    rillig  *
    754  1.1088    rillig  * Internal variables are not exported.
    755   1.776    rillig  */
    756   1.895    rillig static bool
    757  1.1100       sjg ExportVar(const char *name, GNode *scope, VarExportMode mode)
    758   1.776    rillig {
    759   1.776    rillig 	Var *v;
    760   1.776    rillig 
    761   1.776    rillig 	if (!MayExport(name))
    762   1.895    rillig 		return false;
    763   1.776    rillig 
    764  1.1100       sjg 	v = VarFind(name, scope, false);
    765  1.1100       sjg 	if (v == NULL && scope != SCOPE_GLOBAL)
    766  1.1100       sjg 		v = VarFind(name, SCOPE_GLOBAL, false);
    767   1.776    rillig 	if (v == NULL)
    768   1.895    rillig 		return false;
    769   1.776    rillig 
    770   1.776    rillig 	if (mode == VEM_ENV)
    771  1.1100       sjg 		return ExportVarEnv(v, scope);
    772   1.776    rillig 	else if (mode == VEM_PLAIN)
    773   1.776    rillig 		return ExportVarPlain(v);
    774   1.776    rillig 	else
    775   1.776    rillig 		return ExportVarLiteral(v);
    776   1.776    rillig }
    777   1.776    rillig 
    778   1.776    rillig /*
    779   1.765    rillig  * Actually export the variables that have been marked as needing to be
    780   1.765    rillig  * re-exported.
    781   1.118       sjg  */
    782   1.118       sjg void
    783  1.1100       sjg Var_ReexportVars(GNode *scope)
    784   1.118       sjg {
    785   1.775    rillig 	char *xvarnames;
    786   1.412    rillig 
    787   1.703    rillig 	/*
    788   1.703    rillig 	 * Several make implementations support this sort of mechanism for
    789   1.703    rillig 	 * tracking recursion - but each uses a different name.
    790   1.703    rillig 	 * We allow the makefiles to update MAKELEVEL and ensure
    791   1.703    rillig 	 * children see a correctly incremented value.
    792   1.703    rillig 	 */
    793  1.1067    rillig 	char level_buf[21];
    794  1.1067    rillig 	snprintf(level_buf, sizeof level_buf, "%d", makelevel + 1);
    795  1.1067    rillig 	setenv(MAKE_LEVEL_ENV, level_buf, 1);
    796   1.182  christos 
    797   1.703    rillig 	if (var_exportedVars == VAR_EXPORTED_NONE)
    798   1.703    rillig 		return;
    799   1.118       sjg 
    800   1.703    rillig 	if (var_exportedVars == VAR_EXPORTED_ALL) {
    801   1.703    rillig 		HashIter hi;
    802   1.575    rillig 
    803   1.831    rillig 		/* Ouch! Exporting all variables at once is crazy. */
    804   1.801    rillig 		HashIter_Init(&hi, &SCOPE_GLOBAL->vars);
    805  1.1114    rillig 		while (HashIter_Next(&hi)) {
    806   1.703    rillig 			Var *var = hi.entry->value;
    807  1.1100       sjg 			ExportVar(var->name.str, scope, VEM_ENV);
    808   1.703    rillig 		}
    809   1.703    rillig 		return;
    810   1.575    rillig 	}
    811   1.369    rillig 
    812  1.1045    rillig 	xvarnames = Var_Subst("${.MAKE.EXPORTED:O:u}", SCOPE_GLOBAL,
    813  1.1119    rillig 	    VARE_EVAL);
    814   1.703    rillig 	/* TODO: handle errors */
    815   1.775    rillig 	if (xvarnames[0] != '\0') {
    816   1.895    rillig 		Words varnames = Str_Words(xvarnames, false);
    817   1.703    rillig 		size_t i;
    818   1.703    rillig 
    819   1.775    rillig 		for (i = 0; i < varnames.len; i++)
    820  1.1100       sjg 			ExportVar(varnames.words[i], scope, VEM_ENV);
    821   1.775    rillig 		Words_Free(varnames);
    822   1.703    rillig 	}
    823   1.775    rillig 	free(xvarnames);
    824   1.118       sjg }
    825   1.118       sjg 
    826   1.726    rillig static void
    827   1.895    rillig ExportVars(const char *varnames, bool isExport, VarExportMode mode)
    828   1.831    rillig /* TODO: try to combine the parameters 'isExport' and 'mode'. */
    829   1.726    rillig {
    830   1.895    rillig 	Words words = Str_Words(varnames, false);
    831   1.727    rillig 	size_t i;
    832   1.727    rillig 
    833   1.727    rillig 	if (words.len == 1 && words.words[0][0] == '\0')
    834   1.727    rillig 		words.len = 0;
    835   1.727    rillig 
    836   1.727    rillig 	for (i = 0; i < words.len; i++) {
    837   1.727    rillig 		const char *varname = words.words[i];
    838  1.1100       sjg 		if (!ExportVar(varname, SCOPE_GLOBAL, mode))
    839   1.727    rillig 			continue;
    840   1.727    rillig 
    841   1.727    rillig 		if (var_exportedVars == VAR_EXPORTED_NONE)
    842   1.727    rillig 			var_exportedVars = VAR_EXPORTED_SOME;
    843   1.726    rillig 
    844   1.765    rillig 		if (isExport && mode == VEM_PLAIN)
    845  1.1045    rillig 			Global_Append(".MAKE.EXPORTED", varname);
    846   1.726    rillig 	}
    847   1.727    rillig 	Words_Free(words);
    848   1.726    rillig }
    849   1.726    rillig 
    850   1.728    rillig static void
    851   1.895    rillig ExportVarsExpand(const char *uvarnames, bool isExport, VarExportMode mode)
    852   1.728    rillig {
    853  1.1119    rillig 	char *xvarnames = Var_Subst(uvarnames, SCOPE_GLOBAL, VARE_EVAL);
    854   1.728    rillig 	/* TODO: handle errors */
    855   1.730    rillig 	ExportVars(xvarnames, isExport, mode);
    856   1.728    rillig 	free(xvarnames);
    857   1.728    rillig }
    858   1.728    rillig 
    859   1.731    rillig /* Export the named variables, or all variables. */
    860   1.118       sjg void
    861   1.731    rillig Var_Export(VarExportMode mode, const char *varnames)
    862   1.118       sjg {
    863  1.1117       sjg 	if (mode == VEM_ALL) {
    864   1.703    rillig 		var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
    865   1.703    rillig 		return;
    866  1.1117       sjg 	} else if (mode == VEM_PLAIN && varnames[0] == '\0') {
    867  1.1117       sjg 		Parse_Error(PARSE_WARNING, ".export requires an argument.");
    868  1.1117       sjg 		return;
    869   1.703    rillig 	}
    870   1.118       sjg 
    871   1.895    rillig 	ExportVarsExpand(varnames, true, mode);
    872   1.729    rillig }
    873   1.729    rillig 
    874   1.729    rillig void
    875   1.729    rillig Var_ExportVars(const char *varnames)
    876   1.729    rillig {
    877   1.895    rillig 	ExportVarsExpand(varnames, false, VEM_PLAIN);
    878   1.118       sjg }
    879   1.118       sjg 
    880   1.155       sjg 
    881   1.700    rillig static void
    882   1.714    rillig ClearEnv(void)
    883   1.701    rillig {
    884  1.1083    rillig 	const char *level;
    885   1.701    rillig 	char **newenv;
    886   1.701    rillig 
    887  1.1083    rillig 	level = getenv(MAKE_LEVEL_ENV);	/* we should preserve this */
    888   1.701    rillig 	if (environ == savedEnv) {
    889   1.701    rillig 		/* we have been here before! */
    890   1.701    rillig 		newenv = bmake_realloc(environ, 2 * sizeof(char *));
    891   1.701    rillig 	} else {
    892   1.701    rillig 		if (savedEnv != NULL) {
    893   1.701    rillig 			free(savedEnv);
    894   1.701    rillig 			savedEnv = NULL;
    895   1.701    rillig 		}
    896   1.701    rillig 		newenv = bmake_malloc(2 * sizeof(char *));
    897   1.701    rillig 	}
    898   1.701    rillig 
    899   1.701    rillig 	/* Note: we cannot safely free() the original environ. */
    900   1.701    rillig 	environ = savedEnv = newenv;
    901   1.701    rillig 	newenv[0] = NULL;
    902   1.701    rillig 	newenv[1] = NULL;
    903  1.1083    rillig 	if (level != NULL && *level != '\0')
    904  1.1083    rillig 		setenv(MAKE_LEVEL_ENV, level, 1);
    905   1.701    rillig }
    906   1.701    rillig 
    907   1.701    rillig static void
    908   1.895    rillig GetVarnamesToUnexport(bool isEnv, const char *arg,
    909   1.715    rillig 		      FStr *out_varnames, UnexportWhat *out_what)
    910   1.714    rillig {
    911   1.714    rillig 	UnexportWhat what;
    912   1.739    rillig 	FStr varnames = FStr_InitRefer("");
    913   1.714    rillig 
    914   1.732    rillig 	if (isEnv) {
    915   1.732    rillig 		if (arg[0] != '\0') {
    916   1.723    rillig 			Parse_Error(PARSE_FATAL,
    917   1.723    rillig 			    "The directive .unexport-env does not take "
    918   1.723    rillig 			    "arguments");
    919   1.830    rillig 			/* continue anyway */
    920   1.723    rillig 		}
    921   1.714    rillig 		what = UNEXPORT_ENV;
    922   1.723    rillig 
    923   1.732    rillig 	} else {
    924   1.732    rillig 		what = arg[0] != '\0' ? UNEXPORT_NAMED : UNEXPORT_ALL;
    925   1.714    rillig 		if (what == UNEXPORT_NAMED)
    926   1.739    rillig 			varnames = FStr_InitRefer(arg);
    927   1.714    rillig 	}
    928   1.714    rillig 
    929   1.714    rillig 	if (what != UNEXPORT_NAMED) {
    930  1.1045    rillig 		char *expanded = Var_Subst("${.MAKE.EXPORTED:O:u}",
    931  1.1119    rillig 		    SCOPE_GLOBAL, VARE_EVAL);
    932   1.714    rillig 		/* TODO: handle errors */
    933   1.739    rillig 		varnames = FStr_InitOwn(expanded);
    934   1.714    rillig 	}
    935   1.714    rillig 
    936   1.714    rillig 	*out_varnames = varnames;
    937   1.714    rillig 	*out_what = what;
    938   1.714    rillig }
    939   1.714    rillig 
    940   1.714    rillig static void
    941   1.959    rillig UnexportVar(Substring varname, UnexportWhat what)
    942   1.700    rillig {
    943   1.959    rillig 	Var *v = VarFindSubstring(varname, SCOPE_GLOBAL, false);
    944   1.700    rillig 	if (v == NULL) {
    945   1.959    rillig 		DEBUG2(VAR, "Not unexporting \"%.*s\" (not found)\n",
    946   1.959    rillig 		    (int)Substring_Length(varname), varname.start);
    947   1.700    rillig 		return;
    948   1.700    rillig 	}
    949   1.700    rillig 
    950   1.959    rillig 	DEBUG2(VAR, "Unexporting \"%.*s\"\n",
    951   1.959    rillig 	    (int)Substring_Length(varname), varname.start);
    952   1.902    rillig 	if (what != UNEXPORT_ENV && v->exported && !v->reexport)
    953   1.711    rillig 		unsetenv(v->name.str);
    954   1.902    rillig 	v->exported = false;
    955   1.902    rillig 	v->reexport = false;
    956   1.700    rillig 
    957   1.713    rillig 	if (what == UNEXPORT_NAMED) {
    958   1.713    rillig 		/* Remove the variable names from .MAKE.EXPORTED. */
    959   1.700    rillig 		/* XXX: v->name is injected without escaping it */
    960  1.1083    rillig 		char *expr = str_concat3(
    961  1.1083    rillig 		    "${.MAKE.EXPORTED:N", v->name.str, "}");
    962  1.1119    rillig 		char *filtered = Var_Subst(expr, SCOPE_GLOBAL, VARE_EVAL);
    963   1.700    rillig 		/* TODO: handle errors */
    964  1.1083    rillig 		Global_Set(".MAKE.EXPORTED", filtered);
    965  1.1083    rillig 		free(filtered);
    966   1.700    rillig 		free(expr);
    967   1.700    rillig 	}
    968   1.700    rillig }
    969   1.700    rillig 
    970   1.716    rillig static void
    971  1.1142    rillig UnexportVars(const char *varnames, UnexportWhat what)
    972   1.716    rillig {
    973   1.716    rillig 	size_t i;
    974   1.959    rillig 	SubstringWords words;
    975   1.717    rillig 
    976   1.717    rillig 	if (what == UNEXPORT_ENV)
    977   1.717    rillig 		ClearEnv();
    978   1.716    rillig 
    979  1.1142    rillig 	words = Substring_Words(varnames, false);
    980   1.959    rillig 	for (i = 0; i < words.len; i++)
    981   1.959    rillig 		UnexportVar(words.words[i], what);
    982   1.959    rillig 	SubstringWords_Free(words);
    983   1.716    rillig 
    984   1.716    rillig 	if (what != UNEXPORT_NAMED)
    985  1.1045    rillig 		Global_Delete(".MAKE.EXPORTED");
    986   1.716    rillig }
    987   1.716    rillig 
    988  1.1088    rillig /* Handle the .unexport and .unexport-env directives. */
    989   1.155       sjg void
    990   1.895    rillig Var_UnExport(bool isEnv, const char *arg)
    991   1.155       sjg {
    992   1.713    rillig 	UnexportWhat what;
    993   1.714    rillig 	FStr varnames;
    994   1.155       sjg 
    995   1.732    rillig 	GetVarnamesToUnexport(isEnv, arg, &varnames, &what);
    996  1.1142    rillig 	UnexportVars(varnames.str, what);
    997   1.712    rillig 	FStr_Done(&varnames);
    998   1.155       sjg }
    999   1.155       sjg 
   1000   1.747    rillig /* Set the variable to the value; the name is not expanded. */
   1001   1.800    rillig void
   1002   1.805    rillig Var_SetWithFlags(GNode *scope, const char *name, const char *val,
   1003   1.800    rillig 		 VarSetFlags flags)
   1004     1.1       cgd {
   1005   1.704    rillig 	Var *v;
   1006   1.142       dsl 
   1007   1.793    rillig 	assert(val != NULL);
   1008   1.793    rillig 	if (name[0] == '\0') {
   1009  1.1086    rillig 		DEBUG3(VAR,
   1010  1.1086    rillig 		    "%s: ignoring '%s = %s' as the variable name is empty\n",
   1011  1.1086    rillig 		    scope->name, name, val);
   1012   1.793    rillig 		return;
   1013   1.793    rillig 	}
   1014   1.793    rillig 
   1015  1.1089    rillig 	if (scope == SCOPE_GLOBAL
   1016  1.1089    rillig 	    && VarFind(name, SCOPE_CMDLINE, false) != NULL) {
   1017  1.1089    rillig 		/*
   1018  1.1089    rillig 		 * The global variable would not be visible anywhere.
   1019  1.1089    rillig 		 * Therefore, there is no point in setting it at all.
   1020  1.1089    rillig 		 */
   1021  1.1082    rillig 		DEBUG3(VAR,
   1022  1.1086    rillig 		    "%s: ignoring '%s = %s' "
   1023  1.1082    rillig 		    "due to a command line variable of the same name\n",
   1024  1.1086    rillig 		    scope->name, name, val);
   1025   1.834    rillig 		return;
   1026  1.1080    rillig 	}
   1027   1.400    rillig 
   1028   1.704    rillig 	/*
   1029   1.802    rillig 	 * Only look for a variable in the given scope since anything set
   1030   1.802    rillig 	 * here will override anything in a lower scope, so there's not much
   1031   1.830    rillig 	 * point in searching them all.
   1032   1.704    rillig 	 */
   1033   1.895    rillig 	v = VarFind(name, scope, false);
   1034   1.704    rillig 	if (v == NULL) {
   1035   1.802    rillig 		if (scope == SCOPE_CMDLINE && !(flags & VAR_SET_NO_EXPORT)) {
   1036   1.704    rillig 			/*
   1037  1.1105    rillig 			 * This variable would normally prevent the same name
   1038  1.1105    rillig 			 * being added to SCOPE_GLOBAL, so delete it from
   1039  1.1105    rillig 			 * there if needed. Otherwise -V name may show the
   1040  1.1105    rillig 			 * wrong value.
   1041   1.832    rillig 			 *
   1042   1.835    rillig 			 * See ExistsInCmdline.
   1043   1.704    rillig 			 */
   1044  1.1141    rillig 			Var *gl = VarFind(name, SCOPE_GLOBAL, false);
   1045  1.1145    rillig 			if (gl != NULL && strcmp(gl->val.data, val) == 0) {
   1046  1.1145    rillig 				DEBUG3(VAR,
   1047  1.1145    rillig 				    "%s: ignoring to override the global "
   1048  1.1145    rillig 				    "'%s = %s' from a command line variable "
   1049  1.1145    rillig 				    "as the value wouldn't change\n",
   1050  1.1145    rillig 				    scope->name, name, val);
   1051  1.1145    rillig 			} else if (gl != NULL && gl->readOnlyLoud)
   1052  1.1141    rillig 				Parse_Error(PARSE_FATAL,
   1053  1.1141    rillig 				    "Cannot override "
   1054  1.1141    rillig 				    "read-only global variable \"%s\" "
   1055  1.1141    rillig 				    "with a command line variable", name);
   1056  1.1141    rillig 			else
   1057  1.1141    rillig 				Var_Delete(SCOPE_GLOBAL, name);
   1058   1.704    rillig 		}
   1059   1.973       sjg 		if (strcmp(name, ".SUFFIXES") == 0) {
   1060  1.1079    rillig 			/* special: treat as read-only */
   1061  1.1086    rillig 			DEBUG3(VAR,
   1062  1.1086    rillig 			    "%s: ignoring '%s = %s' as it is read-only\n",
   1063   1.973       sjg 			    scope->name, name, val);
   1064   1.973       sjg 			return;
   1065   1.973       sjg 		}
   1066   1.833    rillig 		v = VarAdd(name, val, scope, flags);
   1067   1.704    rillig 	} else {
   1068  1.1121    rillig 		if (v->readOnlyLoud) {
   1069  1.1121    rillig 			Parse_Error(PARSE_FATAL,
   1070  1.1121    rillig 			    "Cannot overwrite \"%s\" as it is read-only",
   1071  1.1121    rillig 			    name);
   1072  1.1121    rillig 			return;
   1073  1.1121    rillig 		}
   1074   1.902    rillig 		if (v->readOnly && !(flags & VAR_SET_READONLY)) {
   1075  1.1086    rillig 			DEBUG3(VAR,
   1076  1.1086    rillig 			    "%s: ignoring '%s = %s' as it is read-only\n",
   1077   1.802    rillig 			    scope->name, name, val);
   1078   1.747    rillig 			return;
   1079   1.704    rillig 		}
   1080   1.998    rillig 		Buf_Clear(&v->val);
   1081   1.704    rillig 		Buf_AddStr(&v->val, val);
   1082   1.704    rillig 
   1083  1.1018    rillig 		DEBUG4(VAR, "%s: %s = %s%s\n",
   1084  1.1018    rillig 		    scope->name, name, val, ValueDescription(val));
   1085   1.902    rillig 		if (v->exported)
   1086  1.1100       sjg 			ExportVar(name, scope, VEM_PLAIN);
   1087   1.183       sjg 	}
   1088   1.833    rillig 
   1089  1.1076       sjg 	if (scope == SCOPE_CMDLINE) {
   1090   1.902    rillig 		v->fromCmd = true;
   1091  1.1079    rillig 
   1092  1.1079    rillig 		/*
   1093  1.1079    rillig 		 * Any variables given on the command line are automatically
   1094  1.1079    rillig 		 * exported to the environment (as per POSIX standard), except
   1095  1.1079    rillig 		 * for internals.
   1096  1.1079    rillig 		 */
   1097  1.1109       sjg 		if (!(flags & VAR_SET_NO_EXPORT)) {
   1098   1.704    rillig 
   1099  1.1076       sjg 			/*
   1100  1.1076       sjg 			 * If requested, don't export these in the
   1101  1.1076       sjg 			 * environment individually.  We still put
   1102  1.1076       sjg 			 * them in .MAKEOVERRIDES so that the
   1103  1.1077    rillig 			 * command-line settings continue to override
   1104  1.1076       sjg 			 * Makefile settings.
   1105  1.1076       sjg 			 */
   1106  1.1109       sjg 			if (!opts.varNoExportEnv && name[0] != '.')
   1107  1.1076       sjg 				setenv(name, val, 1);
   1108  1.1109       sjg 
   1109  1.1109       sjg 			if (!(flags & VAR_SET_INTERNAL))
   1110  1.1109       sjg 				Global_Append(".MAKEOVERRIDES", name);
   1111  1.1076       sjg 		}
   1112   1.704    rillig 	}
   1113   1.833    rillig 
   1114   1.704    rillig 	if (name[0] == '.' && strcmp(name, MAKE_SAVE_DOLLARS) == 0)
   1115   1.704    rillig 		save_dollars = ParseBoolean(val, save_dollars);
   1116   1.205       sjg 
   1117   1.704    rillig 	if (v != NULL)
   1118   1.977    rillig 		VarFreeShortLived(v);
   1119     1.1       cgd }
   1120     1.1       cgd 
   1121   1.798    rillig void
   1122   1.805    rillig Var_Set(GNode *scope, const char *name, const char *val)
   1123   1.798    rillig {
   1124   1.805    rillig 	Var_SetWithFlags(scope, name, val, VAR_SET_NONE);
   1125   1.798    rillig }
   1126   1.798    rillig 
   1127   1.718    rillig /*
   1128  1.1079    rillig  * In the scope, expand the variable name once, then create the variable or
   1129  1.1079    rillig  * replace its value.
   1130   1.230    rillig  */
   1131   1.230    rillig void
   1132   1.805    rillig Var_SetExpand(GNode *scope, const char *name, const char *val)
   1133   1.230    rillig {
   1134  1.1007    rillig 	FStr varname = FStr_InitRefer(name);
   1135  1.1007    rillig 
   1136  1.1007    rillig 	assert(val != NULL);
   1137  1.1007    rillig 
   1138  1.1119    rillig 	Var_Expand(&varname, scope, VARE_EVAL);
   1139  1.1007    rillig 
   1140  1.1007    rillig 	if (varname.str[0] == '\0') {
   1141  1.1086    rillig 		DEBUG4(VAR,
   1142  1.1086    rillig 		    "%s: ignoring '%s = %s' "
   1143  1.1086    rillig 		    "as the variable name '%s' expands to empty\n",
   1144  1.1089    rillig 		    scope->name, varname.str, val, name);
   1145  1.1007    rillig 	} else
   1146  1.1007    rillig 		Var_SetWithFlags(scope, varname.str, val, VAR_SET_NONE);
   1147  1.1007    rillig 
   1148  1.1007    rillig 	FStr_Done(&varname);
   1149   1.230    rillig }
   1150   1.230    rillig 
   1151   1.791    rillig void
   1152   1.792    rillig Global_Set(const char *name, const char *value)
   1153   1.792    rillig {
   1154   1.805    rillig 	Var_Set(SCOPE_GLOBAL, name, value);
   1155   1.792    rillig }
   1156   1.792    rillig 
   1157   1.792    rillig void
   1158   1.804    rillig Global_Delete(const char *name)
   1159   1.804    rillig {
   1160   1.805    rillig 	Var_Delete(SCOPE_GLOBAL, name);
   1161   1.804    rillig }
   1162   1.804    rillig 
   1163  1.1039       sjg void
   1164  1.1039       sjg Global_Set_ReadOnly(const char *name, const char *value)
   1165  1.1039       sjg {
   1166  1.1121    rillig 	Var_SetWithFlags(SCOPE_GLOBAL, name, value, VAR_SET_NONE);
   1167  1.1121    rillig 	VarFind(name, SCOPE_GLOBAL, false)->readOnlyLoud = true;
   1168  1.1039       sjg }
   1169  1.1039       sjg 
   1170   1.718    rillig /*
   1171   1.794    rillig  * Append the value to the named variable.
   1172   1.794    rillig  *
   1173   1.794    rillig  * If the variable doesn't exist, it is created.  Otherwise a single space
   1174   1.794    rillig  * and the given value are appended.
   1175   1.794    rillig  */
   1176   1.794    rillig void
   1177   1.805    rillig Var_Append(GNode *scope, const char *name, const char *val)
   1178   1.794    rillig {
   1179   1.794    rillig 	Var *v;
   1180   1.794    rillig 
   1181   1.802    rillig 	v = VarFind(name, scope, scope == SCOPE_GLOBAL);
   1182   1.794    rillig 
   1183   1.794    rillig 	if (v == NULL) {
   1184   1.805    rillig 		Var_SetWithFlags(scope, name, val, VAR_SET_NONE);
   1185  1.1121    rillig 	} else if (v->readOnlyLoud) {
   1186  1.1121    rillig 		Parse_Error(PARSE_FATAL,
   1187  1.1121    rillig 		    "Cannot append to \"%s\" as it is read-only", name);
   1188  1.1121    rillig 		return;
   1189   1.902    rillig 	} else if (v->readOnly) {
   1190  1.1086    rillig 		DEBUG3(VAR, "%s: ignoring '%s += %s' as it is read-only\n",
   1191  1.1086    rillig 		    scope->name, name, val);
   1192   1.902    rillig 	} else if (scope == SCOPE_CMDLINE || !v->fromCmd) {
   1193   1.794    rillig 		Buf_AddByte(&v->val, ' ');
   1194   1.794    rillig 		Buf_AddStr(&v->val, val);
   1195   1.794    rillig 
   1196   1.911    rillig 		DEBUG3(VAR, "%s: %s = %s\n", scope->name, name, v->val.data);
   1197   1.794    rillig 
   1198   1.978    rillig 		if (v->fromEnvironment) {
   1199  1.1014    rillig 			/* See VarAdd. */
   1200  1.1014    rillig 			HashEntry *he =
   1201  1.1014    rillig 			    HashTable_CreateEntry(&scope->vars, name, NULL);
   1202  1.1014    rillig 			HashEntry_Set(he, v);
   1203  1.1014    rillig 			FStr_Done(&v->name);
   1204  1.1014    rillig 			v->name = FStr_InitRefer(/* aliased to */ he->key);
   1205  1.1014    rillig 			v->shortLived = false;
   1206   1.978    rillig 			v->fromEnvironment = false;
   1207   1.794    rillig 		}
   1208   1.794    rillig 	}
   1209   1.794    rillig }
   1210   1.794    rillig 
   1211   1.794    rillig /*
   1212  1.1088    rillig  * In the scope, expand the variable name once.  If the variable exists in the
   1213  1.1088    rillig  * scope, add a space and the value, otherwise set the variable to the value.
   1214   1.483    rillig  *
   1215  1.1088    rillig  * Appending to an environment variable only works in the global scope, that
   1216  1.1088    rillig  * is, for variable assignments in makefiles, but not inside conditions or the
   1217  1.1088    rillig  * commands of a target.
   1218     1.1       cgd  */
   1219     1.1       cgd void
   1220   1.805    rillig Var_AppendExpand(GNode *scope, const char *name, const char *val)
   1221     1.1       cgd {
   1222   1.838    rillig 	FStr xname = FStr_InitRefer(name);
   1223     1.1       cgd 
   1224   1.704    rillig 	assert(val != NULL);
   1225   1.460    rillig 
   1226  1.1119    rillig 	Var_Expand(&xname, scope, VARE_EVAL);
   1227  1.1001    rillig 	if (xname.str != name && xname.str[0] == '\0')
   1228  1.1086    rillig 		DEBUG4(VAR,
   1229  1.1086    rillig 		    "%s: ignoring '%s += %s' "
   1230  1.1086    rillig 		    "as the variable name '%s' expands to empty\n",
   1231  1.1086    rillig 		    scope->name, xname.str, val, name);
   1232  1.1001    rillig 	else
   1233  1.1001    rillig 		Var_Append(scope, xname.str, val);
   1234     1.1       cgd 
   1235   1.838    rillig 	FStr_Done(&xname);
   1236     1.1       cgd }
   1237     1.1       cgd 
   1238   1.791    rillig void
   1239   1.795    rillig Global_Append(const char *name, const char *value)
   1240   1.791    rillig {
   1241   1.805    rillig 	Var_Append(SCOPE_GLOBAL, name, value);
   1242   1.791    rillig }
   1243   1.791    rillig 
   1244   1.895    rillig bool
   1245   1.805    rillig Var_Exists(GNode *scope, const char *name)
   1246   1.796    rillig {
   1247   1.895    rillig 	Var *v = VarFind(name, scope, true);
   1248   1.796    rillig 	if (v == NULL)
   1249   1.895    rillig 		return false;
   1250   1.796    rillig 
   1251   1.977    rillig 	VarFreeShortLived(v);
   1252   1.895    rillig 	return true;
   1253   1.796    rillig }
   1254   1.796    rillig 
   1255   1.778    rillig /*
   1256   1.802    rillig  * See if the given variable exists, in the given scope or in other
   1257   1.802    rillig  * fallback scopes.
   1258     1.1       cgd  *
   1259    1.70       wiz  * Input:
   1260   1.953    rillig  *	scope		scope in which to start search
   1261   1.953    rillig  *	name		name of the variable to find, is expanded once
   1262     1.1       cgd  */
   1263   1.895    rillig bool
   1264   1.805    rillig Var_ExistsExpand(GNode *scope, const char *name)
   1265     1.1       cgd {
   1266   1.747    rillig 	FStr varname = FStr_InitRefer(name);
   1267   1.895    rillig 	bool exists;
   1268   1.412    rillig 
   1269  1.1119    rillig 	Var_Expand(&varname, scope, VARE_EVAL);
   1270   1.805    rillig 	exists = Var_Exists(scope, varname.str);
   1271   1.747    rillig 	FStr_Done(&varname);
   1272   1.796    rillig 	return exists;
   1273     1.1       cgd }
   1274     1.1       cgd 
   1275   1.718    rillig /*
   1276   1.802    rillig  * Return the unexpanded value of the given variable in the given scope,
   1277  1.1066    rillig  * falling back to the command, global and environment scopes, in this order,
   1278  1.1066    rillig  * but see the -e option.
   1279     1.1       cgd  *
   1280    1.70       wiz  * Input:
   1281  1.1066    rillig  *	name		the name to find, is not expanded any further
   1282    1.70       wiz  *
   1283     1.1       cgd  * Results:
   1284   1.337    rillig  *	The value if the variable exists, NULL if it doesn't.
   1285   1.830    rillig  *	The value is valid until the next modification to any variable.
   1286     1.1       cgd  */
   1287   1.745    rillig FStr
   1288   1.805    rillig Var_Value(GNode *scope, const char *name)
   1289     1.1       cgd {
   1290   1.895    rillig 	Var *v = VarFind(name, scope, true);
   1291   1.703    rillig 	char *value;
   1292   1.703    rillig 
   1293   1.703    rillig 	if (v == NULL)
   1294   1.745    rillig 		return FStr_InitRefer(NULL);
   1295   1.412    rillig 
   1296   1.978    rillig 	if (!v->shortLived)
   1297   1.837    rillig 		return FStr_InitRefer(v->val.data);
   1298   1.837    rillig 
   1299   1.978    rillig 	value = v->val.data;
   1300   1.978    rillig 	v->val.data = NULL;
   1301   1.978    rillig 	VarFreeShortLived(v);
   1302   1.978    rillig 
   1303   1.837    rillig 	return FStr_InitOwn(value);
   1304     1.1       cgd }
   1305     1.1       cgd 
   1306  1.1088    rillig /* Set or clear the read-only attribute of the variable if it exists. */
   1307  1.1037       sjg void
   1308  1.1037       sjg Var_ReadOnly(const char *name, bool bf)
   1309  1.1037       sjg {
   1310  1.1037       sjg 	Var *v;
   1311  1.1037       sjg 
   1312  1.1037       sjg 	v = VarFind(name, SCOPE_GLOBAL, false);
   1313  1.1037       sjg 	if (v == NULL) {
   1314  1.1037       sjg 		DEBUG1(VAR, "Var_ReadOnly: %s not found\n", name);
   1315  1.1037       sjg 		return;
   1316  1.1037       sjg 	}
   1317  1.1037       sjg 	v->readOnly = bf;
   1318  1.1038       sjg 	DEBUG2(VAR, "Var_ReadOnly: %s %s\n", name, bf ? "true" : "false");
   1319  1.1037       sjg }
   1320  1.1037       sjg 
   1321  1.1037       sjg /*
   1322   1.778    rillig  * Return the unexpanded variable value from this node, without trying to look
   1323   1.802    rillig  * up the variable in any other scope.
   1324   1.778    rillig  */
   1325   1.616    rillig const char *
   1326   1.803    rillig GNode_ValueDirect(GNode *gn, const char *name)
   1327   1.616    rillig {
   1328   1.895    rillig 	Var *v = VarFind(name, gn, false);
   1329   1.785    rillig 	return v != NULL ? v->val.data : NULL;
   1330   1.616    rillig }
   1331   1.616    rillig 
   1332   1.906    rillig static VarEvalMode
   1333   1.906    rillig VarEvalMode_WithoutKeepDollar(VarEvalMode emode)
   1334   1.906    rillig {
   1335  1.1119    rillig 	return emode == VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED
   1336  1.1119    rillig 	    ? VARE_EVAL_KEEP_UNDEFINED : emode;
   1337   1.906    rillig }
   1338   1.906    rillig 
   1339   1.905    rillig static bool
   1340   1.906    rillig VarEvalMode_ShouldEval(VarEvalMode emode)
   1341   1.905    rillig {
   1342  1.1119    rillig 	return emode != VARE_PARSE;
   1343   1.906    rillig }
   1344   1.906    rillig 
   1345   1.906    rillig static bool
   1346   1.906    rillig VarEvalMode_ShouldKeepUndef(VarEvalMode emode)
   1347   1.906    rillig {
   1348  1.1119    rillig 	return emode == VARE_EVAL_KEEP_UNDEFINED ||
   1349  1.1119    rillig 	       emode == VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED;
   1350   1.906    rillig }
   1351   1.906    rillig 
   1352   1.906    rillig static bool
   1353   1.906    rillig VarEvalMode_ShouldKeepDollar(VarEvalMode emode)
   1354   1.906    rillig {
   1355  1.1119    rillig 	return emode == VARE_EVAL_KEEP_DOLLAR_AND_UNDEFINED;
   1356   1.905    rillig }
   1357   1.905    rillig 
   1358   1.905    rillig 
   1359   1.278    rillig static void
   1360   1.278    rillig SepBuf_Init(SepBuf *buf, char sep)
   1361   1.278    rillig {
   1362   1.703    rillig 	Buf_InitSize(&buf->buf, 32);
   1363   1.895    rillig 	buf->needSep = false;
   1364   1.703    rillig 	buf->sep = sep;
   1365   1.278    rillig }
   1366   1.278    rillig 
   1367   1.278    rillig static void
   1368   1.278    rillig SepBuf_Sep(SepBuf *buf)
   1369   1.278    rillig {
   1370   1.895    rillig 	buf->needSep = true;
   1371   1.278    rillig }
   1372   1.278    rillig 
   1373   1.278    rillig static void
   1374   1.314    rillig SepBuf_AddBytes(SepBuf *buf, const char *mem, size_t mem_size)
   1375   1.278    rillig {
   1376   1.703    rillig 	if (mem_size == 0)
   1377   1.703    rillig 		return;
   1378   1.703    rillig 	if (buf->needSep && buf->sep != '\0') {
   1379   1.703    rillig 		Buf_AddByte(&buf->buf, buf->sep);
   1380   1.895    rillig 		buf->needSep = false;
   1381   1.703    rillig 	}
   1382   1.703    rillig 	Buf_AddBytes(&buf->buf, mem, mem_size);
   1383   1.278    rillig }
   1384   1.278    rillig 
   1385   1.314    rillig static void
   1386  1.1055    rillig SepBuf_AddRange(SepBuf *buf, const char *start, const char *end)
   1387   1.314    rillig {
   1388   1.703    rillig 	SepBuf_AddBytes(buf, start, (size_t)(end - start));
   1389   1.314    rillig }
   1390   1.314    rillig 
   1391   1.314    rillig static void
   1392   1.314    rillig SepBuf_AddStr(SepBuf *buf, const char *str)
   1393   1.314    rillig {
   1394   1.703    rillig 	SepBuf_AddBytes(buf, str, strlen(str));
   1395   1.314    rillig }
   1396   1.314    rillig 
   1397   1.919    rillig static void
   1398   1.919    rillig SepBuf_AddSubstring(SepBuf *buf, Substring sub)
   1399   1.919    rillig {
   1400  1.1055    rillig 	SepBuf_AddRange(buf, sub.start, sub.end);
   1401   1.919    rillig }
   1402   1.919    rillig 
   1403   1.278    rillig static char *
   1404   1.784    rillig SepBuf_DoneData(SepBuf *buf)
   1405   1.278    rillig {
   1406   1.784    rillig 	return Buf_DoneData(&buf->buf);
   1407   1.278    rillig }
   1408   1.278    rillig 
   1409   1.278    rillig 
   1410   1.778    rillig /*
   1411  1.1075    rillig  * This callback for ModifyWords gets a single word from an expression
   1412   1.609    rillig  * and typically adds a modification of this word to the buffer. It may also
   1413   1.609    rillig  * do nothing or add several words.
   1414   1.609    rillig  *
   1415   1.822    rillig  * For example, when evaluating the modifier ':M*b' in ${:Ua b c:M*b}, the
   1416   1.822    rillig  * callback is called 3 times, once for "a", "b" and "c".
   1417   1.919    rillig  *
   1418   1.919    rillig  * Some ModifyWord functions assume that they are always passed a
   1419   1.919    rillig  * null-terminated substring, which is currently guaranteed but may change in
   1420   1.919    rillig  * the future.
   1421   1.778    rillig  */
   1422   1.919    rillig typedef void (*ModifyWordProc)(Substring word, SepBuf *buf, void *data);
   1423   1.244    rillig 
   1424   1.244    rillig 
   1425   1.278    rillig static void
   1426   1.919    rillig ModifyWord_Head(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
   1427     1.1       cgd {
   1428   1.919    rillig 	SepBuf_AddSubstring(buf, Substring_Dirname(word));
   1429     1.1       cgd }
   1430     1.1       cgd 
   1431   1.278    rillig static void
   1432   1.919    rillig ModifyWord_Tail(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
   1433     1.1       cgd {
   1434   1.919    rillig 	SepBuf_AddSubstring(buf, Substring_Basename(word));
   1435     1.1       cgd }
   1436     1.1       cgd 
   1437   1.278    rillig static void
   1438   1.919    rillig ModifyWord_Suffix(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
   1439     1.1       cgd {
   1440  1.1092    rillig 	const char *lastDot = Substring_FindLast(word, '.');
   1441   1.703    rillig 	if (lastDot != NULL)
   1442  1.1055    rillig 		SepBuf_AddRange(buf, lastDot + 1, word.end);
   1443     1.1       cgd }
   1444     1.1       cgd 
   1445   1.278    rillig static void
   1446   1.919    rillig ModifyWord_Root(Substring word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
   1447     1.1       cgd {
   1448   1.919    rillig 	const char *lastDot, *end;
   1449   1.919    rillig 
   1450  1.1092    rillig 	lastDot = Substring_FindLast(word, '.');
   1451   1.919    rillig 	end = lastDot != NULL ? lastDot : word.end;
   1452  1.1055    rillig 	SepBuf_AddRange(buf, word.start, end);
   1453     1.1       cgd }
   1454     1.1       cgd 
   1455   1.926    rillig struct ModifyWord_SysVSubstArgs {
   1456   1.806    rillig 	GNode *scope;
   1457   1.925    rillig 	Substring lhsPrefix;
   1458   1.925    rillig 	bool lhsPercent;
   1459   1.925    rillig 	Substring lhsSuffix;
   1460   1.703    rillig 	const char *rhs;
   1461   1.541    rillig };
   1462   1.276    rillig 
   1463   1.278    rillig static void
   1464   1.926    rillig ModifyWord_SysVSubst(Substring word, SepBuf *buf, void *data)
   1465     1.5       cgd {
   1466   1.926    rillig 	const struct ModifyWord_SysVSubstArgs *args = data;
   1467   1.925    rillig 	FStr rhs;
   1468   1.703    rillig 	const char *percent;
   1469   1.919    rillig 
   1470   1.925    rillig 	if (Substring_IsEmpty(word))
   1471   1.703    rillig 		return;
   1472   1.925    rillig 
   1473  1.1011    rillig 	if (!Substring_HasPrefix(word, args->lhsPrefix) ||
   1474  1.1011    rillig 	    !Substring_HasSuffix(word, args->lhsSuffix)) {
   1475  1.1011    rillig 		SepBuf_AddSubstring(buf, word);
   1476  1.1011    rillig 		return;
   1477  1.1011    rillig 	}
   1478   1.925    rillig 
   1479   1.925    rillig 	rhs = FStr_InitRefer(args->rhs);
   1480  1.1119    rillig 	Var_Expand(&rhs, args->scope, VARE_EVAL);
   1481   1.379    rillig 
   1482   1.925    rillig 	percent = args->lhsPercent ? strchr(rhs.str, '%') : NULL;
   1483   1.379    rillig 
   1484   1.925    rillig 	if (percent != NULL)
   1485  1.1055    rillig 		SepBuf_AddRange(buf, rhs.str, percent);
   1486   1.925    rillig 	if (percent != NULL || !args->lhsPercent)
   1487  1.1055    rillig 		SepBuf_AddRange(buf,
   1488   1.925    rillig 		    word.start + Substring_Length(args->lhsPrefix),
   1489   1.925    rillig 		    word.end - Substring_Length(args->lhsSuffix));
   1490   1.925    rillig 	SepBuf_AddStr(buf, percent != NULL ? percent + 1 : rhs.str);
   1491   1.379    rillig 
   1492   1.925    rillig 	FStr_Done(&rhs);
   1493     1.5       cgd }
   1494     1.5       cgd 
   1495   1.918    rillig static const char *
   1496   1.918    rillig Substring_Find(Substring haystack, Substring needle)
   1497   1.918    rillig {
   1498   1.918    rillig 	size_t len, needleLen, i;
   1499   1.918    rillig 
   1500   1.918    rillig 	len = Substring_Length(haystack);
   1501   1.918    rillig 	needleLen = Substring_Length(needle);
   1502   1.918    rillig 	for (i = 0; i + needleLen <= len; i++)
   1503   1.918    rillig 		if (memcmp(haystack.start + i, needle.start, needleLen) == 0)
   1504   1.918    rillig 			return haystack.start + i;
   1505   1.918    rillig 	return NULL;
   1506   1.918    rillig }
   1507   1.918    rillig 
   1508  1.1079    rillig struct ModifyWord_SubstArgs {
   1509  1.1079    rillig 	Substring lhs;
   1510  1.1079    rillig 	Substring rhs;
   1511  1.1079    rillig 	PatternFlags pflags;
   1512  1.1079    rillig 	bool matched;
   1513  1.1079    rillig };
   1514  1.1079    rillig 
   1515   1.278    rillig static void
   1516   1.919    rillig ModifyWord_Subst(Substring word, SepBuf *buf, void *data)
   1517     1.1       cgd {
   1518   1.703    rillig 	struct ModifyWord_SubstArgs *args = data;
   1519   1.918    rillig 	size_t wordLen, lhsLen;
   1520  1.1089    rillig 	const char *match;
   1521   1.703    rillig 
   1522   1.919    rillig 	wordLen = Substring_Length(word);
   1523   1.788    rillig 	if (args->pflags.subOnce && args->matched)
   1524   1.703    rillig 		goto nosub;
   1525   1.703    rillig 
   1526   1.918    rillig 	lhsLen = Substring_Length(args->lhs);
   1527   1.788    rillig 	if (args->pflags.anchorStart) {
   1528   1.918    rillig 		if (wordLen < lhsLen ||
   1529   1.919    rillig 		    memcmp(word.start, args->lhs.start, lhsLen) != 0)
   1530   1.703    rillig 			goto nosub;
   1531   1.703    rillig 
   1532   1.918    rillig 		if (args->pflags.anchorEnd && wordLen != lhsLen)
   1533   1.703    rillig 			goto nosub;
   1534   1.703    rillig 
   1535   1.703    rillig 		/* :S,^prefix,replacement, or :S,^whole$,replacement, */
   1536   1.919    rillig 		SepBuf_AddSubstring(buf, args->rhs);
   1537  1.1089    rillig 		SepBuf_AddRange(buf, word.start + lhsLen, word.end);
   1538   1.895    rillig 		args->matched = true;
   1539   1.703    rillig 		return;
   1540   1.703    rillig 	}
   1541     1.1       cgd 
   1542   1.788    rillig 	if (args->pflags.anchorEnd) {
   1543   1.918    rillig 		if (wordLen < lhsLen)
   1544   1.703    rillig 			goto nosub;
   1545  1.1089    rillig 		if (memcmp(word.end - lhsLen, args->lhs.start, lhsLen) != 0)
   1546   1.703    rillig 			goto nosub;
   1547   1.703    rillig 
   1548   1.703    rillig 		/* :S,suffix$,replacement, */
   1549  1.1089    rillig 		SepBuf_AddRange(buf, word.start, word.end - lhsLen);
   1550   1.919    rillig 		SepBuf_AddSubstring(buf, args->rhs);
   1551   1.895    rillig 		args->matched = true;
   1552   1.703    rillig 		return;
   1553   1.703    rillig 	}
   1554   1.315    rillig 
   1555   1.921    rillig 	if (Substring_IsEmpty(args->lhs))
   1556   1.703    rillig 		goto nosub;
   1557   1.279    rillig 
   1558   1.703    rillig 	/* unanchored case, may match more than once */
   1559   1.919    rillig 	while ((match = Substring_Find(word, args->lhs)) != NULL) {
   1560  1.1055    rillig 		SepBuf_AddRange(buf, word.start, match);
   1561   1.919    rillig 		SepBuf_AddSubstring(buf, args->rhs);
   1562   1.895    rillig 		args->matched = true;
   1563   1.921    rillig 		word.start = match + lhsLen;
   1564   1.919    rillig 		if (Substring_IsEmpty(word) || !args->pflags.subGlobal)
   1565   1.703    rillig 			break;
   1566   1.703    rillig 	}
   1567   1.242    rillig nosub:
   1568   1.919    rillig 	SepBuf_AddSubstring(buf, word);
   1569     1.1       cgd }
   1570     1.1       cgd 
   1571   1.400    rillig /* Print the error caused by a regcomp or regexec call. */
   1572    1.16  christos static void
   1573  1.1059    rillig RegexError(int reerr, const regex_t *pat, const char *str)
   1574    1.16  christos {
   1575   1.703    rillig 	size_t errlen = regerror(reerr, pat, NULL, 0);
   1576   1.703    rillig 	char *errbuf = bmake_malloc(errlen);
   1577   1.703    rillig 	regerror(reerr, pat, errbuf, errlen);
   1578  1.1125    rillig 	Parse_Error(PARSE_FATAL, "%s: %s", str, errbuf);
   1579   1.703    rillig 	free(errbuf);
   1580    1.16  christos }
   1581    1.16  christos 
   1582   1.981    rillig /* In the modifier ':C', replace a backreference from \0 to \9. */
   1583   1.981    rillig static void
   1584   1.981    rillig RegexReplaceBackref(char ref, SepBuf *buf, const char *wp,
   1585   1.981    rillig 		    const regmatch_t *m, size_t nsub)
   1586   1.981    rillig {
   1587  1.1160    rillig 	unsigned n = (unsigned)ref - '0';
   1588   1.981    rillig 
   1589   1.981    rillig 	if (n >= nsub)
   1590  1.1125    rillig 		Parse_Error(PARSE_FATAL, "No subexpression \\%u", n);
   1591   1.981    rillig 	else if (m[n].rm_so == -1) {
   1592   1.981    rillig 		if (opts.strict)
   1593   1.981    rillig 			Error("No match for subexpression \\%u", n);
   1594   1.981    rillig 	} else {
   1595  1.1055    rillig 		SepBuf_AddRange(buf,
   1596   1.981    rillig 		    wp + (size_t)m[n].rm_so,
   1597   1.981    rillig 		    wp + (size_t)m[n].rm_eo);
   1598   1.981    rillig 	}
   1599   1.981    rillig }
   1600   1.981    rillig 
   1601   1.937    rillig /*
   1602   1.983    rillig  * The regular expression matches the word; now add the replacement to the
   1603   1.983    rillig  * buffer, taking back-references from 'wp'.
   1604   1.937    rillig  */
   1605   1.937    rillig static void
   1606   1.984    rillig RegexReplace(Substring replace, SepBuf *buf, const char *wp,
   1607   1.937    rillig 	     const regmatch_t *m, size_t nsub)
   1608   1.937    rillig {
   1609   1.937    rillig 	const char *rp;
   1610   1.937    rillig 
   1611   1.984    rillig 	for (rp = replace.start; rp != replace.end; rp++) {
   1612   1.984    rillig 		if (*rp == '\\' && rp + 1 != replace.end &&
   1613   1.984    rillig 		    (rp[1] == '&' || rp[1] == '\\'))
   1614   1.983    rillig 			SepBuf_AddBytes(buf, ++rp, 1);
   1615   1.984    rillig 		else if (*rp == '\\' && rp + 1 != replace.end &&
   1616   1.984    rillig 			 ch_isdigit(rp[1]))
   1617   1.983    rillig 			RegexReplaceBackref(*++rp, buf, wp, m, nsub);
   1618   1.983    rillig 		else if (*rp == '&') {
   1619  1.1055    rillig 			SepBuf_AddRange(buf,
   1620   1.948    rillig 			    wp + (size_t)m[0].rm_so,
   1621   1.948    rillig 			    wp + (size_t)m[0].rm_eo);
   1622   1.983    rillig 		} else
   1623   1.937    rillig 			SepBuf_AddBytes(buf, rp, 1);
   1624   1.937    rillig 	}
   1625   1.937    rillig }
   1626   1.937    rillig 
   1627   1.541    rillig struct ModifyWord_SubstRegexArgs {
   1628   1.703    rillig 	regex_t re;
   1629   1.703    rillig 	size_t nsub;
   1630   1.984    rillig 	Substring replace;
   1631   1.927    rillig 	PatternFlags pflags;
   1632   1.895    rillig 	bool matched;
   1633   1.541    rillig };
   1634   1.291    rillig 
   1635   1.278    rillig static void
   1636   1.919    rillig ModifyWord_SubstRegex(Substring word, SepBuf *buf, void *data)
   1637    1.16  christos {
   1638   1.704    rillig 	struct ModifyWord_SubstRegexArgs *args = data;
   1639   1.704    rillig 	int xrv;
   1640   1.919    rillig 	const char *wp;
   1641   1.704    rillig 	int flags = 0;
   1642   1.704    rillig 	regmatch_t m[10];
   1643    1.16  christos 
   1644   1.919    rillig 	assert(word.end[0] == '\0');	/* assume null-terminated word */
   1645   1.919    rillig 	wp = word.start;
   1646   1.936    rillig 	if (args->pflags.subOnce && args->matched)
   1647   1.936    rillig 		goto no_match;
   1648   1.307    rillig 
   1649   1.935    rillig again:
   1650   1.704    rillig 	xrv = regexec(&args->re, wp, args->nsub, m, flags);
   1651   1.935    rillig 	if (xrv == 0)
   1652   1.935    rillig 		goto ok;
   1653   1.935    rillig 	if (xrv != REG_NOMATCH)
   1654  1.1059    rillig 		RegexError(xrv, &args->re, "Unexpected regex error");
   1655   1.936    rillig no_match:
   1656  1.1055    rillig 	SepBuf_AddRange(buf, wp, word.end);
   1657   1.936    rillig 	return;
   1658    1.16  christos 
   1659   1.935    rillig ok:
   1660   1.935    rillig 	args->matched = true;
   1661   1.935    rillig 	SepBuf_AddBytes(buf, wp, (size_t)m[0].rm_so);
   1662   1.704    rillig 
   1663   1.937    rillig 	RegexReplace(args->replace, buf, wp, m, args->nsub);
   1664   1.445    rillig 
   1665   1.948    rillig 	wp += (size_t)m[0].rm_eo;
   1666   1.935    rillig 	if (args->pflags.subGlobal) {
   1667   1.935    rillig 		flags |= REG_NOTBOL;
   1668  1.1077    rillig 		if (m[0].rm_so == 0 && m[0].rm_eo == 0 && *wp != '\0') {
   1669   1.935    rillig 			SepBuf_AddBytes(buf, wp, 1);
   1670   1.935    rillig 			wp++;
   1671   1.704    rillig 		}
   1672   1.704    rillig 		if (*wp != '\0')
   1673   1.935    rillig 			goto again;
   1674   1.935    rillig 	}
   1675   1.935    rillig 	if (*wp != '\0')
   1676   1.704    rillig 		SepBuf_AddStr(buf, wp);
   1677    1.16  christos }
   1678    1.16  christos 
   1679    1.16  christos 
   1680   1.541    rillig struct ModifyWord_LoopArgs {
   1681   1.806    rillig 	GNode *scope;
   1682   1.928    rillig 	const char *var;	/* name of the temporary variable */
   1683   1.928    rillig 	const char *body;	/* string to expand */
   1684   1.906    rillig 	VarEvalMode emode;
   1685   1.541    rillig };
   1686   1.291    rillig 
   1687   1.278    rillig static void
   1688   1.919    rillig ModifyWord_Loop(Substring word, SepBuf *buf, void *data)
   1689    1.40       sjg {
   1690   1.703    rillig 	const struct ModifyWord_LoopArgs *args;
   1691   1.703    rillig 	char *s;
   1692   1.412    rillig 
   1693   1.919    rillig 	if (Substring_IsEmpty(word))
   1694   1.703    rillig 		return;
   1695   1.278    rillig 
   1696   1.703    rillig 	args = data;
   1697   1.919    rillig 	assert(word.end[0] == '\0');	/* assume null-terminated word */
   1698   1.928    rillig 	Var_SetWithFlags(args->scope, args->var, word.start,
   1699   1.919    rillig 	    VAR_SET_NO_EXPORT);
   1700  1.1043    rillig 	s = Var_Subst(args->body, args->scope, args->emode);
   1701   1.703    rillig 	/* TODO: handle errors */
   1702    1.64       sjg 
   1703  1.1090    rillig 	DEBUG2(VAR, "ModifyWord_Loop: expand \"%s\" to \"%s\"\n",
   1704  1.1090    rillig 	    args->body, s);
   1705   1.703    rillig 
   1706   1.703    rillig 	if (s[0] == '\n' || Buf_EndsWith(&buf->buf, '\n'))
   1707   1.895    rillig 		buf->needSep = false;
   1708   1.703    rillig 	SepBuf_AddStr(buf, s);
   1709   1.703    rillig 	free(s);
   1710    1.40       sjg }
   1711    1.40       sjg 
   1712    1.81       sjg 
   1713   1.778    rillig /*
   1714   1.778    rillig  * The :[first..last] modifier selects words from the expression.
   1715   1.778    rillig  * It can also reverse the words.
   1716   1.778    rillig  */
   1717    1.81       sjg static char *
   1718   1.840    rillig VarSelectWords(const char *str, int first, int last,
   1719   1.895    rillig 	       char sep, bool oneBigWord)
   1720    1.81       sjg {
   1721   1.960    rillig 	SubstringWords words;
   1722   1.703    rillig 	int len, start, end, step;
   1723   1.703    rillig 	int i;
   1724   1.703    rillig 
   1725   1.703    rillig 	SepBuf buf;
   1726   1.703    rillig 	SepBuf_Init(&buf, sep);
   1727   1.703    rillig 
   1728   1.703    rillig 	if (oneBigWord) {
   1729   1.960    rillig 		/* fake what Substring_Words() would do */
   1730   1.703    rillig 		words.len = 1;
   1731   1.960    rillig 		words.words = bmake_malloc(sizeof(words.words[0]));
   1732   1.960    rillig 		words.freeIt = NULL;
   1733   1.960    rillig 		words.words[0] = Substring_InitStr(str); /* no need to copy */
   1734   1.703    rillig 	} else {
   1735   1.960    rillig 		words = Substring_Words(str, false);
   1736   1.703    rillig 	}
   1737    1.81       sjg 
   1738  1.1088    rillig 	/* Convert -1 to len, -2 to (len - 1), etc. */
   1739   1.703    rillig 	len = (int)words.len;
   1740   1.703    rillig 	if (first < 0)
   1741   1.703    rillig 		first += len + 1;
   1742   1.703    rillig 	if (last < 0)
   1743   1.703    rillig 		last += len + 1;
   1744   1.703    rillig 
   1745   1.703    rillig 	if (first > last) {
   1746   1.703    rillig 		start = (first > len ? len : first) - 1;
   1747   1.703    rillig 		end = last < 1 ? 0 : last - 1;
   1748   1.703    rillig 		step = -1;
   1749   1.703    rillig 	} else {
   1750   1.703    rillig 		start = first < 1 ? 0 : first - 1;
   1751   1.703    rillig 		end = last > len ? len : last;
   1752   1.703    rillig 		step = 1;
   1753   1.703    rillig 	}
   1754    1.81       sjg 
   1755   1.703    rillig 	for (i = start; (step < 0) == (i >= end); i += step) {
   1756   1.960    rillig 		SepBuf_AddSubstring(&buf, words.words[i]);
   1757   1.703    rillig 		SepBuf_Sep(&buf);
   1758   1.703    rillig 	}
   1759    1.81       sjg 
   1760   1.960    rillig 	SubstringWords_Free(words);
   1761    1.81       sjg 
   1762   1.784    rillig 	return SepBuf_DoneData(&buf);
   1763    1.81       sjg }
   1764    1.81       sjg 
   1765   1.156       sjg 
   1766   1.278    rillig static void
   1767   1.919    rillig ModifyWord_Realpath(Substring word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
   1768   1.156       sjg {
   1769   1.703    rillig 	struct stat st;
   1770   1.703    rillig 	char rbuf[MAXPATHLEN];
   1771   1.919    rillig 	const char *rp;
   1772   1.231    rillig 
   1773   1.919    rillig 	assert(word.end[0] == '\0');	/* assume null-terminated word */
   1774   1.919    rillig 	rp = cached_realpath(word.start, rbuf);
   1775   1.703    rillig 	if (rp != NULL && *rp == '/' && stat(rp, &st) == 0)
   1776   1.919    rillig 		SepBuf_AddStr(buf, rp);
   1777   1.919    rillig 	else
   1778   1.919    rillig 		SepBuf_AddSubstring(buf, word);
   1779   1.156       sjg }
   1780   1.156       sjg 
   1781    1.35  christos 
   1782   1.403    rillig static char *
   1783   1.962    rillig SubstringWords_JoinFree(SubstringWords words)
   1784   1.403    rillig {
   1785   1.703    rillig 	Buffer buf;
   1786   1.703    rillig 	size_t i;
   1787   1.412    rillig 
   1788   1.703    rillig 	Buf_Init(&buf);
   1789   1.403    rillig 
   1790   1.703    rillig 	for (i = 0; i < words.len; i++) {
   1791   1.703    rillig 		if (i != 0) {
   1792   1.988    rillig 			/*
   1793   1.988    rillig 			 * XXX: Use ch->sep instead of ' ', for consistency.
   1794   1.988    rillig 			 */
   1795   1.703    rillig 			Buf_AddByte(&buf, ' ');
   1796   1.703    rillig 		}
   1797  1.1055    rillig 		Buf_AddRange(&buf, words.words[i].start, words.words[i].end);
   1798   1.703    rillig 	}
   1799   1.403    rillig 
   1800   1.962    rillig 	SubstringWords_Free(words);
   1801   1.403    rillig 
   1802   1.784    rillig 	return Buf_DoneData(&buf);
   1803   1.403    rillig }
   1804   1.403    rillig 
   1805    1.55  christos 
   1806   1.778    rillig /*
   1807   1.778    rillig  * Quote shell meta-characters and space characters in the string.
   1808   1.778    rillig  * If quoteDollar is set, also quote and double any '$' characters.
   1809   1.778    rillig  */
   1810   1.924    rillig static void
   1811  1.1059    rillig QuoteShell(const char *str, bool quoteDollar, LazyBuf *buf)
   1812    1.16  christos {
   1813   1.924    rillig 	const char *p;
   1814   1.193  christos 
   1815   1.924    rillig 	LazyBuf_Init(buf, str);
   1816   1.924    rillig 	for (p = str; *p != '\0'; p++) {
   1817   1.924    rillig 		if (*p == '\n') {
   1818   1.703    rillig 			const char *newline = Shell_GetNewline();
   1819   1.703    rillig 			if (newline == NULL)
   1820   1.703    rillig 				newline = "\\\n";
   1821   1.924    rillig 			LazyBuf_AddStr(buf, newline);
   1822   1.703    rillig 			continue;
   1823   1.703    rillig 		}
   1824   1.997    rillig 		if (ch_isspace(*p) || ch_is_shell_meta(*p))
   1825   1.924    rillig 			LazyBuf_Add(buf, '\\');
   1826   1.924    rillig 		LazyBuf_Add(buf, *p);
   1827   1.924    rillig 		if (quoteDollar && *p == '$')
   1828   1.924    rillig 			LazyBuf_AddStr(buf, "\\$");
   1829   1.193  christos 	}
   1830    1.16  christos }
   1831    1.16  christos 
   1832   1.778    rillig /*
   1833   1.778    rillig  * Compute the 32-bit hash of the given string, using the MurmurHash3
   1834   1.778    rillig  * algorithm. Output is encoded as 8 hex digits, in Little Endian order.
   1835   1.778    rillig  */
   1836   1.163     joerg static char *
   1837  1.1059    rillig Hash(const char *str)
   1838   1.163     joerg {
   1839   1.703    rillig 	static const char hexdigits[16] = "0123456789abcdef";
   1840   1.703    rillig 	const unsigned char *ustr = (const unsigned char *)str;
   1841   1.703    rillig 
   1842   1.703    rillig 	uint32_t h = 0x971e137bU;
   1843   1.703    rillig 	uint32_t c1 = 0x95543787U;
   1844   1.703    rillig 	uint32_t c2 = 0x2ad7eb25U;
   1845   1.703    rillig 	size_t len2 = strlen(str);
   1846   1.163     joerg 
   1847   1.703    rillig 	char *buf;
   1848   1.703    rillig 	size_t i;
   1849   1.703    rillig 
   1850   1.703    rillig 	size_t len;
   1851   1.781    rillig 	for (len = len2; len != 0;) {
   1852   1.703    rillig 		uint32_t k = 0;
   1853   1.703    rillig 		switch (len) {
   1854   1.703    rillig 		default:
   1855   1.703    rillig 			k = ((uint32_t)ustr[3] << 24) |
   1856   1.703    rillig 			    ((uint32_t)ustr[2] << 16) |
   1857   1.703    rillig 			    ((uint32_t)ustr[1] << 8) |
   1858   1.703    rillig 			    (uint32_t)ustr[0];
   1859   1.703    rillig 			len -= 4;
   1860   1.703    rillig 			ustr += 4;
   1861   1.703    rillig 			break;
   1862   1.703    rillig 		case 3:
   1863   1.703    rillig 			k |= (uint32_t)ustr[2] << 16;
   1864   1.703    rillig 			/* FALLTHROUGH */
   1865   1.703    rillig 		case 2:
   1866   1.703    rillig 			k |= (uint32_t)ustr[1] << 8;
   1867   1.703    rillig 			/* FALLTHROUGH */
   1868   1.703    rillig 		case 1:
   1869   1.703    rillig 			k |= (uint32_t)ustr[0];
   1870   1.703    rillig 			len = 0;
   1871   1.703    rillig 		}
   1872   1.703    rillig 		c1 = c1 * 5 + 0x7b7d159cU;
   1873   1.703    rillig 		c2 = c2 * 5 + 0x6bce6396U;
   1874   1.703    rillig 		k *= c1;
   1875   1.703    rillig 		k = (k << 11) ^ (k >> 21);
   1876   1.703    rillig 		k *= c2;
   1877   1.703    rillig 		h = (h << 13) ^ (h >> 19);
   1878   1.703    rillig 		h = h * 5 + 0x52dce729U;
   1879   1.703    rillig 		h ^= k;
   1880   1.703    rillig 	}
   1881   1.703    rillig 	h ^= (uint32_t)len2;
   1882   1.703    rillig 	h *= 0x85ebca6b;
   1883   1.703    rillig 	h ^= h >> 13;
   1884   1.703    rillig 	h *= 0xc2b2ae35;
   1885   1.703    rillig 	h ^= h >> 16;
   1886   1.703    rillig 
   1887   1.703    rillig 	buf = bmake_malloc(9);
   1888   1.703    rillig 	for (i = 0; i < 8; i++) {
   1889   1.703    rillig 		buf[i] = hexdigits[h & 0x0f];
   1890   1.703    rillig 		h >>= 4;
   1891   1.703    rillig 	}
   1892   1.703    rillig 	buf[8] = '\0';
   1893   1.703    rillig 	return buf;
   1894   1.163     joerg }
   1895   1.163     joerg 
   1896   1.164       sjg static char *
   1897  1.1059    rillig FormatTime(const char *fmt, time_t t, bool gmt)
   1898   1.164       sjg {
   1899   1.703    rillig 	char buf[BUFSIZ];
   1900   1.164       sjg 
   1901   1.993    rillig 	if (t == 0)
   1902   1.993    rillig 		time(&t);
   1903   1.703    rillig 	if (*fmt == '\0')
   1904   1.703    rillig 		fmt = "%c";
   1905  1.1064    rillig 	if (gmt && strchr(fmt, 's') != NULL) {
   1906  1.1064    rillig 		/* strftime "%s" only works with localtime, not with gmtime. */
   1907  1.1062    rillig 		const char *prev_tz_env = getenv("TZ");
   1908  1.1062    rillig 		char *prev_tz = prev_tz_env != NULL
   1909  1.1062    rillig 		    ? bmake_strdup(prev_tz_env) : NULL;
   1910  1.1062    rillig 		setenv("TZ", "UTC", 1);
   1911  1.1062    rillig 		strftime(buf, sizeof buf, fmt, localtime(&t));
   1912  1.1062    rillig 		if (prev_tz != NULL) {
   1913  1.1062    rillig 			setenv("TZ", prev_tz, 1);
   1914  1.1062    rillig 			free(prev_tz);
   1915  1.1062    rillig 		} else
   1916  1.1062    rillig 			unsetenv("TZ");
   1917  1.1062    rillig 	} else
   1918  1.1064    rillig 		strftime(buf, sizeof buf, fmt, (gmt ? gmtime : localtime)(&t));
   1919   1.235    rillig 
   1920   1.703    rillig 	buf[sizeof buf - 1] = '\0';
   1921   1.703    rillig 	return bmake_strdup(buf);
   1922   1.164       sjg }
   1923   1.164       sjg 
   1924   1.687    rillig /*
   1925   1.687    rillig  * The ApplyModifier functions take an expression that is being evaluated.
   1926   1.830    rillig  * Their task is to apply a single modifier to the expression.  This involves
   1927   1.830    rillig  * parsing the modifier, evaluating it and finally updating the value of the
   1928   1.830    rillig  * expression.
   1929   1.467    rillig  *
   1930   1.467    rillig  * Parsing the modifier
   1931   1.467    rillig  *
   1932   1.467    rillig  * If parsing succeeds, the parsing position *pp is updated to point to the
   1933   1.467    rillig  * first character following the modifier, which typically is either ':' or
   1934   1.891    rillig  * ch->endc.  The modifier doesn't have to check for this delimiter character,
   1935   1.687    rillig  * this is done by ApplyModifiers.
   1936   1.687    rillig  *
   1937   1.687    rillig  * XXX: As of 2020-11-15, some modifiers such as :S, :C, :P, :L do not
   1938   1.687    rillig  * need to be followed by a ':' or endc; this was an unintended mistake.
   1939   1.467    rillig  *
   1940  1.1079    rillig  * If parsing fails because of a missing delimiter after a modifier part (as
   1941  1.1079    rillig  * in the :S, :C or :@ modifiers), return AMR_CLEANUP.
   1942   1.467    rillig  *
   1943   1.467    rillig  * If parsing fails because the modifier is unknown, return AMR_UNKNOWN to
   1944  1.1088    rillig  * try the SysV modifier ':from=to' as fallback.  This should only be
   1945   1.467    rillig  * done as long as there have been no side effects from evaluating nested
   1946   1.467    rillig  * variables, to avoid evaluating them more than once.  In this case, the
   1947   1.687    rillig  * parsing position may or may not be updated.  (XXX: Why not? The original
   1948   1.687    rillig  * parsing position is well-known in ApplyModifiers.)
   1949   1.467    rillig  *
   1950   1.467    rillig  * If parsing fails and the SysV modifier ${VAR:from=to} should not be used
   1951  1.1066    rillig  * as a fallback, issue an error message using Parse_Error (preferred over
   1952  1.1088    rillig  * Error) and then return AMR_CLEANUP, which stops processing the expression.
   1953  1.1088    rillig  * (XXX: As of 2020-08-23, evaluation of the string continues nevertheless
   1954  1.1088    rillig  * after skipping a few bytes, which results in garbage.)
   1955   1.467    rillig  *
   1956   1.467    rillig  * Evaluating the modifier
   1957   1.467    rillig  *
   1958   1.467    rillig  * After parsing, the modifier is evaluated.  The side effects from evaluating
   1959  1.1075    rillig  * nested expressions in the modifier text often already happen
   1960   1.830    rillig  * during parsing though.  For most modifiers this doesn't matter since their
   1961   1.949    rillig  * only noticeable effect is that they update the value of the expression.
   1962   1.830    rillig  * Some modifiers such as ':sh' or '::=' have noticeable side effects though.
   1963   1.467    rillig  *
   1964  1.1075    rillig  * Evaluating the modifier usually takes the current value of the
   1965  1.1094    rillig  * expression from ch->expr->value, or the variable name from ch->var->name,
   1966  1.1066    rillig  * and stores the result back in ch->expr->value via Expr_SetValueOwn or
   1967   1.821    rillig  * Expr_SetValueRefer.
   1968   1.467    rillig  *
   1969   1.528    rillig  * Some modifiers such as :D and :U turn undefined expressions into defined
   1970  1.1066    rillig  * expressions using Expr_Define.
   1971   1.350    rillig  */
   1972   1.409    rillig 
   1973   1.825    rillig typedef enum ExprDefined {
   1974  1.1075    rillig 	/* The expression is based on a regular, defined variable. */
   1975   1.825    rillig 	DEF_REGULAR,
   1976  1.1075    rillig 	/* The expression is based on an undefined variable. */
   1977   1.825    rillig 	DEF_UNDEF,
   1978   1.703    rillig 	/*
   1979  1.1075    rillig 	 * The expression started as an undefined expression, but one
   1980   1.825    rillig 	 * of the modifiers (such as ':D' or ':U') has turned the expression
   1981   1.825    rillig 	 * from undefined to defined.
   1982   1.703    rillig 	 */
   1983   1.825    rillig 	DEF_DEFINED
   1984   1.825    rillig } ExprDefined;
   1985   1.527    rillig 
   1986   1.951    rillig static const char ExprDefined_Name[][10] = {
   1987   1.826    rillig 	"regular",
   1988   1.826    rillig 	"undefined",
   1989   1.826    rillig 	"defined"
   1990   1.789    rillig };
   1991   1.527    rillig 
   1992   1.897    rillig #if __STDC_VERSION__ >= 199901L
   1993   1.989    rillig #define const_member		const
   1994   1.897    rillig #else
   1995   1.989    rillig #define const_member		/* no const possible */
   1996   1.897    rillig #endif
   1997   1.897    rillig 
   1998   1.966    rillig /* An expression based on a variable, such as $@ or ${VAR:Mpattern:Q}. */
   1999   1.823    rillig typedef struct Expr {
   2000   1.898    rillig 	const char *name;
   2001   1.823    rillig 	FStr value;
   2002   1.906    rillig 	VarEvalMode const_member emode;
   2003   1.897    rillig 	GNode *const_member scope;
   2004   1.825    rillig 	ExprDefined defined;
   2005   1.823    rillig } Expr;
   2006   1.823    rillig 
   2007   1.823    rillig /*
   2008   1.890    rillig  * The status of applying a chain of modifiers to an expression.
   2009   1.823    rillig  *
   2010   1.890    rillig  * The modifiers of an expression are broken into chains of modifiers,
   2011   1.892    rillig  * starting a new nested chain whenever an indirect modifier starts.  There
   2012   1.892    rillig  * are at most 2 nesting levels: the outer one for the direct modifiers, and
   2013   1.892    rillig  * the inner one for the indirect modifiers.
   2014   1.890    rillig  *
   2015   1.892    rillig  * For example, the expression ${VAR:M*:${IND1}:${IND2}:O:u} has 3 chains of
   2016   1.889    rillig  * modifiers:
   2017   1.889    rillig  *
   2018   1.892    rillig  *	Chain 1 starts with the single modifier ':M*'.
   2019   1.892    rillig  *	  Chain 2 starts with all modifiers from ${IND1}.
   2020   1.892    rillig  *	  Chain 2 ends at the ':' between ${IND1} and ${IND2}.
   2021   1.893    rillig  *	  Chain 3 starts with all modifiers from ${IND2}.
   2022   1.893    rillig  *	  Chain 3 ends at the ':' after ${IND2}.
   2023   1.942    rillig  *	Chain 1 continues with the 2 modifiers ':O' and ':u'.
   2024   1.892    rillig  *	Chain 1 ends at the final '}' of the expression.
   2025   1.890    rillig  *
   2026   1.892    rillig  * After such a chain ends, its properties no longer have any effect.
   2027   1.889    rillig  *
   2028   1.823    rillig  * See varmod-indirect.mk.
   2029   1.823    rillig  */
   2030   1.891    rillig typedef struct ModChain {
   2031   1.823    rillig 	Expr *expr;
   2032   1.703    rillig 	/* '\0' or '{' or '(' */
   2033   1.897    rillig 	char const_member startc;
   2034   1.703    rillig 	/* '\0' or '}' or ')' */
   2035   1.897    rillig 	char const_member endc;
   2036  1.1094    rillig 	/* Separator when joining words (see the :ts modifier). */
   2037   1.703    rillig 	char sep;
   2038   1.703    rillig 	/*
   2039  1.1066    rillig 	 * Whether some modifiers that otherwise split the variable value
   2040   1.703    rillig 	 * into words, like :S and :C, treat the variable value as a single
   2041   1.703    rillig 	 * big word, possibly containing spaces.
   2042   1.703    rillig 	 */
   2043   1.895    rillig 	bool oneBigWord;
   2044   1.891    rillig } ModChain;
   2045   1.236    rillig 
   2046   1.525    rillig static void
   2047   1.812    rillig Expr_Define(Expr *expr)
   2048   1.525    rillig {
   2049   1.825    rillig 	if (expr->defined == DEF_UNDEF)
   2050   1.825    rillig 		expr->defined = DEF_DEFINED;
   2051   1.525    rillig }
   2052   1.525    rillig 
   2053   1.965    rillig static const char *
   2054   1.965    rillig Expr_Str(const Expr *expr)
   2055   1.965    rillig {
   2056   1.965    rillig 	return expr->value.str;
   2057   1.965    rillig }
   2058   1.965    rillig 
   2059   1.967    rillig static SubstringWords
   2060   1.967    rillig Expr_Words(const Expr *expr)
   2061   1.967    rillig {
   2062   1.967    rillig 	return Substring_Words(Expr_Str(expr), false);
   2063   1.967    rillig }
   2064   1.967    rillig 
   2065   1.813    rillig static void
   2066   1.921    rillig Expr_SetValue(Expr *expr, FStr value)
   2067   1.921    rillig {
   2068   1.921    rillig 	FStr_Done(&expr->value);
   2069   1.921    rillig 	expr->value = value;
   2070   1.921    rillig }
   2071   1.921    rillig 
   2072   1.921    rillig static void
   2073   1.813    rillig Expr_SetValueOwn(Expr *expr, char *value)
   2074   1.813    rillig {
   2075   1.921    rillig 	Expr_SetValue(expr, FStr_InitOwn(value));
   2076   1.813    rillig }
   2077   1.813    rillig 
   2078   1.813    rillig static void
   2079   1.813    rillig Expr_SetValueRefer(Expr *expr, const char *value)
   2080   1.813    rillig {
   2081   1.921    rillig 	Expr_SetValue(expr, FStr_InitRefer(value));
   2082   1.813    rillig }
   2083   1.813    rillig 
   2084   1.905    rillig static bool
   2085   1.905    rillig Expr_ShouldEval(const Expr *expr)
   2086   1.905    rillig {
   2087   1.906    rillig 	return VarEvalMode_ShouldEval(expr->emode);
   2088   1.905    rillig }
   2089   1.905    rillig 
   2090   1.905    rillig static bool
   2091   1.905    rillig ModChain_ShouldEval(const ModChain *ch)
   2092   1.905    rillig {
   2093   1.905    rillig 	return Expr_ShouldEval(ch->expr);
   2094   1.905    rillig }
   2095   1.905    rillig 
   2096   1.905    rillig 
   2097   1.578    rillig typedef enum ApplyModifierResult {
   2098   1.703    rillig 	/* Continue parsing */
   2099   1.703    rillig 	AMR_OK,
   2100  1.1093    rillig 	/* Not a match, try the ':from=to' modifier as well. */
   2101   1.703    rillig 	AMR_UNKNOWN,
   2102  1.1155    rillig 	/* Error out without further error message. */
   2103   1.703    rillig 	AMR_CLEANUP
   2104   1.356    rillig } ApplyModifierResult;
   2105   1.356    rillig 
   2106   1.703    rillig /*
   2107   1.703    rillig  * Allow backslashes to escape the delimiter, $, and \, but don't touch other
   2108   1.703    rillig  * backslashes.
   2109   1.703    rillig  */
   2110   1.895    rillig static bool
   2111   1.620    rillig IsEscapedModifierPart(const char *p, char delim,
   2112   1.620    rillig 		      struct ModifyWord_SubstArgs *subst)
   2113   1.620    rillig {
   2114  1.1118    rillig 	if (p[0] != '\\' || p[1] == '\0')
   2115   1.895    rillig 		return false;
   2116   1.703    rillig 	if (p[1] == delim || p[1] == '\\' || p[1] == '$')
   2117   1.895    rillig 		return true;
   2118   1.703    rillig 	return p[1] == '&' && subst != NULL;
   2119   1.620    rillig }
   2120   1.620    rillig 
   2121   1.956    rillig /*
   2122   1.957    rillig  * In a part of a modifier, parse a subexpression and evaluate it.
   2123   1.957    rillig  */
   2124   1.957    rillig static void
   2125   1.957    rillig ParseModifierPartExpr(const char **pp, LazyBuf *part, const ModChain *ch,
   2126   1.957    rillig 		      VarEvalMode emode)
   2127   1.957    rillig {
   2128   1.957    rillig 	const char *p = *pp;
   2129  1.1042    rillig 	FStr nested_val = Var_Parse(&p, ch->expr->scope,
   2130  1.1042    rillig 	    VarEvalMode_WithoutKeepDollar(emode));
   2131   1.957    rillig 	/* TODO: handle errors */
   2132  1.1047    rillig 	if (VarEvalMode_ShouldEval(emode))
   2133  1.1047    rillig 		LazyBuf_AddStr(part, nested_val.str);
   2134  1.1047    rillig 	else
   2135  1.1047    rillig 		LazyBuf_AddSubstring(part, Substring_Init(*pp, p));
   2136   1.957    rillig 	FStr_Done(&nested_val);
   2137   1.957    rillig 	*pp = p;
   2138   1.957    rillig }
   2139   1.957    rillig 
   2140  1.1029    rillig /*
   2141  1.1047    rillig  * In a part of a modifier, parse some text that looks like a subexpression.
   2142  1.1047    rillig  * If the text starts with '$(', any '(' and ')' must be balanced.
   2143  1.1047    rillig  * If the text starts with '${', any '{' and '}' must be balanced.
   2144  1.1066    rillig  * If the text starts with '$', that '$' is copied verbatim, it is not parsed
   2145  1.1075    rillig  * as a short-name expression.
   2146  1.1029    rillig  */
   2147   1.956    rillig static void
   2148  1.1047    rillig ParseModifierPartBalanced(const char **pp, LazyBuf *part)
   2149   1.956    rillig {
   2150   1.956    rillig 	const char *p = *pp;
   2151   1.956    rillig 
   2152   1.956    rillig 	if (p[1] == '(' || p[1] == '{') {
   2153  1.1029    rillig 		char startc = p[1];
   2154  1.1029    rillig 		int endc = startc == '(' ? ')' : '}';
   2155  1.1029    rillig 		int depth = 1;
   2156  1.1029    rillig 
   2157  1.1029    rillig 		for (p += 2; *p != '\0' && depth > 0; p++) {
   2158  1.1029    rillig 			if (p[-1] != '\\') {
   2159  1.1029    rillig 				if (*p == startc)
   2160  1.1029    rillig 					depth++;
   2161  1.1029    rillig 				if (*p == endc)
   2162  1.1029    rillig 					depth--;
   2163  1.1029    rillig 			}
   2164  1.1029    rillig 		}
   2165  1.1089    rillig 		LazyBuf_AddSubstring(part, Substring_Init(*pp, p));
   2166  1.1029    rillig 		*pp = p;
   2167   1.956    rillig 	} else {
   2168  1.1089    rillig 		LazyBuf_Add(part, *p);
   2169  1.1029    rillig 		*pp = p + 1;
   2170   1.956    rillig 	}
   2171   1.956    rillig }
   2172   1.956    rillig 
   2173  1.1115    rillig /*
   2174  1.1115    rillig  * Parse a part of a modifier such as the "from" and "to" in :S/from/to/ or
   2175  1.1115    rillig  * the "var" or "replacement ${var}" in :@var@replacement ${var}@, up to and
   2176  1.1115    rillig  * including the next unescaped delimiter.  The delimiter, as well as the
   2177  1.1115    rillig  * backslash or the dollar, can be escaped with a backslash.
   2178  1.1115    rillig  *
   2179  1.1115    rillig  * Return true if parsing succeeded, together with the parsed (and possibly
   2180  1.1115    rillig  * expanded) part.  In that case, pp points right after the delimiter.  The
   2181  1.1115    rillig  * delimiter is not included in the part though.
   2182  1.1115    rillig  */
   2183  1.1044    rillig static bool
   2184  1.1115    rillig ParseModifierPart(
   2185  1.1115    rillig     /* The parsing position, updated upon return */
   2186   1.703    rillig     const char **pp,
   2187  1.1115    rillig     char end1,
   2188  1.1115    rillig     char end2,
   2189  1.1115    rillig     /* Mode for evaluating nested expressions. */
   2190   1.906    rillig     VarEvalMode emode,
   2191   1.891    rillig     ModChain *ch,
   2192   1.921    rillig     LazyBuf *part,
   2193   1.988    rillig     /*
   2194  1.1066    rillig      * For the first part of the ':S' modifier, set anchorEnd if the last
   2195   1.988    rillig      * character of the pattern is a $.
   2196   1.988    rillig      */
   2197   1.927    rillig     PatternFlags *out_pflags,
   2198   1.988    rillig     /*
   2199  1.1066    rillig      * For the second part of the ':S' modifier, allow ampersands to be
   2200  1.1066    rillig      * escaped and replace unescaped ampersands with subst->lhs.
   2201   1.988    rillig      */
   2202   1.541    rillig     struct ModifyWord_SubstArgs *subst
   2203   1.704    rillig )
   2204   1.704    rillig {
   2205  1.1115    rillig 	const char *p = *pp;
   2206   1.704    rillig 
   2207   1.923    rillig 	LazyBuf_Init(part, p);
   2208  1.1050    rillig 	while (*p != '\0' && *p != end1 && *p != end2) {
   2209  1.1115    rillig 		if (IsEscapedModifierPart(p, end2, subst)) {
   2210   1.921    rillig 			LazyBuf_Add(part, p[1]);
   2211   1.704    rillig 			p += 2;
   2212   1.958    rillig 		} else if (*p != '$') {	/* Unescaped, simple text */
   2213   1.704    rillig 			if (subst != NULL && *p == '&')
   2214   1.921    rillig 				LazyBuf_AddSubstring(part, subst->lhs);
   2215   1.704    rillig 			else
   2216   1.921    rillig 				LazyBuf_Add(part, *p);
   2217   1.704    rillig 			p++;
   2218  1.1115    rillig 		} else if (p[1] == end2) {	/* Unescaped '$' at end */
   2219   1.704    rillig 			if (out_pflags != NULL)
   2220   1.895    rillig 				out_pflags->anchorEnd = true;
   2221   1.704    rillig 			else
   2222   1.921    rillig 				LazyBuf_Add(part, *p);
   2223   1.704    rillig 			p++;
   2224  1.1047    rillig 		} else if (emode == VARE_PARSE_BALANCED)
   2225  1.1047    rillig 			ParseModifierPartBalanced(&p, part);
   2226  1.1047    rillig 		else
   2227   1.957    rillig 			ParseModifierPartExpr(&p, part, ch, emode);
   2228   1.529    rillig 	}
   2229   1.529    rillig 
   2230  1.1050    rillig 	if (*p != end1 && *p != end2) {
   2231  1.1125    rillig 		Parse_Error(PARSE_FATAL,
   2232  1.1148    rillig 		    "Unfinished modifier after \"%.*s\", expecting \"%c\"",
   2233  1.1148    rillig 		    (int)(p - *pp), *pp, end2);
   2234   1.921    rillig 		LazyBuf_Done(part);
   2235  1.1148    rillig 		*pp = p;
   2236  1.1044    rillig 		return false;
   2237   1.704    rillig 	}
   2238  1.1148    rillig 	*pp = p;
   2239  1.1115    rillig 	if (end1 == end2)
   2240  1.1050    rillig 		(*pp)++;
   2241   1.529    rillig 
   2242   1.921    rillig 	{
   2243   1.921    rillig 		Substring sub = LazyBuf_Get(part);
   2244   1.921    rillig 		DEBUG2(VAR, "Modifier part: \"%.*s\"\n",
   2245   1.921    rillig 		    (int)Substring_Length(sub), sub.start);
   2246   1.921    rillig 	}
   2247   1.921    rillig 
   2248  1.1044    rillig 	return true;
   2249   1.529    rillig }
   2250   1.529    rillig 
   2251   1.895    rillig MAKE_INLINE bool
   2252   1.891    rillig IsDelimiter(char c, const ModChain *ch)
   2253   1.859    rillig {
   2254  1.1032    rillig 	return c == ':' || c == ch->endc || c == '\0';
   2255   1.859    rillig }
   2256   1.859    rillig 
   2257   1.400    rillig /* Test whether mod starts with modname, followed by a delimiter. */
   2258   1.895    rillig MAKE_INLINE bool
   2259   1.891    rillig ModMatch(const char *mod, const char *modname, const ModChain *ch)
   2260   1.340    rillig {
   2261   1.703    rillig 	size_t n = strlen(modname);
   2262   1.891    rillig 	return strncmp(mod, modname, n) == 0 && IsDelimiter(mod[n], ch);
   2263   1.340    rillig }
   2264   1.340    rillig 
   2265   1.400    rillig /* Test whether mod starts with modname, followed by a delimiter or '='. */
   2266   1.895    rillig MAKE_INLINE bool
   2267   1.891    rillig ModMatchEq(const char *mod, const char *modname, const ModChain *ch)
   2268   1.340    rillig {
   2269   1.703    rillig 	size_t n = strlen(modname);
   2270   1.703    rillig 	return strncmp(mod, modname, n) == 0 &&
   2271   1.891    rillig 	       (IsDelimiter(mod[n], ch) || mod[n] == '=');
   2272   1.340    rillig }
   2273   1.236    rillig 
   2274   1.895    rillig static bool
   2275   1.635    rillig TryParseIntBase0(const char **pp, int *out_num)
   2276   1.635    rillig {
   2277   1.703    rillig 	char *end;
   2278   1.703    rillig 	long n;
   2279   1.635    rillig 
   2280   1.703    rillig 	errno = 0;
   2281   1.703    rillig 	n = strtol(*pp, &end, 0);
   2282   1.865    rillig 
   2283   1.865    rillig 	if (end == *pp)
   2284   1.895    rillig 		return false;
   2285   1.703    rillig 	if ((n == LONG_MIN || n == LONG_MAX) && errno == ERANGE)
   2286   1.895    rillig 		return false;
   2287   1.703    rillig 	if (n < INT_MIN || n > INT_MAX)
   2288   1.895    rillig 		return false;
   2289   1.635    rillig 
   2290   1.703    rillig 	*pp = end;
   2291   1.703    rillig 	*out_num = (int)n;
   2292   1.895    rillig 	return true;
   2293   1.635    rillig }
   2294   1.635    rillig 
   2295   1.895    rillig static bool
   2296   1.635    rillig TryParseSize(const char **pp, size_t *out_num)
   2297   1.635    rillig {
   2298   1.703    rillig 	char *end;
   2299   1.703    rillig 	unsigned long n;
   2300   1.635    rillig 
   2301   1.703    rillig 	if (!ch_isdigit(**pp))
   2302   1.895    rillig 		return false;
   2303   1.635    rillig 
   2304   1.703    rillig 	errno = 0;
   2305   1.703    rillig 	n = strtoul(*pp, &end, 10);
   2306   1.703    rillig 	if (n == ULONG_MAX && errno == ERANGE)
   2307   1.895    rillig 		return false;
   2308   1.703    rillig 	if (n > SIZE_MAX)
   2309   1.895    rillig 		return false;
   2310   1.635    rillig 
   2311   1.703    rillig 	*pp = end;
   2312   1.703    rillig 	*out_num = (size_t)n;
   2313   1.895    rillig 	return true;
   2314   1.635    rillig }
   2315   1.635    rillig 
   2316   1.895    rillig static bool
   2317   1.635    rillig TryParseChar(const char **pp, int base, char *out_ch)
   2318   1.635    rillig {
   2319   1.703    rillig 	char *end;
   2320   1.703    rillig 	unsigned long n;
   2321   1.635    rillig 
   2322   1.703    rillig 	if (!ch_isalnum(**pp))
   2323   1.895    rillig 		return false;
   2324   1.635    rillig 
   2325   1.703    rillig 	errno = 0;
   2326   1.703    rillig 	n = strtoul(*pp, &end, base);
   2327   1.703    rillig 	if (n == ULONG_MAX && errno == ERANGE)
   2328   1.895    rillig 		return false;
   2329   1.703    rillig 	if (n > UCHAR_MAX)
   2330   1.895    rillig 		return false;
   2331   1.635    rillig 
   2332   1.703    rillig 	*pp = end;
   2333   1.703    rillig 	*out_ch = (char)n;
   2334   1.895    rillig 	return true;
   2335   1.635    rillig }
   2336   1.635    rillig 
   2337   1.820    rillig /*
   2338   1.822    rillig  * Modify each word of the expression using the given function and place the
   2339   1.822    rillig  * result back in the expression.
   2340   1.820    rillig  */
   2341   1.820    rillig static void
   2342   1.891    rillig ModifyWords(ModChain *ch,
   2343   1.822    rillig 	    ModifyWordProc modifyWord, void *modifyWord_args,
   2344   1.895    rillig 	    bool oneBigWord)
   2345   1.820    rillig {
   2346   1.891    rillig 	Expr *expr = ch->expr;
   2347   1.965    rillig 	const char *val = Expr_Str(expr);
   2348   1.820    rillig 	SepBuf result;
   2349   1.920    rillig 	SubstringWords words;
   2350   1.820    rillig 	size_t i;
   2351   1.919    rillig 	Substring word;
   2352   1.820    rillig 
   2353  1.1097    rillig 	if (!ModChain_ShouldEval(ch))
   2354  1.1097    rillig 		return;
   2355  1.1097    rillig 
   2356   1.820    rillig 	if (oneBigWord) {
   2357   1.891    rillig 		SepBuf_Init(&result, ch->sep);
   2358   1.919    rillig 		/* XXX: performance: Substring_InitStr calls strlen */
   2359   1.919    rillig 		word = Substring_InitStr(val);
   2360   1.919    rillig 		modifyWord(word, &result, modifyWord_args);
   2361   1.820    rillig 		goto done;
   2362   1.820    rillig 	}
   2363   1.820    rillig 
   2364   1.920    rillig 	words = Substring_Words(val, false);
   2365   1.820    rillig 
   2366   1.954    rillig 	DEBUG3(VAR, "ModifyWords: split \"%s\" into %u %s\n",
   2367   1.954    rillig 	    val, (unsigned)words.len, words.len != 1 ? "words" : "word");
   2368   1.820    rillig 
   2369   1.891    rillig 	SepBuf_Init(&result, ch->sep);
   2370   1.820    rillig 	for (i = 0; i < words.len; i++) {
   2371   1.920    rillig 		modifyWord(words.words[i], &result, modifyWord_args);
   2372   1.820    rillig 		if (result.buf.len > 0)
   2373   1.820    rillig 			SepBuf_Sep(&result);
   2374   1.820    rillig 	}
   2375   1.820    rillig 
   2376   1.920    rillig 	SubstringWords_Free(words);
   2377   1.820    rillig 
   2378   1.820    rillig done:
   2379   1.823    rillig 	Expr_SetValueOwn(expr, SepBuf_DoneData(&result));
   2380   1.820    rillig }
   2381   1.820    rillig 
   2382   1.236    rillig /* :@var (at) ...${var}...@ */
   2383   1.356    rillig static ApplyModifierResult
   2384   1.891    rillig ApplyModifier_Loop(const char **pp, ModChain *ch)
   2385   1.417    rillig {
   2386   1.891    rillig 	Expr *expr = ch->expr;
   2387   1.703    rillig 	struct ModifyWord_LoopArgs args;
   2388   1.703    rillig 	char prev_sep;
   2389   1.921    rillig 	LazyBuf tvarBuf, strBuf;
   2390   1.921    rillig 	FStr tvar, str;
   2391   1.703    rillig 
   2392   1.823    rillig 	args.scope = expr->scope;
   2393   1.703    rillig 
   2394   1.703    rillig 	(*pp)++;		/* Skip the first '@' */
   2395  1.1119    rillig 	if (!ParseModifierPart(pp, '@', '@', VARE_PARSE,
   2396  1.1115    rillig 	    ch, &tvarBuf, NULL, NULL))
   2397   1.703    rillig 		return AMR_CLEANUP;
   2398   1.921    rillig 	tvar = LazyBuf_DoneGet(&tvarBuf);
   2399   1.928    rillig 	args.var = tvar.str;
   2400   1.928    rillig 	if (strchr(args.var, '$') != NULL) {
   2401   1.703    rillig 		Parse_Error(PARSE_FATAL,
   2402  1.1102    rillig 		    "In the :@ modifier, the variable name \"%s\" "
   2403   1.969    rillig 		    "must not contain a dollar",
   2404  1.1102    rillig 		    args.var);
   2405  1.1112    rillig 		goto cleanup_tvar;
   2406   1.703    rillig 	}
   2407   1.236    rillig 
   2408  1.1115    rillig 	if (!ParseModifierPart(pp, '@', '@', VARE_PARSE_BALANCED,
   2409  1.1115    rillig 	    ch, &strBuf, NULL, NULL))
   2410  1.1112    rillig 		goto cleanup_tvar;
   2411   1.921    rillig 	str = LazyBuf_DoneGet(&strBuf);
   2412   1.928    rillig 	args.body = str.str;
   2413   1.703    rillig 
   2414   1.906    rillig 	if (!Expr_ShouldEval(expr))
   2415   1.870    rillig 		goto done;
   2416   1.870    rillig 
   2417   1.906    rillig 	args.emode = VarEvalMode_WithoutKeepDollar(expr->emode);
   2418   1.891    rillig 	prev_sep = ch->sep;
   2419   1.891    rillig 	ch->sep = ' ';		/* XXX: should be ch->sep for consistency */
   2420   1.891    rillig 	ModifyWords(ch, ModifyWord_Loop, &args, ch->oneBigWord);
   2421   1.891    rillig 	ch->sep = prev_sep;
   2422   1.928    rillig 	/* XXX: Consider restoring the previous value instead of deleting. */
   2423   1.928    rillig 	Var_Delete(expr->scope, args.var);
   2424   1.870    rillig 
   2425   1.870    rillig done:
   2426   1.921    rillig 	FStr_Done(&tvar);
   2427   1.921    rillig 	FStr_Done(&str);
   2428   1.703    rillig 	return AMR_OK;
   2429  1.1112    rillig 
   2430  1.1112    rillig cleanup_tvar:
   2431  1.1112    rillig 	FStr_Done(&tvar);
   2432  1.1112    rillig 	return AMR_CLEANUP;
   2433   1.236    rillig }
   2434   1.236    rillig 
   2435  1.1026    rillig static void
   2436  1.1027    rillig ParseModifier_Defined(const char **pp, ModChain *ch, bool shouldEval,
   2437  1.1026    rillig 		      LazyBuf *buf)
   2438   1.236    rillig {
   2439   1.703    rillig 	const char *p;
   2440   1.412    rillig 
   2441   1.703    rillig 	p = *pp + 1;
   2442  1.1026    rillig 	LazyBuf_Init(buf, p);
   2443  1.1032    rillig 	while (!IsDelimiter(*p, ch)) {
   2444   1.703    rillig 
   2445   1.988    rillig 		/*
   2446   1.988    rillig 		 * XXX: This code is similar to the one in Var_Parse. See if
   2447  1.1065    rillig 		 * the code can be merged. See also ParseModifier_Match and
   2448   1.988    rillig 		 * ParseModifierPart.
   2449   1.988    rillig 		 */
   2450   1.703    rillig 
   2451  1.1066    rillig 		/* See Buf_AddEscaped in for.c for the counterpart. */
   2452   1.703    rillig 		if (*p == '\\') {
   2453   1.703    rillig 			char c = p[1];
   2454  1.1030    rillig 			if ((IsDelimiter(c, ch) && c != '\0') ||
   2455  1.1030    rillig 			    c == '$' || c == '\\') {
   2456  1.1027    rillig 				if (shouldEval)
   2457  1.1027    rillig 					LazyBuf_Add(buf, c);
   2458   1.703    rillig 				p += 2;
   2459   1.703    rillig 				continue;
   2460   1.703    rillig 			}
   2461   1.703    rillig 		}
   2462   1.236    rillig 
   2463   1.703    rillig 		if (*p == '$') {
   2464  1.1042    rillig 			FStr val = Var_Parse(&p, ch->expr->scope,
   2465  1.1119    rillig 			    shouldEval ? ch->expr->emode : VARE_PARSE);
   2466   1.703    rillig 			/* TODO: handle errors */
   2467  1.1027    rillig 			if (shouldEval)
   2468  1.1027    rillig 				LazyBuf_AddStr(buf, val.str);
   2469  1.1027    rillig 			FStr_Done(&val);
   2470   1.703    rillig 			continue;
   2471   1.703    rillig 		}
   2472   1.687    rillig 
   2473  1.1027    rillig 		if (shouldEval)
   2474  1.1027    rillig 			LazyBuf_Add(buf, *p);
   2475   1.703    rillig 		p++;
   2476   1.466    rillig 	}
   2477   1.703    rillig 	*pp = p;
   2478  1.1026    rillig }
   2479  1.1026    rillig 
   2480  1.1026    rillig /* :Ddefined or :Uundefined */
   2481  1.1026    rillig static ApplyModifierResult
   2482  1.1026    rillig ApplyModifier_Defined(const char **pp, ModChain *ch)
   2483  1.1026    rillig {
   2484  1.1026    rillig 	Expr *expr = ch->expr;
   2485  1.1026    rillig 	LazyBuf buf;
   2486  1.1027    rillig 	bool shouldEval =
   2487  1.1027    rillig 	    Expr_ShouldEval(expr) &&
   2488  1.1027    rillig 	    (**pp == 'D') == (expr->defined == DEF_REGULAR);
   2489  1.1026    rillig 
   2490  1.1027    rillig 	ParseModifier_Defined(pp, ch, shouldEval, &buf);
   2491   1.466    rillig 
   2492   1.823    rillig 	Expr_Define(expr);
   2493  1.1027    rillig 	if (shouldEval)
   2494   1.929    rillig 		Expr_SetValue(expr, Substring_Str(LazyBuf_Get(&buf)));
   2495  1.1111    rillig 	LazyBuf_Done(&buf);
   2496   1.821    rillig 
   2497   1.703    rillig 	return AMR_OK;
   2498   1.236    rillig }
   2499   1.236    rillig 
   2500   1.567    rillig /* :L */
   2501   1.567    rillig static ApplyModifierResult
   2502   1.891    rillig ApplyModifier_Literal(const char **pp, ModChain *ch)
   2503   1.567    rillig {
   2504   1.891    rillig 	Expr *expr = ch->expr;
   2505   1.864    rillig 
   2506   1.864    rillig 	(*pp)++;
   2507   1.864    rillig 
   2508   1.905    rillig 	if (Expr_ShouldEval(expr)) {
   2509   1.872    rillig 		Expr_Define(expr);
   2510   1.898    rillig 		Expr_SetValueOwn(expr, bmake_strdup(expr->name));
   2511   1.872    rillig 	}
   2512   1.864    rillig 
   2513   1.703    rillig 	return AMR_OK;
   2514   1.567    rillig }
   2515   1.567    rillig 
   2516   1.895    rillig static bool
   2517   1.633    rillig TryParseTime(const char **pp, time_t *out_time)
   2518   1.631    rillig {
   2519   1.703    rillig 	char *end;
   2520   1.703    rillig 	unsigned long n;
   2521   1.631    rillig 
   2522   1.703    rillig 	if (!ch_isdigit(**pp))
   2523   1.895    rillig 		return false;
   2524   1.631    rillig 
   2525   1.703    rillig 	errno = 0;
   2526   1.703    rillig 	n = strtoul(*pp, &end, 10);
   2527   1.703    rillig 	if (n == ULONG_MAX && errno == ERANGE)
   2528   1.895    rillig 		return false;
   2529   1.631    rillig 
   2530   1.703    rillig 	*pp = end;
   2531   1.703    rillig 	*out_time = (time_t)n;	/* ignore possible truncation for now */
   2532   1.895    rillig 	return true;
   2533   1.631    rillig }
   2534   1.631    rillig 
   2535   1.994    rillig /* :gmtime and :localtime */
   2536   1.356    rillig static ApplyModifierResult
   2537   1.995    rillig ApplyModifier_Time(const char **pp, ModChain *ch)
   2538   1.236    rillig {
   2539   1.950    rillig 	Expr *expr;
   2540   1.993    rillig 	time_t t;
   2541   1.994    rillig 	const char *args;
   2542   1.995    rillig 	const char *mod = *pp;
   2543   1.995    rillig 	bool gmt = mod[0] == 'g';
   2544   1.412    rillig 
   2545   1.994    rillig 	if (!ModMatchEq(mod, gmt ? "gmtime" : "localtime", ch))
   2546   1.703    rillig 		return AMR_UNKNOWN;
   2547   1.994    rillig 	args = mod + (gmt ? 6 : 9);
   2548   1.703    rillig 
   2549   1.994    rillig 	if (args[0] == '=') {
   2550   1.994    rillig 		const char *p = args + 1;
   2551  1.1050    rillig 		LazyBuf buf;
   2552  1.1104    rillig 		FStr arg;
   2553  1.1115    rillig 		if (!ParseModifierPart(&p, ':', ch->endc, ch->expr->emode,
   2554  1.1050    rillig 		    ch, &buf, NULL, NULL))
   2555   1.703    rillig 			return AMR_CLEANUP;
   2556  1.1104    rillig 		arg = LazyBuf_DoneGet(&buf);
   2557  1.1050    rillig 		if (ModChain_ShouldEval(ch)) {
   2558  1.1104    rillig 			const char *arg_p = arg.str;
   2559  1.1104    rillig 			if (!TryParseTime(&arg_p, &t) || *arg_p != '\0') {
   2560  1.1050    rillig 				Parse_Error(PARSE_FATAL,
   2561  1.1104    rillig 				    "Invalid time value \"%s\"", arg.str);
   2562  1.1104    rillig 				FStr_Done(&arg);
   2563  1.1050    rillig 				return AMR_CLEANUP;
   2564  1.1050    rillig 			}
   2565  1.1050    rillig 		} else
   2566  1.1050    rillig 			t = 0;
   2567  1.1104    rillig 		FStr_Done(&arg);
   2568   1.843    rillig 		*pp = p;
   2569   1.703    rillig 	} else {
   2570   1.993    rillig 		t = 0;
   2571   1.994    rillig 		*pp = args;
   2572   1.631    rillig 	}
   2573   1.864    rillig 
   2574   1.950    rillig 	expr = ch->expr;
   2575   1.950    rillig 	if (Expr_ShouldEval(expr))
   2576  1.1059    rillig 		Expr_SetValueOwn(expr, FormatTime(Expr_Str(expr), t, gmt));
   2577   1.864    rillig 
   2578   1.703    rillig 	return AMR_OK;
   2579   1.236    rillig }
   2580   1.236    rillig 
   2581   1.236    rillig /* :hash */
   2582   1.356    rillig static ApplyModifierResult
   2583   1.891    rillig ApplyModifier_Hash(const char **pp, ModChain *ch)
   2584   1.236    rillig {
   2585   1.891    rillig 	if (!ModMatch(*pp, "hash", ch))
   2586   1.703    rillig 		return AMR_UNKNOWN;
   2587   1.864    rillig 	*pp += 4;
   2588   1.340    rillig 
   2589   1.905    rillig 	if (ModChain_ShouldEval(ch))
   2590  1.1059    rillig 		Expr_SetValueOwn(ch->expr, Hash(Expr_Str(ch->expr)));
   2591   1.864    rillig 
   2592   1.703    rillig 	return AMR_OK;
   2593   1.236    rillig }
   2594   1.236    rillig 
   2595   1.236    rillig /* :P */
   2596   1.356    rillig static ApplyModifierResult
   2597   1.891    rillig ApplyModifier_Path(const char **pp, ModChain *ch)
   2598   1.236    rillig {
   2599   1.891    rillig 	Expr *expr = ch->expr;
   2600   1.703    rillig 	GNode *gn;
   2601   1.703    rillig 	char *path;
   2602   1.412    rillig 
   2603   1.864    rillig 	(*pp)++;
   2604   1.864    rillig 
   2605   1.950    rillig 	if (!Expr_ShouldEval(expr))
   2606   1.873    rillig 		return AMR_OK;
   2607   1.873    rillig 
   2608   1.823    rillig 	Expr_Define(expr);
   2609   1.409    rillig 
   2610   1.898    rillig 	gn = Targ_FindNode(expr->name);
   2611  1.1067    rillig 	if (gn == NULL || gn->type & OP_NOPATH)
   2612   1.703    rillig 		path = NULL;
   2613  1.1067    rillig 	else if (gn->path != NULL)
   2614   1.703    rillig 		path = bmake_strdup(gn->path);
   2615  1.1067    rillig 	else {
   2616   1.703    rillig 		SearchPath *searchPath = Suff_FindPath(gn);
   2617   1.898    rillig 		path = Dir_FindFile(expr->name, searchPath);
   2618   1.703    rillig 	}
   2619   1.703    rillig 	if (path == NULL)
   2620   1.898    rillig 		path = bmake_strdup(expr->name);
   2621   1.823    rillig 	Expr_SetValueOwn(expr, path);
   2622   1.409    rillig 
   2623   1.703    rillig 	return AMR_OK;
   2624   1.236    rillig }
   2625   1.236    rillig 
   2626   1.236    rillig /* :!cmd! */
   2627   1.356    rillig static ApplyModifierResult
   2628   1.891    rillig ApplyModifier_ShellCommand(const char **pp, ModChain *ch)
   2629   1.236    rillig {
   2630   1.891    rillig 	Expr *expr = ch->expr;
   2631   1.921    rillig 	LazyBuf cmdBuf;
   2632   1.921    rillig 	FStr cmd;
   2633   1.703    rillig 
   2634   1.703    rillig 	(*pp)++;
   2635  1.1115    rillig 	if (!ParseModifierPart(pp, '!', '!', expr->emode,
   2636  1.1115    rillig 	    ch, &cmdBuf, NULL, NULL))
   2637   1.703    rillig 		return AMR_CLEANUP;
   2638   1.921    rillig 	cmd = LazyBuf_DoneGet(&cmdBuf);
   2639   1.921    rillig 
   2640  1.1000    rillig 	if (Expr_ShouldEval(expr)) {
   2641  1.1000    rillig 		char *output, *error;
   2642  1.1000    rillig 		output = Cmd_Exec(cmd.str, &error);
   2643  1.1000    rillig 		Expr_SetValueOwn(expr, output);
   2644  1.1000    rillig 		if (error != NULL) {
   2645  1.1122    rillig 			Parse_Error(PARSE_WARNING, "%s", error);
   2646  1.1000    rillig 			free(error);
   2647  1.1000    rillig 		}
   2648  1.1000    rillig 	} else
   2649  1.1000    rillig 		Expr_SetValueRefer(expr, "");
   2650   1.703    rillig 
   2651   1.921    rillig 	FStr_Done(&cmd);
   2652   1.864    rillig 	Expr_Define(expr);
   2653   1.274    rillig 
   2654   1.703    rillig 	return AMR_OK;
   2655   1.236    rillig }
   2656   1.236    rillig 
   2657   1.778    rillig /*
   2658   1.778    rillig  * The :range modifier generates an integer sequence as long as the words.
   2659   1.778    rillig  * The :range=7 modifier generates an integer sequence from 1 to 7.
   2660   1.778    rillig  */
   2661   1.356    rillig static ApplyModifierResult
   2662   1.891    rillig ApplyModifier_Range(const char **pp, ModChain *ch)
   2663   1.236    rillig {
   2664   1.703    rillig 	size_t n;
   2665   1.703    rillig 	Buffer buf;
   2666   1.703    rillig 	size_t i;
   2667   1.412    rillig 
   2668   1.703    rillig 	const char *mod = *pp;
   2669   1.891    rillig 	if (!ModMatchEq(mod, "range", ch))
   2670   1.703    rillig 		return AMR_UNKNOWN;
   2671   1.703    rillig 
   2672   1.703    rillig 	if (mod[5] == '=') {
   2673   1.703    rillig 		const char *p = mod + 6;
   2674   1.703    rillig 		if (!TryParseSize(&p, &n)) {
   2675   1.703    rillig 			Parse_Error(PARSE_FATAL,
   2676   1.844    rillig 			    "Invalid number \"%s\" for ':range' modifier",
   2677   1.844    rillig 			    mod + 6);
   2678   1.703    rillig 			return AMR_CLEANUP;
   2679   1.703    rillig 		}
   2680   1.703    rillig 		*pp = p;
   2681   1.703    rillig 	} else {
   2682   1.703    rillig 		n = 0;
   2683   1.703    rillig 		*pp = mod + 5;
   2684   1.635    rillig 	}
   2685   1.386    rillig 
   2686   1.905    rillig 	if (!ModChain_ShouldEval(ch))
   2687   1.873    rillig 		return AMR_OK;
   2688   1.873    rillig 
   2689   1.703    rillig 	if (n == 0) {
   2690   1.967    rillig 		SubstringWords words = Expr_Words(ch->expr);
   2691   1.703    rillig 		n = words.len;
   2692   1.961    rillig 		SubstringWords_Free(words);
   2693   1.703    rillig 	}
   2694   1.386    rillig 
   2695   1.703    rillig 	Buf_Init(&buf);
   2696   1.386    rillig 
   2697   1.703    rillig 	for (i = 0; i < n; i++) {
   2698   1.703    rillig 		if (i != 0) {
   2699   1.988    rillig 			/*
   2700   1.988    rillig 			 * XXX: Use ch->sep instead of ' ', for consistency.
   2701   1.988    rillig 			 */
   2702   1.703    rillig 			Buf_AddByte(&buf, ' ');
   2703   1.703    rillig 		}
   2704   1.703    rillig 		Buf_AddInt(&buf, 1 + (int)i);
   2705   1.703    rillig 	}
   2706   1.386    rillig 
   2707   1.891    rillig 	Expr_SetValueOwn(ch->expr, Buf_DoneData(&buf));
   2708   1.703    rillig 	return AMR_OK;
   2709   1.236    rillig }
   2710   1.236    rillig 
   2711   1.845    rillig /* Parse a ':M' or ':N' modifier. */
   2712  1.1013    rillig static char *
   2713  1.1013    rillig ParseModifier_Match(const char **pp, const ModChain *ch)
   2714   1.236    rillig {
   2715   1.845    rillig 	const char *mod = *pp;
   2716   1.891    rillig 	Expr *expr = ch->expr;
   2717   1.895    rillig 	bool copy = false;	/* pattern should be, or has been, copied */
   2718   1.895    rillig 	bool needSubst = false;
   2719   1.703    rillig 	const char *endpat;
   2720   1.703    rillig 	char *pattern;
   2721   1.412    rillig 
   2722   1.703    rillig 	/*
   2723   1.703    rillig 	 * In the loop below, ignore ':' unless we are at (or back to) the
   2724   1.703    rillig 	 * original brace level.
   2725   1.703    rillig 	 * XXX: This will likely not work right if $() and ${} are intermixed.
   2726   1.703    rillig 	 */
   2727   1.845    rillig 	/*
   2728   1.845    rillig 	 * XXX: This code is similar to the one in Var_Parse.
   2729   1.703    rillig 	 * See if the code can be merged.
   2730   1.845    rillig 	 * See also ApplyModifier_Defined.
   2731   1.845    rillig 	 */
   2732  1.1083    rillig 	int depth = 0;
   2733   1.703    rillig 	const char *p;
   2734  1.1083    rillig 	for (p = mod + 1; *p != '\0' && !(*p == ':' && depth == 0); p++) {
   2735  1.1031    rillig 		if (*p == '\\' && p[1] != '\0' &&
   2736   1.891    rillig 		    (IsDelimiter(p[1], ch) || p[1] == ch->startc)) {
   2737   1.703    rillig 			if (!needSubst)
   2738   1.895    rillig 				copy = true;
   2739   1.703    rillig 			p++;
   2740   1.703    rillig 			continue;
   2741   1.703    rillig 		}
   2742   1.703    rillig 		if (*p == '$')
   2743   1.895    rillig 			needSubst = true;
   2744   1.703    rillig 		if (*p == '(' || *p == '{')
   2745  1.1083    rillig 			depth++;
   2746   1.703    rillig 		if (*p == ')' || *p == '}') {
   2747  1.1083    rillig 			depth--;
   2748  1.1083    rillig 			if (depth < 0)
   2749   1.703    rillig 				break;
   2750   1.703    rillig 		}
   2751   1.236    rillig 	}
   2752   1.703    rillig 	*pp = p;
   2753   1.703    rillig 	endpat = p;
   2754   1.703    rillig 
   2755   1.703    rillig 	if (copy) {
   2756   1.703    rillig 		char *dst;
   2757   1.703    rillig 		const char *src;
   2758   1.703    rillig 
   2759   1.703    rillig 		/* Compress the \:'s out of the pattern. */
   2760   1.703    rillig 		pattern = bmake_malloc((size_t)(endpat - (mod + 1)) + 1);
   2761   1.703    rillig 		dst = pattern;
   2762   1.703    rillig 		src = mod + 1;
   2763   1.703    rillig 		for (; src < endpat; src++, dst++) {
   2764   1.703    rillig 			if (src[0] == '\\' && src + 1 < endpat &&
   2765   1.891    rillig 			    /* XXX: ch->startc is missing here; see above */
   2766   1.891    rillig 			    IsDelimiter(src[1], ch))
   2767   1.703    rillig 				src++;
   2768   1.703    rillig 			*dst = *src;
   2769   1.703    rillig 		}
   2770   1.703    rillig 		*dst = '\0';
   2771   1.703    rillig 	} else {
   2772   1.703    rillig 		pattern = bmake_strsedup(mod + 1, endpat);
   2773   1.236    rillig 	}
   2774   1.288    rillig 
   2775   1.703    rillig 	if (needSubst) {
   2776   1.703    rillig 		char *old_pattern = pattern;
   2777  1.1013    rillig 		/*
   2778  1.1013    rillig 		 * XXX: Contrary to ParseModifierPart, a dollar in a ':M' or
   2779  1.1013    rillig 		 * ':N' modifier must be escaped as '$$', not as '\$'.
   2780  1.1013    rillig 		 */
   2781  1.1043    rillig 		pattern = Var_Subst(pattern, expr->scope, expr->emode);
   2782   1.703    rillig 		/* TODO: handle errors */
   2783   1.703    rillig 		free(old_pattern);
   2784   1.236    rillig 	}
   2785   1.346    rillig 
   2786   1.908    rillig 	DEBUG2(VAR, "Pattern for ':%c' is \"%s\"\n", mod[0], pattern);
   2787   1.346    rillig 
   2788  1.1013    rillig 	return pattern;
   2789   1.845    rillig }
   2790   1.845    rillig 
   2791  1.1057    rillig struct ModifyWord_MatchArgs {
   2792  1.1057    rillig 	const char *pattern;
   2793  1.1057    rillig 	bool neg;
   2794  1.1058    rillig 	bool error_reported;
   2795  1.1057    rillig };
   2796  1.1057    rillig 
   2797  1.1057    rillig static void
   2798  1.1057    rillig ModifyWord_Match(Substring word, SepBuf *buf, void *data)
   2799  1.1057    rillig {
   2800  1.1057    rillig 	struct ModifyWord_MatchArgs *args = data;
   2801  1.1058    rillig 	StrMatchResult res;
   2802  1.1057    rillig 	assert(word.end[0] == '\0');	/* assume null-terminated word */
   2803  1.1058    rillig 	res = Str_Match(word.start, args->pattern);
   2804  1.1058    rillig 	if (res.error != NULL && !args->error_reported) {
   2805  1.1058    rillig 		args->error_reported = true;
   2806  1.1135    rillig 		Parse_Error(PARSE_FATAL,
   2807  1.1058    rillig 		    "%s in pattern '%s' of modifier '%s'",
   2808  1.1058    rillig 		    res.error, args->pattern, args->neg ? ":N" : ":M");
   2809  1.1058    rillig 	}
   2810  1.1058    rillig 	if (res.matched != args->neg)
   2811  1.1057    rillig 		SepBuf_AddSubstring(buf, word);
   2812  1.1057    rillig }
   2813  1.1057    rillig 
   2814   1.845    rillig /* :Mpattern or :Npattern */
   2815   1.845    rillig static ApplyModifierResult
   2816   1.891    rillig ApplyModifier_Match(const char **pp, ModChain *ch)
   2817   1.845    rillig {
   2818   1.996    rillig 	char mod = **pp;
   2819   1.845    rillig 	char *pattern;
   2820   1.845    rillig 
   2821  1.1013    rillig 	pattern = ParseModifier_Match(pp, ch);
   2822   1.845    rillig 
   2823   1.905    rillig 	if (ModChain_ShouldEval(ch)) {
   2824  1.1057    rillig 		struct ModifyWord_MatchArgs args;
   2825  1.1057    rillig 		args.pattern = pattern;
   2826  1.1057    rillig 		args.neg = mod == 'N';
   2827  1.1058    rillig 		args.error_reported = false;
   2828  1.1057    rillig 		ModifyWords(ch, ModifyWord_Match, &args, ch->oneBigWord);
   2829   1.876    rillig 	}
   2830   1.876    rillig 
   2831   1.703    rillig 	free(pattern);
   2832   1.703    rillig 	return AMR_OK;
   2833   1.236    rillig }
   2834   1.236    rillig 
   2835  1.1054       sjg struct ModifyWord_MtimeArgs {
   2836  1.1054       sjg 	bool error;
   2837  1.1060    rillig 	bool use_fallback;
   2838  1.1054       sjg 	ApplyModifierResult rc;
   2839  1.1060    rillig 	time_t fallback;
   2840  1.1054       sjg };
   2841  1.1054       sjg 
   2842  1.1054       sjg static void
   2843  1.1054       sjg ModifyWord_Mtime(Substring word, SepBuf *buf, void *data)
   2844  1.1054       sjg {
   2845  1.1060    rillig 	struct ModifyWord_MtimeArgs *args = data;
   2846  1.1054       sjg 	struct stat st;
   2847  1.1060    rillig 	char tbuf[21];
   2848  1.1054       sjg 
   2849  1.1054       sjg 	if (Substring_IsEmpty(word))
   2850  1.1054       sjg 		return;
   2851  1.1054       sjg 	assert(word.end[0] == '\0');	/* assume null-terminated word */
   2852  1.1054       sjg 	if (stat(word.start, &st) < 0) {
   2853  1.1054       sjg 		if (args->error) {
   2854  1.1054       sjg 			Parse_Error(PARSE_FATAL,
   2855  1.1054       sjg 			    "Cannot determine mtime for '%s': %s",
   2856  1.1054       sjg 			    word.start, strerror(errno));
   2857  1.1054       sjg 			args->rc = AMR_CLEANUP;
   2858  1.1054       sjg 			return;
   2859  1.1054       sjg 		}
   2860  1.1060    rillig 		if (args->use_fallback)
   2861  1.1060    rillig 			st.st_mtime = args->fallback;
   2862  1.1054       sjg 		else
   2863  1.1054       sjg 			time(&st.st_mtime);
   2864  1.1054       sjg 	}
   2865  1.1054       sjg 	snprintf(tbuf, sizeof(tbuf), "%u", (unsigned)st.st_mtime);
   2866  1.1054       sjg 	SepBuf_AddStr(buf, tbuf);
   2867  1.1054       sjg }
   2868  1.1054       sjg 
   2869  1.1051       sjg /* :mtime */
   2870  1.1051       sjg static ApplyModifierResult
   2871  1.1051       sjg ApplyModifier_Mtime(const char **pp, ModChain *ch)
   2872  1.1051       sjg {
   2873  1.1054       sjg 	const char *p, *mod = *pp;
   2874  1.1054       sjg 	struct ModifyWord_MtimeArgs args;
   2875  1.1051       sjg 
   2876  1.1051       sjg 	if (!ModMatchEq(mod, "mtime", ch))
   2877  1.1051       sjg 		return AMR_UNKNOWN;
   2878  1.1051       sjg 	*pp += 5;
   2879  1.1054       sjg 	p = *pp;
   2880  1.1060    rillig 	args.error = false;
   2881  1.1060    rillig 	args.use_fallback = p[0] == '=';
   2882  1.1054       sjg 	args.rc = AMR_OK;
   2883  1.1060    rillig 	if (args.use_fallback) {
   2884  1.1054       sjg 		p++;
   2885  1.1060    rillig 		if (TryParseTime(&p, &args.fallback)) {
   2886  1.1072    rillig 		} else if (strncmp(p, "error", 5) == 0) {
   2887  1.1060    rillig 			p += 5;
   2888  1.1060    rillig 			args.error = true;
   2889  1.1072    rillig 		} else
   2890  1.1072    rillig 			goto invalid_argument;
   2891  1.1072    rillig 		if (!IsDelimiter(*p, ch))
   2892  1.1072    rillig 			goto invalid_argument;
   2893  1.1054       sjg 		*pp = p;
   2894  1.1051       sjg 	}
   2895  1.1097    rillig 	ModifyWords(ch, ModifyWord_Mtime, &args, ch->oneBigWord);
   2896  1.1054       sjg 	return args.rc;
   2897  1.1072    rillig 
   2898  1.1072    rillig invalid_argument:
   2899  1.1072    rillig 	Parse_Error(PARSE_FATAL,
   2900  1.1072    rillig 	    "Invalid argument '%.*s' for modifier ':mtime'",
   2901  1.1072    rillig 	    (int)strcspn(*pp + 1, ":{}()"), *pp + 1);
   2902  1.1072    rillig 	return AMR_CLEANUP;
   2903  1.1051       sjg }
   2904  1.1051       sjg 
   2905   1.860    rillig static void
   2906   1.927    rillig ParsePatternFlags(const char **pp, PatternFlags *pflags, bool *oneBigWord)
   2907   1.860    rillig {
   2908   1.860    rillig 	for (;; (*pp)++) {
   2909   1.860    rillig 		if (**pp == 'g')
   2910   1.895    rillig 			pflags->subGlobal = true;
   2911   1.860    rillig 		else if (**pp == '1')
   2912   1.895    rillig 			pflags->subOnce = true;
   2913   1.860    rillig 		else if (**pp == 'W')
   2914   1.895    rillig 			*oneBigWord = true;
   2915   1.860    rillig 		else
   2916   1.860    rillig 			break;
   2917   1.860    rillig 	}
   2918   1.860    rillig }
   2919   1.860    rillig 
   2920   1.927    rillig MAKE_INLINE PatternFlags
   2921   1.927    rillig PatternFlags_None(void)
   2922   1.897    rillig {
   2923   1.927    rillig 	PatternFlags pflags = { false, false, false, false };
   2924   1.897    rillig 	return pflags;
   2925   1.897    rillig }
   2926   1.897    rillig 
   2927   1.236    rillig /* :S,from,to, */
   2928   1.356    rillig static ApplyModifierResult
   2929   1.891    rillig ApplyModifier_Subst(const char **pp, ModChain *ch)
   2930   1.236    rillig {
   2931   1.703    rillig 	struct ModifyWord_SubstArgs args;
   2932   1.895    rillig 	bool oneBigWord;
   2933   1.921    rillig 	LazyBuf lhsBuf, rhsBuf;
   2934   1.299    rillig 
   2935   1.703    rillig 	char delim = (*pp)[1];
   2936   1.703    rillig 	if (delim == '\0') {
   2937  1.1125    rillig 		Parse_Error(PARSE_FATAL,
   2938  1.1125    rillig 		    "Missing delimiter for modifier ':S'");
   2939   1.703    rillig 		(*pp)++;
   2940   1.703    rillig 		return AMR_CLEANUP;
   2941   1.703    rillig 	}
   2942   1.236    rillig 
   2943   1.703    rillig 	*pp += 2;
   2944   1.236    rillig 
   2945   1.927    rillig 	args.pflags = PatternFlags_None();
   2946   1.895    rillig 	args.matched = false;
   2947   1.236    rillig 
   2948   1.703    rillig 	if (**pp == '^') {
   2949   1.895    rillig 		args.pflags.anchorStart = true;
   2950   1.703    rillig 		(*pp)++;
   2951   1.703    rillig 	}
   2952   1.703    rillig 
   2953  1.1115    rillig 	if (!ParseModifierPart(pp, delim, delim, ch->expr->emode,
   2954  1.1115    rillig 	    ch, &lhsBuf, &args.pflags, NULL))
   2955   1.703    rillig 		return AMR_CLEANUP;
   2956   1.921    rillig 	args.lhs = LazyBuf_Get(&lhsBuf);
   2957   1.703    rillig 
   2958  1.1115    rillig 	if (!ParseModifierPart(pp, delim, delim, ch->expr->emode,
   2959  1.1115    rillig 	    ch, &rhsBuf, NULL, &args)) {
   2960   1.921    rillig 		LazyBuf_Done(&lhsBuf);
   2961   1.703    rillig 		return AMR_CLEANUP;
   2962   1.921    rillig 	}
   2963   1.921    rillig 	args.rhs = LazyBuf_Get(&rhsBuf);
   2964   1.703    rillig 
   2965   1.891    rillig 	oneBigWord = ch->oneBigWord;
   2966   1.860    rillig 	ParsePatternFlags(pp, &args.pflags, &oneBigWord);
   2967   1.236    rillig 
   2968   1.891    rillig 	ModifyWords(ch, ModifyWord_Subst, &args, oneBigWord);
   2969   1.236    rillig 
   2970   1.921    rillig 	LazyBuf_Done(&lhsBuf);
   2971   1.921    rillig 	LazyBuf_Done(&rhsBuf);
   2972   1.703    rillig 	return AMR_OK;
   2973   1.236    rillig }
   2974   1.236    rillig 
   2975   1.236    rillig /* :C,from,to, */
   2976   1.356    rillig static ApplyModifierResult
   2977   1.891    rillig ApplyModifier_Regex(const char **pp, ModChain *ch)
   2978   1.236    rillig {
   2979   1.703    rillig 	struct ModifyWord_SubstRegexArgs args;
   2980   1.895    rillig 	bool oneBigWord;
   2981   1.703    rillig 	int error;
   2982   1.921    rillig 	LazyBuf reBuf, replaceBuf;
   2983   1.984    rillig 	FStr re;
   2984   1.703    rillig 
   2985   1.703    rillig 	char delim = (*pp)[1];
   2986   1.703    rillig 	if (delim == '\0') {
   2987  1.1125    rillig 		Parse_Error(PARSE_FATAL,
   2988  1.1125    rillig 		    "Missing delimiter for modifier ':C'");
   2989   1.703    rillig 		(*pp)++;
   2990   1.703    rillig 		return AMR_CLEANUP;
   2991   1.703    rillig 	}
   2992   1.703    rillig 
   2993   1.703    rillig 	*pp += 2;
   2994   1.236    rillig 
   2995  1.1115    rillig 	if (!ParseModifierPart(pp, delim, delim, ch->expr->emode,
   2996  1.1115    rillig 	    ch, &reBuf, NULL, NULL))
   2997   1.703    rillig 		return AMR_CLEANUP;
   2998   1.921    rillig 	re = LazyBuf_DoneGet(&reBuf);
   2999   1.703    rillig 
   3000  1.1115    rillig 	if (!ParseModifierPart(pp, delim, delim, ch->expr->emode,
   3001  1.1115    rillig 	    ch, &replaceBuf, NULL, NULL)) {
   3002   1.921    rillig 		FStr_Done(&re);
   3003   1.703    rillig 		return AMR_CLEANUP;
   3004   1.703    rillig 	}
   3005   1.984    rillig 	args.replace = LazyBuf_Get(&replaceBuf);
   3006   1.703    rillig 
   3007   1.927    rillig 	args.pflags = PatternFlags_None();
   3008   1.895    rillig 	args.matched = false;
   3009   1.891    rillig 	oneBigWord = ch->oneBigWord;
   3010   1.860    rillig 	ParsePatternFlags(pp, &args.pflags, &oneBigWord);
   3011   1.236    rillig 
   3012  1.1034    rillig 	if (!ModChain_ShouldEval(ch))
   3013  1.1034    rillig 		goto done;
   3014   1.856    rillig 
   3015   1.921    rillig 	error = regcomp(&args.re, re.str, REG_EXTENDED);
   3016   1.703    rillig 	if (error != 0) {
   3017  1.1059    rillig 		RegexError(error, &args.re, "Regex compilation error");
   3018   1.984    rillig 		LazyBuf_Done(&replaceBuf);
   3019   1.921    rillig 		FStr_Done(&re);
   3020   1.703    rillig 		return AMR_CLEANUP;
   3021   1.236    rillig 	}
   3022   1.236    rillig 
   3023   1.703    rillig 	args.nsub = args.re.re_nsub + 1;
   3024   1.703    rillig 	if (args.nsub > 10)
   3025   1.703    rillig 		args.nsub = 10;
   3026   1.820    rillig 
   3027   1.891    rillig 	ModifyWords(ch, ModifyWord_SubstRegex, &args, oneBigWord);
   3028   1.820    rillig 
   3029   1.703    rillig 	regfree(&args.re);
   3030  1.1034    rillig done:
   3031   1.984    rillig 	LazyBuf_Done(&replaceBuf);
   3032   1.921    rillig 	FStr_Done(&re);
   3033   1.703    rillig 	return AMR_OK;
   3034   1.703    rillig }
   3035   1.236    rillig 
   3036   1.555    rillig /* :Q, :q */
   3037   1.555    rillig static ApplyModifierResult
   3038   1.891    rillig ApplyModifier_Quote(const char **pp, ModChain *ch)
   3039   1.555    rillig {
   3040   1.924    rillig 	LazyBuf buf;
   3041   1.924    rillig 	bool quoteDollar;
   3042   1.924    rillig 
   3043   1.924    rillig 	quoteDollar = **pp == 'q';
   3044   1.891    rillig 	if (!IsDelimiter((*pp)[1], ch))
   3045   1.703    rillig 		return AMR_UNKNOWN;
   3046   1.861    rillig 	(*pp)++;
   3047   1.861    rillig 
   3048   1.924    rillig 	if (!ModChain_ShouldEval(ch))
   3049   1.924    rillig 		return AMR_OK;
   3050   1.924    rillig 
   3051  1.1059    rillig 	QuoteShell(Expr_Str(ch->expr), quoteDollar, &buf);
   3052   1.924    rillig 	if (buf.data != NULL)
   3053   1.924    rillig 		Expr_SetValue(ch->expr, LazyBuf_DoneGet(&buf));
   3054   1.924    rillig 	else
   3055   1.924    rillig 		LazyBuf_Done(&buf);
   3056   1.861    rillig 
   3057   1.861    rillig 	return AMR_OK;
   3058   1.555    rillig }
   3059   1.555    rillig 
   3060   1.278    rillig static void
   3061   1.919    rillig ModifyWord_Copy(Substring word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
   3062   1.278    rillig {
   3063   1.919    rillig 	SepBuf_AddSubstring(buf, word);
   3064   1.275    rillig }
   3065   1.275    rillig 
   3066   1.289    rillig /* :ts<separator> */
   3067   1.356    rillig static ApplyModifierResult
   3068   1.891    rillig ApplyModifier_ToSep(const char **pp, ModChain *ch)
   3069   1.289    rillig {
   3070   1.703    rillig 	const char *sep = *pp + 2;
   3071   1.703    rillig 
   3072   1.873    rillig 	/*
   3073  1.1079    rillig 	 * Even in parse-only mode, apply the side effects, since the side
   3074  1.1079    rillig 	 * effects are neither observable nor is there a performance penalty.
   3075  1.1119    rillig 	 * Checking for VARE_EVAL for every single piece of code in here
   3076   1.873    rillig 	 * would make the code in this function too hard to read.
   3077   1.873    rillig 	 */
   3078   1.873    rillig 
   3079   1.703    rillig 	/* ":ts<any><endc>" or ":ts<any>:" */
   3080   1.891    rillig 	if (sep[0] != ch->endc && IsDelimiter(sep[1], ch)) {
   3081   1.864    rillig 		*pp = sep + 1;
   3082   1.891    rillig 		ch->sep = sep[0];
   3083   1.703    rillig 		goto ok;
   3084   1.703    rillig 	}
   3085   1.468    rillig 
   3086   1.703    rillig 	/* ":ts<endc>" or ":ts:" */
   3087   1.891    rillig 	if (IsDelimiter(sep[0], ch)) {
   3088   1.864    rillig 		*pp = sep;
   3089   1.891    rillig 		ch->sep = '\0';	/* no separator */
   3090   1.703    rillig 		goto ok;
   3091   1.703    rillig 	}
   3092   1.468    rillig 
   3093  1.1154    rillig 	if (sep[0] != '\\')
   3094  1.1154    rillig 		return AMR_UNKNOWN;
   3095   1.468    rillig 
   3096   1.703    rillig 	/* ":ts\n" */
   3097   1.703    rillig 	if (sep[1] == 'n') {
   3098   1.864    rillig 		*pp = sep + 2;
   3099   1.891    rillig 		ch->sep = '\n';
   3100   1.703    rillig 		goto ok;
   3101   1.703    rillig 	}
   3102   1.468    rillig 
   3103   1.703    rillig 	/* ":ts\t" */
   3104   1.703    rillig 	if (sep[1] == 't') {
   3105   1.864    rillig 		*pp = sep + 2;
   3106   1.891    rillig 		ch->sep = '\t';
   3107   1.703    rillig 		goto ok;
   3108   1.703    rillig 	}
   3109   1.468    rillig 
   3110   1.703    rillig 	/* ":ts\x40" or ":ts\100" */
   3111   1.703    rillig 	{
   3112   1.703    rillig 		const char *p = sep + 1;
   3113   1.703    rillig 		int base = 8;	/* assume octal */
   3114   1.468    rillig 
   3115   1.703    rillig 		if (sep[1] == 'x') {
   3116   1.703    rillig 			base = 16;
   3117   1.703    rillig 			p++;
   3118  1.1154    rillig 		} else if (!ch_isdigit(sep[1]))
   3119  1.1154    rillig 			return AMR_UNKNOWN;	/* ":ts\..." */
   3120   1.289    rillig 
   3121   1.891    rillig 		if (!TryParseChar(&p, base, &ch->sep)) {
   3122   1.703    rillig 			Parse_Error(PARSE_FATAL,
   3123   1.970    rillig 			    "Invalid character number at \"%s\"", p);
   3124   1.703    rillig 			return AMR_CLEANUP;
   3125   1.703    rillig 		}
   3126  1.1154    rillig 		if (!IsDelimiter(*p, ch))
   3127  1.1154    rillig 			return AMR_UNKNOWN;
   3128   1.468    rillig 
   3129   1.703    rillig 		*pp = p;
   3130   1.556    rillig 	}
   3131   1.635    rillig 
   3132   1.468    rillig ok:
   3133   1.891    rillig 	ModifyWords(ch, ModifyWord_Copy, NULL, ch->oneBigWord);
   3134   1.703    rillig 	return AMR_OK;
   3135   1.289    rillig }
   3136   1.289    rillig 
   3137   1.738    rillig static char *
   3138  1.1126       sjg str_totitle(const char *str)
   3139  1.1126       sjg {
   3140  1.1126       sjg 	size_t i, n = strlen(str) + 1;
   3141  1.1126       sjg 	char *res = bmake_malloc(n);
   3142  1.1126       sjg 	for (i = 0; i < n; i++) {
   3143  1.1126       sjg 		if (i == 0 || ch_isspace(res[i - 1]))
   3144  1.1126       sjg 			res[i] = ch_toupper(str[i]);
   3145  1.1126       sjg 		else
   3146  1.1126       sjg 			res[i] = ch_tolower(str[i]);
   3147  1.1126       sjg 	}
   3148  1.1126       sjg 	return res;
   3149  1.1126       sjg }
   3150  1.1126       sjg 
   3151  1.1126       sjg 
   3152  1.1126       sjg static char *
   3153   1.738    rillig str_toupper(const char *str)
   3154   1.738    rillig {
   3155  1.1106    rillig 	size_t i, n = strlen(str) + 1;
   3156  1.1106    rillig 	char *res = bmake_malloc(n);
   3157  1.1106    rillig 	for (i = 0; i < n; i++)
   3158   1.738    rillig 		res[i] = ch_toupper(str[i]);
   3159   1.738    rillig 	return res;
   3160   1.738    rillig }
   3161   1.738    rillig 
   3162   1.738    rillig static char *
   3163   1.738    rillig str_tolower(const char *str)
   3164   1.738    rillig {
   3165  1.1106    rillig 	size_t i, n = strlen(str) + 1;
   3166  1.1106    rillig 	char *res = bmake_malloc(n);
   3167  1.1106    rillig 	for (i = 0; i < n; i++)
   3168   1.738    rillig 		res[i] = ch_tolower(str[i]);
   3169   1.738    rillig 	return res;
   3170   1.738    rillig }
   3171   1.738    rillig 
   3172   1.289    rillig /* :tA, :tu, :tl, :ts<separator>, etc. */
   3173   1.356    rillig static ApplyModifierResult
   3174   1.891    rillig ApplyModifier_To(const char **pp, ModChain *ch)
   3175   1.236    rillig {
   3176   1.891    rillig 	Expr *expr = ch->expr;
   3177   1.703    rillig 	const char *mod = *pp;
   3178   1.703    rillig 	assert(mod[0] == 't');
   3179   1.363    rillig 
   3180  1.1154    rillig 	if (IsDelimiter(mod[1], ch))
   3181  1.1154    rillig 		return AMR_UNKNOWN;		/* ":t<endc>" or ":t:" */
   3182   1.289    rillig 
   3183   1.703    rillig 	if (mod[1] == 's')
   3184   1.891    rillig 		return ApplyModifier_ToSep(pp, ch);
   3185   1.289    rillig 
   3186  1.1154    rillig 	if (!IsDelimiter(mod[2], ch))
   3187  1.1154    rillig 		return AMR_UNKNOWN;
   3188   1.236    rillig 
   3189   1.810    rillig 	if (mod[1] == 'A') {				/* :tA */
   3190   1.864    rillig 		*pp = mod + 2;
   3191   1.891    rillig 		ModifyWords(ch, ModifyWord_Realpath, NULL, ch->oneBigWord);
   3192   1.703    rillig 		return AMR_OK;
   3193   1.703    rillig 	}
   3194   1.475    rillig 
   3195  1.1126       sjg 	if (mod[1] == 't') {				/* :tt */
   3196  1.1126       sjg 		*pp = mod + 2;
   3197  1.1126       sjg 		if (Expr_ShouldEval(expr))
   3198  1.1126       sjg 			Expr_SetValueOwn(expr, str_totitle(Expr_Str(expr)));
   3199  1.1126       sjg 		return AMR_OK;
   3200  1.1126       sjg 	}
   3201  1.1127    rillig 
   3202   1.810    rillig 	if (mod[1] == 'u') {				/* :tu */
   3203   1.864    rillig 		*pp = mod + 2;
   3204   1.950    rillig 		if (Expr_ShouldEval(expr))
   3205   1.965    rillig 			Expr_SetValueOwn(expr, str_toupper(Expr_Str(expr)));
   3206   1.703    rillig 		return AMR_OK;
   3207   1.703    rillig 	}
   3208   1.475    rillig 
   3209   1.810    rillig 	if (mod[1] == 'l') {				/* :tl */
   3210   1.864    rillig 		*pp = mod + 2;
   3211   1.950    rillig 		if (Expr_ShouldEval(expr))
   3212   1.965    rillig 			Expr_SetValueOwn(expr, str_tolower(Expr_Str(expr)));
   3213   1.703    rillig 		return AMR_OK;
   3214   1.703    rillig 	}
   3215   1.475    rillig 
   3216   1.810    rillig 	if (mod[1] == 'W' || mod[1] == 'w') {		/* :tW, :tw */
   3217   1.864    rillig 		*pp = mod + 2;
   3218   1.891    rillig 		ch->oneBigWord = mod[1] == 'W';
   3219   1.703    rillig 		return AMR_OK;
   3220   1.703    rillig 	}
   3221   1.475    rillig 
   3222  1.1154    rillig 	return AMR_UNKNOWN;		/* ":t<any>:" or ":t<any><endc>" */
   3223   1.236    rillig }
   3224   1.236    rillig 
   3225   1.634    rillig /* :[#], :[1], :[-1..1], etc. */
   3226   1.356    rillig static ApplyModifierResult
   3227   1.891    rillig ApplyModifier_Words(const char **pp, ModChain *ch)
   3228   1.236    rillig {
   3229   1.891    rillig 	Expr *expr = ch->expr;
   3230   1.703    rillig 	int first, last;
   3231  1.1157    rillig 	const char *p;
   3232  1.1079    rillig 	LazyBuf argBuf;
   3233  1.1079    rillig 	FStr arg;
   3234   1.412    rillig 
   3235   1.703    rillig 	(*pp)++;		/* skip the '[' */
   3236  1.1115    rillig 	if (!ParseModifierPart(pp, ']', ']', expr->emode,
   3237  1.1115    rillig 	    ch, &argBuf, NULL, NULL))
   3238   1.703    rillig 		return AMR_CLEANUP;
   3239  1.1079    rillig 	arg = LazyBuf_DoneGet(&argBuf);
   3240  1.1079    rillig 	p = arg.str;
   3241   1.703    rillig 
   3242  1.1157    rillig 	if (!IsDelimiter(**pp, ch)) {
   3243  1.1157    rillig 		Parse_Error(PARSE_FATAL,
   3244  1.1157    rillig 		    "Extra text after \"[%s]\"", arg.str);
   3245  1.1157    rillig 		FStr_Done(&arg);
   3246  1.1157    rillig 		return AMR_CLEANUP;
   3247  1.1157    rillig 	}
   3248   1.703    rillig 
   3249   1.905    rillig 	if (!ModChain_ShouldEval(ch))
   3250   1.877    rillig 		goto ok;
   3251   1.877    rillig 
   3252  1.1069    rillig 	if (p[0] == '\0')
   3253  1.1069    rillig 		goto bad_modifier;		/* Found ":[]". */
   3254   1.703    rillig 
   3255  1.1069    rillig 	if (strcmp(p, "#") == 0) {		/* Found ":[#]" */
   3256  1.1069    rillig 		if (ch->oneBigWord)
   3257   1.823    rillig 			Expr_SetValueRefer(expr, "1");
   3258  1.1069    rillig 		else {
   3259   1.703    rillig 			Buffer buf;
   3260   1.412    rillig 
   3261   1.967    rillig 			SubstringWords words = Expr_Words(expr);
   3262   1.703    rillig 			size_t ac = words.len;
   3263   1.961    rillig 			SubstringWords_Free(words);
   3264   1.703    rillig 
   3265  1.1087    rillig 			Buf_Init(&buf);
   3266   1.703    rillig 			Buf_AddInt(&buf, (int)ac);
   3267   1.823    rillig 			Expr_SetValueOwn(expr, Buf_DoneData(&buf));
   3268   1.703    rillig 		}
   3269   1.703    rillig 		goto ok;
   3270   1.703    rillig 	}
   3271   1.494    rillig 
   3272  1.1069    rillig 	if (strcmp(p, "*") == 0) {		/* ":[*]" */
   3273   1.895    rillig 		ch->oneBigWord = true;
   3274   1.703    rillig 		goto ok;
   3275   1.236    rillig 	}
   3276   1.288    rillig 
   3277  1.1069    rillig 	if (strcmp(p, "@") == 0) {		/* ":[@]" */
   3278   1.895    rillig 		ch->oneBigWord = false;
   3279   1.703    rillig 		goto ok;
   3280   1.703    rillig 	}
   3281   1.288    rillig 
   3282  1.1069    rillig 	/* Expect ":[N]" or ":[start..end]" */
   3283   1.703    rillig 	if (!TryParseIntBase0(&p, &first))
   3284  1.1069    rillig 		goto bad_modifier;
   3285   1.703    rillig 
   3286  1.1069    rillig 	if (p[0] == '\0')			/* ":[N]" */
   3287   1.703    rillig 		last = first;
   3288  1.1069    rillig 	else if (strncmp(p, "..", 2) == 0) {
   3289   1.703    rillig 		p += 2;
   3290   1.703    rillig 		if (!TryParseIntBase0(&p, &last) || *p != '\0')
   3291  1.1069    rillig 			goto bad_modifier;
   3292   1.703    rillig 	} else
   3293  1.1069    rillig 		goto bad_modifier;
   3294   1.288    rillig 
   3295  1.1069    rillig 	if (first == 0 && last == 0) {		/* ":[0]" or ":[0..0]" */
   3296   1.895    rillig 		ch->oneBigWord = true;
   3297   1.703    rillig 		goto ok;
   3298   1.703    rillig 	}
   3299   1.288    rillig 
   3300  1.1069    rillig 	if (first == 0 || last == 0)		/* ":[0..N]" or ":[N..0]" */
   3301   1.703    rillig 		goto bad_modifier;
   3302   1.703    rillig 
   3303   1.823    rillig 	Expr_SetValueOwn(expr,
   3304   1.965    rillig 	    VarSelectWords(Expr_Str(expr), first, last,
   3305  1.1019    rillig 		ch->sep, ch->oneBigWord));
   3306   1.288    rillig 
   3307   1.288    rillig ok:
   3308  1.1079    rillig 	FStr_Done(&arg);
   3309   1.703    rillig 	return AMR_OK;
   3310   1.288    rillig 
   3311   1.288    rillig bad_modifier:
   3312  1.1157    rillig 	Parse_Error(PARSE_FATAL, "Invalid modifier \":[%s]\"", arg.str);
   3313  1.1079    rillig 	FStr_Done(&arg);
   3314  1.1155    rillig 	return AMR_CLEANUP;
   3315   1.236    rillig }
   3316   1.236    rillig 
   3317  1.1016    rillig #if __STDC_VERSION__ >= 199901L
   3318   1.939       sjg # define NUM_TYPE long long
   3319  1.1009    rillig # define PARSE_NUM_TYPE strtoll
   3320  1.1009    rillig #else
   3321  1.1009    rillig # define NUM_TYPE long
   3322  1.1009    rillig # define PARSE_NUM_TYPE strtol
   3323   1.939       sjg #endif
   3324   1.939       sjg 
   3325   1.939       sjg static NUM_TYPE
   3326   1.964    rillig num_val(Substring s)
   3327   1.939       sjg {
   3328   1.939       sjg 	NUM_TYPE val;
   3329   1.939       sjg 	char *ep;
   3330   1.939       sjg 
   3331  1.1009    rillig 	val = PARSE_NUM_TYPE(s.start, &ep, 0);
   3332   1.964    rillig 	if (ep != s.start) {
   3333   1.939       sjg 		switch (*ep) {
   3334   1.939       sjg 		case 'K':
   3335   1.939       sjg 		case 'k':
   3336   1.939       sjg 			val <<= 10;
   3337   1.939       sjg 			break;
   3338   1.939       sjg 		case 'M':
   3339   1.939       sjg 		case 'm':
   3340   1.939       sjg 			val <<= 20;
   3341   1.939       sjg 			break;
   3342   1.939       sjg 		case 'G':
   3343   1.939       sjg 		case 'g':
   3344   1.939       sjg 			val <<= 30;
   3345   1.939       sjg 			break;
   3346   1.939       sjg 		}
   3347   1.939       sjg 	}
   3348   1.939       sjg 	return val;
   3349   1.939       sjg }
   3350   1.939       sjg 
   3351   1.939       sjg static int
   3352   1.964    rillig SubNumAsc(const void *sa, const void *sb)
   3353   1.939       sjg {
   3354   1.939       sjg 	NUM_TYPE a, b;
   3355   1.939       sjg 
   3356   1.964    rillig 	a = num_val(*((const Substring *)sa));
   3357   1.964    rillig 	b = num_val(*((const Substring *)sb));
   3358  1.1067    rillig 	return a > b ? 1 : b > a ? -1 : 0;
   3359   1.939       sjg }
   3360   1.940    rillig 
   3361   1.939       sjg static int
   3362   1.964    rillig SubNumDesc(const void *sa, const void *sb)
   3363   1.939       sjg {
   3364   1.964    rillig 	return SubNumAsc(sb, sa);
   3365   1.939       sjg }
   3366   1.940    rillig 
   3367   1.404    rillig static int
   3368  1.1068    rillig Substring_Cmp(Substring a, Substring b)
   3369  1.1068    rillig {
   3370  1.1068    rillig 	for (; a.start < a.end && b.start < b.end; a.start++, b.start++)
   3371  1.1068    rillig 		if (a.start[0] != b.start[0])
   3372  1.1068    rillig 			return (unsigned char)a.start[0]
   3373  1.1068    rillig 			    - (unsigned char)b.start[0];
   3374  1.1068    rillig 	return (int)((a.end - a.start) - (b.end - b.start));
   3375  1.1068    rillig }
   3376  1.1068    rillig 
   3377  1.1068    rillig static int
   3378   1.964    rillig SubStrAsc(const void *sa, const void *sb)
   3379   1.404    rillig {
   3380  1.1068    rillig 	return Substring_Cmp(*(const Substring *)sa, *(const Substring *)sb);
   3381   1.404    rillig }
   3382   1.404    rillig 
   3383   1.404    rillig static int
   3384   1.964    rillig SubStrDesc(const void *sa, const void *sb)
   3385   1.404    rillig {
   3386   1.964    rillig 	return SubStrAsc(sb, sa);
   3387   1.404    rillig }
   3388   1.404    rillig 
   3389   1.705    rillig static void
   3390   1.962    rillig ShuffleSubstrings(Substring *strs, size_t n)
   3391   1.705    rillig {
   3392   1.705    rillig 	size_t i;
   3393   1.705    rillig 
   3394   1.705    rillig 	for (i = n - 1; i > 0; i--) {
   3395   1.705    rillig 		size_t rndidx = (size_t)random() % (i + 1);
   3396   1.962    rillig 		Substring t = strs[i];
   3397   1.705    rillig 		strs[i] = strs[rndidx];
   3398   1.705    rillig 		strs[rndidx] = t;
   3399   1.705    rillig 	}
   3400   1.705    rillig }
   3401   1.705    rillig 
   3402   1.943    rillig /*
   3403   1.943    rillig  * :O		order ascending
   3404   1.943    rillig  * :Or		order descending
   3405   1.943    rillig  * :Ox		shuffle
   3406   1.943    rillig  * :On		numeric ascending
   3407   1.943    rillig  * :Onr, :Orn	numeric descending
   3408   1.939       sjg  */
   3409   1.356    rillig static ApplyModifierResult
   3410   1.891    rillig ApplyModifier_Order(const char **pp, ModChain *ch)
   3411   1.236    rillig {
   3412   1.942    rillig 	const char *mod = *pp;
   3413   1.962    rillig 	SubstringWords words;
   3414   1.946    rillig 	int (*cmp)(const void *, const void *);
   3415   1.401    rillig 
   3416  1.1032    rillig 	if (IsDelimiter(mod[1], ch)) {
   3417   1.964    rillig 		cmp = SubStrAsc;
   3418   1.939       sjg 		(*pp)++;
   3419  1.1032    rillig 	} else if (IsDelimiter(mod[2], ch)) {
   3420   1.942    rillig 		if (mod[1] == 'n')
   3421   1.964    rillig 			cmp = SubNumAsc;
   3422   1.942    rillig 		else if (mod[1] == 'r')
   3423   1.964    rillig 			cmp = SubStrDesc;
   3424   1.942    rillig 		else if (mod[1] == 'x')
   3425   1.944    rillig 			cmp = NULL;
   3426   1.942    rillig 		else
   3427  1.1153    rillig 			return AMR_UNKNOWN;
   3428   1.942    rillig 		*pp += 2;
   3429  1.1032    rillig 	} else if (IsDelimiter(mod[3], ch)) {
   3430   1.942    rillig 		if ((mod[1] == 'n' && mod[2] == 'r') ||
   3431   1.944    rillig 		    (mod[1] == 'r' && mod[2] == 'n'))
   3432   1.964    rillig 			cmp = SubNumDesc;
   3433   1.944    rillig 		else
   3434  1.1153    rillig 			return AMR_UNKNOWN;
   3435   1.942    rillig 		*pp += 3;
   3436   1.996    rillig 	} else
   3437  1.1153    rillig 		return AMR_UNKNOWN;
   3438   1.402    rillig 
   3439   1.905    rillig 	if (!ModChain_ShouldEval(ch))
   3440   1.879    rillig 		return AMR_OK;
   3441   1.879    rillig 
   3442   1.967    rillig 	words = Expr_Words(ch->expr);
   3443   1.944    rillig 	if (cmp == NULL)
   3444   1.962    rillig 		ShuffleSubstrings(words.words, words.len);
   3445   1.964    rillig 	else {
   3446   1.964    rillig 		assert(words.words[0].end[0] == '\0');
   3447   1.944    rillig 		qsort(words.words, words.len, sizeof(words.words[0]), cmp);
   3448   1.964    rillig 	}
   3449   1.962    rillig 	Expr_SetValueOwn(ch->expr, SubstringWords_JoinFree(words));
   3450   1.878    rillig 
   3451   1.705    rillig 	return AMR_OK;
   3452   1.236    rillig }
   3453   1.236    rillig 
   3454   1.236    rillig /* :? then : else */
   3455   1.356    rillig static ApplyModifierResult
   3456   1.891    rillig ApplyModifier_IfElse(const char **pp, ModChain *ch)
   3457   1.236    rillig {
   3458   1.891    rillig 	Expr *expr = ch->expr;
   3459   1.985    rillig 	LazyBuf thenBuf;
   3460   1.985    rillig 	LazyBuf elseBuf;
   3461   1.412    rillig 
   3462  1.1119    rillig 	VarEvalMode then_emode = VARE_PARSE;
   3463  1.1119    rillig 	VarEvalMode else_emode = VARE_PARSE;
   3464  1.1161    rillig 	int parseErrorsBefore = parseErrors;
   3465   1.236    rillig 
   3466  1.1143    rillig 	CondResult cond_rc = CR_TRUE;	/* anything other than CR_ERROR */
   3467   1.905    rillig 	if (Expr_ShouldEval(expr)) {
   3468  1.1124    rillig 		evalStack.elems[evalStack.len - 1].kind = VSK_COND;
   3469   1.990    rillig 		cond_rc = Cond_EvalCondition(expr->name);
   3470   1.990    rillig 		if (cond_rc == CR_TRUE)
   3471   1.906    rillig 			then_emode = expr->emode;
   3472  1.1161    rillig 		else if (cond_rc == CR_FALSE)
   3473   1.906    rillig 			else_emode = expr->emode;
   3474  1.1161    rillig 		else if (parseErrors == parseErrorsBefore)
   3475  1.1161    rillig 			Parse_Error(PARSE_FATAL, "Bad condition");
   3476   1.703    rillig 	}
   3477   1.703    rillig 
   3478  1.1124    rillig 	evalStack.elems[evalStack.len - 1].kind = VSK_COND_THEN;
   3479   1.988    rillig 	(*pp)++;		/* skip past the '?' */
   3480  1.1115    rillig 	if (!ParseModifierPart(pp, ':', ':', then_emode,
   3481  1.1115    rillig 	    ch, &thenBuf, NULL, NULL))
   3482   1.703    rillig 		return AMR_CLEANUP;
   3483   1.703    rillig 
   3484  1.1124    rillig 	evalStack.elems[evalStack.len - 1].kind = VSK_COND_ELSE;
   3485  1.1115    rillig 	if (!ParseModifierPart(pp, ch->endc, ch->endc, else_emode,
   3486  1.1115    rillig 	    ch, &elseBuf, NULL, NULL)) {
   3487   1.985    rillig 		LazyBuf_Done(&thenBuf);
   3488   1.703    rillig 		return AMR_CLEANUP;
   3489   1.921    rillig 	}
   3490   1.703    rillig 
   3491   1.891    rillig 	(*pp)--;		/* Go back to the ch->endc. */
   3492   1.809    rillig 
   3493   1.990    rillig 	if (cond_rc == CR_ERROR) {
   3494   1.985    rillig 		LazyBuf_Done(&thenBuf);
   3495   1.985    rillig 		LazyBuf_Done(&elseBuf);
   3496   1.703    rillig 		return AMR_CLEANUP;
   3497   1.703    rillig 	}
   3498   1.703    rillig 
   3499   1.950    rillig 	if (!Expr_ShouldEval(expr)) {
   3500   1.985    rillig 		LazyBuf_Done(&thenBuf);
   3501   1.985    rillig 		LazyBuf_Done(&elseBuf);
   3502   1.990    rillig 	} else if (cond_rc == CR_TRUE) {
   3503   1.985    rillig 		Expr_SetValue(expr, LazyBuf_DoneGet(&thenBuf));
   3504   1.985    rillig 		LazyBuf_Done(&elseBuf);
   3505   1.703    rillig 	} else {
   3506   1.985    rillig 		LazyBuf_Done(&thenBuf);
   3507   1.985    rillig 		Expr_SetValue(expr, LazyBuf_DoneGet(&elseBuf));
   3508   1.703    rillig 	}
   3509   1.823    rillig 	Expr_Define(expr);
   3510   1.703    rillig 	return AMR_OK;
   3511   1.236    rillig }
   3512   1.236    rillig 
   3513   1.283    rillig /*
   3514   1.808    rillig  * The ::= modifiers are special in that they do not read the variable value
   3515   1.808    rillig  * but instead assign to that variable.  They always expand to an empty
   3516   1.808    rillig  * string.
   3517   1.808    rillig  *
   3518   1.808    rillig  * Their main purpose is in supporting .for loops that generate shell commands
   3519   1.808    rillig  * since an ordinary variable assignment at that point would terminate the
   3520   1.808    rillig  * dependency group for these targets.  For example:
   3521   1.283    rillig  *
   3522   1.808    rillig  * list-targets: .USE
   3523   1.283    rillig  * .for i in ${.TARGET} ${.TARGET:R}.gz
   3524   1.808    rillig  *	@${t::=$i}
   3525   1.808    rillig  *	@echo 'The target is ${t:T}.'
   3526   1.283    rillig  * .endfor
   3527   1.283    rillig  *
   3528   1.283    rillig  *	  ::=<str>	Assigns <str> as the new value of variable.
   3529   1.283    rillig  *	  ::?=<str>	Assigns <str> as value of variable if
   3530   1.283    rillig  *			it was not already set.
   3531   1.283    rillig  *	  ::+=<str>	Appends <str> to variable.
   3532   1.283    rillig  *	  ::!=<cmd>	Assigns output of <cmd> as the new value of
   3533   1.283    rillig  *			variable.
   3534   1.283    rillig  */
   3535   1.356    rillig static ApplyModifierResult
   3536   1.891    rillig ApplyModifier_Assign(const char **pp, ModChain *ch)
   3537   1.236    rillig {
   3538   1.891    rillig 	Expr *expr = ch->expr;
   3539   1.802    rillig 	GNode *scope;
   3540   1.921    rillig 	FStr val;
   3541   1.921    rillig 	LazyBuf buf;
   3542   1.272    rillig 
   3543   1.703    rillig 	const char *mod = *pp;
   3544   1.703    rillig 	const char *op = mod + 1;
   3545   1.272    rillig 
   3546   1.703    rillig 	if (op[0] == '=')
   3547   1.992    rillig 		goto found_op;
   3548   1.992    rillig 	if ((op[0] == '+' || op[0] == '?' || op[0] == '!') && op[1] == '=')
   3549   1.992    rillig 		goto found_op;
   3550  1.1066    rillig 	return AMR_UNKNOWN;	/* "::<unrecognized>" */
   3551   1.862    rillig 
   3552   1.992    rillig found_op:
   3553   1.898    rillig 	if (expr->name[0] == '\0') {
   3554  1.1156    rillig 		const char *value = op[0] == '=' ? op + 1 : op + 2;
   3555   1.703    rillig 		*pp = mod + 1;
   3556  1.1155    rillig 		/* Take a guess at where the modifier ends. */
   3557  1.1156    rillig 		Parse_Error(PARSE_FATAL,
   3558  1.1156    rillig 		    "Invalid attempt to assign \"%.*s\" to variable \"\" "
   3559  1.1156    rillig 		    "via modifier \"::%.*s\"",
   3560  1.1156    rillig 		    (int)strcspn(value, ":)}"), value,
   3561  1.1156    rillig 		    (int)(value - op), op);
   3562  1.1155    rillig 		return AMR_CLEANUP;
   3563   1.703    rillig 	}
   3564   1.272    rillig 
   3565  1.1089    rillig 	*pp = mod + (op[0] != '=' ? 3 : 2);
   3566   1.703    rillig 
   3567  1.1115    rillig 	if (!ParseModifierPart(pp, ch->endc, ch->endc, expr->emode,
   3568  1.1115    rillig 	    ch, &buf, NULL, NULL))
   3569   1.703    rillig 		return AMR_CLEANUP;
   3570   1.921    rillig 	val = LazyBuf_DoneGet(&buf);
   3571   1.703    rillig 
   3572   1.891    rillig 	(*pp)--;		/* Go back to the ch->endc. */
   3573   1.703    rillig 
   3574   1.905    rillig 	if (!Expr_ShouldEval(expr))
   3575   1.882    rillig 		goto done;
   3576   1.882    rillig 
   3577   1.881    rillig 	scope = expr->scope;	/* scope where v belongs */
   3578  1.1089    rillig 	if (expr->defined == DEF_REGULAR && expr->scope != SCOPE_GLOBAL
   3579  1.1089    rillig 	    && VarFind(expr->name, expr->scope, false) == NULL)
   3580  1.1089    rillig 		scope = SCOPE_GLOBAL;
   3581   1.881    rillig 
   3582   1.999    rillig 	if (op[0] == '+')
   3583   1.921    rillig 		Var_Append(scope, expr->name, val.str);
   3584   1.999    rillig 	else if (op[0] == '!') {
   3585  1.1000    rillig 		char *output, *error;
   3586  1.1000    rillig 		output = Cmd_Exec(val.str, &error);
   3587  1.1000    rillig 		if (error != NULL) {
   3588  1.1123    rillig 			Parse_Error(PARSE_WARNING, "%s", error);
   3589  1.1000    rillig 			free(error);
   3590  1.1000    rillig 		} else
   3591  1.1000    rillig 			Var_Set(scope, expr->name, output);
   3592  1.1000    rillig 		free(output);
   3593   1.999    rillig 	} else if (op[0] == '?' && expr->defined == DEF_REGULAR) {
   3594   1.999    rillig 		/* Do nothing. */
   3595   1.999    rillig 	} else
   3596   1.921    rillig 		Var_Set(scope, expr->name, val.str);
   3597   1.999    rillig 
   3598   1.882    rillig 	Expr_SetValueRefer(expr, "");
   3599   1.882    rillig 
   3600   1.882    rillig done:
   3601   1.921    rillig 	FStr_Done(&val);
   3602   1.703    rillig 	return AMR_OK;
   3603   1.236    rillig }
   3604   1.236    rillig 
   3605   1.778    rillig /*
   3606   1.778    rillig  * :_=...
   3607   1.778    rillig  * remember current value
   3608   1.778    rillig  */
   3609   1.356    rillig static ApplyModifierResult
   3610   1.891    rillig ApplyModifier_Remember(const char **pp, ModChain *ch)
   3611   1.236    rillig {
   3612   1.891    rillig 	Expr *expr = ch->expr;
   3613   1.703    rillig 	const char *mod = *pp;
   3614   1.868    rillig 	FStr name;
   3615   1.866    rillig 
   3616   1.891    rillig 	if (!ModMatchEq(mod, "_", ch))
   3617   1.703    rillig 		return AMR_UNKNOWN;
   3618   1.703    rillig 
   3619   1.868    rillig 	name = FStr_InitRefer("_");
   3620   1.703    rillig 	if (mod[1] == '=') {
   3621   1.847    rillig 		/*
   3622   1.847    rillig 		 * XXX: This ad-hoc call to strcspn deviates from the usual
   3623   1.847    rillig 		 * behavior defined in ParseModifierPart.  This creates an
   3624  1.1066    rillig 		 * unnecessary and undocumented inconsistency in make.
   3625   1.847    rillig 		 */
   3626   1.869    rillig 		const char *arg = mod + 2;
   3627   1.869    rillig 		size_t argLen = strcspn(arg, ":)}");
   3628   1.869    rillig 		*pp = arg + argLen;
   3629   1.869    rillig 		name = FStr_InitOwn(bmake_strldup(arg, argLen));
   3630   1.868    rillig 	} else
   3631   1.868    rillig 		*pp = mod + 1;
   3632   1.864    rillig 
   3633   1.905    rillig 	if (Expr_ShouldEval(expr))
   3634  1.1040       sjg 		Var_Set(SCOPE_GLOBAL, name.str, Expr_Str(expr));
   3635   1.868    rillig 	FStr_Done(&name);
   3636   1.864    rillig 
   3637   1.703    rillig 	return AMR_OK;
   3638   1.236    rillig }
   3639   1.236    rillig 
   3640   1.778    rillig /*
   3641   1.778    rillig  * Apply the given function to each word of the variable value,
   3642   1.778    rillig  * for a single-letter modifier such as :H, :T.
   3643   1.778    rillig  */
   3644   1.434    rillig static ApplyModifierResult
   3645   1.891    rillig ApplyModifier_WordFunc(const char **pp, ModChain *ch,
   3646   1.822    rillig 		       ModifyWordProc modifyWord)
   3647   1.434    rillig {
   3648   1.891    rillig 	if (!IsDelimiter((*pp)[1], ch))
   3649   1.703    rillig 		return AMR_UNKNOWN;
   3650   1.864    rillig 	(*pp)++;
   3651   1.703    rillig 
   3652  1.1097    rillig 	ModifyWords(ch, modifyWord, NULL, ch->oneBigWord);
   3653   1.864    rillig 
   3654   1.703    rillig 	return AMR_OK;
   3655   1.434    rillig }
   3656   1.434    rillig 
   3657   1.931    rillig /* Remove adjacent duplicate words. */
   3658   1.567    rillig static ApplyModifierResult
   3659   1.891    rillig ApplyModifier_Unique(const char **pp, ModChain *ch)
   3660   1.567    rillig {
   3661   1.962    rillig 	SubstringWords words;
   3662   1.931    rillig 
   3663   1.891    rillig 	if (!IsDelimiter((*pp)[1], ch))
   3664   1.703    rillig 		return AMR_UNKNOWN;
   3665   1.862    rillig 	(*pp)++;
   3666   1.862    rillig 
   3667   1.931    rillig 	if (!ModChain_ShouldEval(ch))
   3668   1.931    rillig 		return AMR_OK;
   3669   1.931    rillig 
   3670   1.967    rillig 	words = Expr_Words(ch->expr);
   3671   1.931    rillig 
   3672   1.931    rillig 	if (words.len > 1) {
   3673  1.1067    rillig 		size_t di, si;
   3674   1.932    rillig 
   3675   1.932    rillig 		di = 0;
   3676   1.932    rillig 		for (si = 1; si < words.len; si++) {
   3677   1.962    rillig 			if (!Substring_Eq(words.words[si], words.words[di])) {
   3678   1.932    rillig 				di++;
   3679   1.932    rillig 				if (di != si)
   3680   1.932    rillig 					words.words[di] = words.words[si];
   3681   1.932    rillig 			}
   3682   1.932    rillig 		}
   3683   1.932    rillig 		words.len = di + 1;
   3684   1.931    rillig 	}
   3685   1.931    rillig 
   3686   1.962    rillig 	Expr_SetValueOwn(ch->expr, SubstringWords_JoinFree(words));
   3687   1.862    rillig 
   3688   1.862    rillig 	return AMR_OK;
   3689   1.567    rillig }
   3690   1.567    rillig 
   3691  1.1071    rillig /* Test whether the modifier has the form '<lhs>=<rhs>'. */
   3692  1.1071    rillig static bool
   3693  1.1071    rillig IsSysVModifier(const char *p, char startc, char endc)
   3694  1.1071    rillig {
   3695  1.1071    rillig 	bool eqFound = false;
   3696  1.1071    rillig 
   3697  1.1071    rillig 	int depth = 1;
   3698  1.1149    rillig 	while (*p != '\0') {
   3699  1.1071    rillig 		if (*p == '=')	/* XXX: should also test depth == 1 */
   3700  1.1071    rillig 			eqFound = true;
   3701  1.1149    rillig 		else if (*p == endc) {
   3702  1.1149    rillig 			if (--depth == 0)
   3703  1.1149    rillig 				break;
   3704  1.1149    rillig 		} else if (*p == startc)
   3705  1.1071    rillig 			depth++;
   3706  1.1149    rillig 		p++;
   3707  1.1071    rillig 	}
   3708  1.1149    rillig 	return eqFound;
   3709  1.1071    rillig }
   3710  1.1071    rillig 
   3711   1.236    rillig /* :from=to */
   3712   1.356    rillig static ApplyModifierResult
   3713   1.891    rillig ApplyModifier_SysV(const char **pp, ModChain *ch)
   3714   1.236    rillig {
   3715   1.891    rillig 	Expr *expr = ch->expr;
   3716   1.925    rillig 	LazyBuf lhsBuf, rhsBuf;
   3717   1.925    rillig 	FStr rhs;
   3718   1.926    rillig 	struct ModifyWord_SysVSubstArgs args;
   3719   1.925    rillig 	Substring lhs;
   3720   1.925    rillig 	const char *lhsSuffix;
   3721   1.412    rillig 
   3722   1.703    rillig 	const char *mod = *pp;
   3723   1.245    rillig 
   3724  1.1071    rillig 	if (!IsSysVModifier(mod, ch->startc, ch->endc))
   3725   1.703    rillig 		return AMR_UNKNOWN;
   3726   1.236    rillig 
   3727  1.1115    rillig 	if (!ParseModifierPart(pp, '=', '=', expr->emode,
   3728  1.1115    rillig 	    ch, &lhsBuf, NULL, NULL))
   3729   1.703    rillig 		return AMR_CLEANUP;
   3730   1.703    rillig 
   3731  1.1115    rillig 	if (!ParseModifierPart(pp, ch->endc, ch->endc, expr->emode,
   3732  1.1115    rillig 	    ch, &rhsBuf, NULL, NULL)) {
   3733   1.925    rillig 		LazyBuf_Done(&lhsBuf);
   3734   1.703    rillig 		return AMR_CLEANUP;
   3735   1.921    rillig 	}
   3736   1.925    rillig 	rhs = LazyBuf_DoneGet(&rhsBuf);
   3737   1.703    rillig 
   3738   1.891    rillig 	(*pp)--;		/* Go back to the ch->endc. */
   3739   1.809    rillig 
   3740   1.925    rillig 	/* Do not turn an empty expression into non-empty. */
   3741   1.965    rillig 	if (lhsBuf.len == 0 && Expr_Str(expr)[0] == '\0')
   3742   1.925    rillig 		goto done;
   3743   1.925    rillig 
   3744   1.925    rillig 	lhs = LazyBuf_Get(&lhsBuf);
   3745   1.925    rillig 	lhsSuffix = Substring_SkipFirst(lhs, '%');
   3746   1.925    rillig 
   3747   1.925    rillig 	args.scope = expr->scope;
   3748   1.925    rillig 	args.lhsPrefix = Substring_Init(lhs.start,
   3749   1.925    rillig 	    lhsSuffix != lhs.start ? lhsSuffix - 1 : lhs.start);
   3750   1.925    rillig 	args.lhsPercent = lhsSuffix != lhs.start;
   3751   1.925    rillig 	args.lhsSuffix = Substring_Init(lhsSuffix, lhs.end);
   3752   1.925    rillig 	args.rhs = rhs.str;
   3753   1.925    rillig 
   3754   1.926    rillig 	ModifyWords(ch, ModifyWord_SysVSubst, &args, ch->oneBigWord);
   3755   1.897    rillig 
   3756   1.925    rillig done:
   3757   1.925    rillig 	LazyBuf_Done(&lhsBuf);
   3758  1.1048    rillig 	FStr_Done(&rhs);
   3759   1.703    rillig 	return AMR_OK;
   3760   1.236    rillig }
   3761   1.236    rillig 
   3762   1.548    rillig /* :sh */
   3763   1.548    rillig static ApplyModifierResult
   3764   1.891    rillig ApplyModifier_SunShell(const char **pp, ModChain *ch)
   3765   1.548    rillig {
   3766   1.891    rillig 	Expr *expr = ch->expr;
   3767   1.703    rillig 	const char *p = *pp;
   3768   1.891    rillig 	if (!(p[1] == 'h' && IsDelimiter(p[2], ch)))
   3769   1.703    rillig 		return AMR_UNKNOWN;
   3770   1.864    rillig 	*pp = p + 2;
   3771   1.863    rillig 
   3772   1.905    rillig 	if (Expr_ShouldEval(expr)) {
   3773  1.1000    rillig 		char *output, *error;
   3774  1.1000    rillig 		output = Cmd_Exec(Expr_Str(expr), &error);
   3775  1.1000    rillig 		if (error != NULL) {
   3776  1.1122    rillig 			Parse_Error(PARSE_WARNING, "%s", error);
   3777  1.1000    rillig 			free(error);
   3778  1.1000    rillig 		}
   3779   1.863    rillig 		Expr_SetValueOwn(expr, output);
   3780   1.863    rillig 	}
   3781   1.864    rillig 
   3782   1.863    rillig 	return AMR_OK;
   3783   1.548    rillig }
   3784   1.548    rillig 
   3785  1.1041    rillig /*
   3786  1.1041    rillig  * In cases where the evaluation mode and the definedness are the "standard"
   3787  1.1041    rillig  * ones, don't log them, to keep the logs readable.
   3788  1.1041    rillig  */
   3789  1.1041    rillig static bool
   3790  1.1041    rillig ShouldLogInSimpleFormat(const Expr *expr)
   3791  1.1041    rillig {
   3792  1.1144    rillig 	return (expr->emode == VARE_EVAL
   3793  1.1144    rillig 		|| expr->emode == VARE_EVAL_DEFINED
   3794  1.1144    rillig 		|| expr->emode == VARE_EVAL_DEFINED_LOUD)
   3795  1.1119    rillig 	    && expr->defined == DEF_REGULAR;
   3796  1.1041    rillig }
   3797  1.1041    rillig 
   3798   1.549    rillig static void
   3799   1.891    rillig LogBeforeApply(const ModChain *ch, const char *mod)
   3800   1.549    rillig {
   3801   1.891    rillig 	const Expr *expr = ch->expr;
   3802   1.895    rillig 	bool is_single_char = mod[0] != '\0' && IsDelimiter(mod[1], ch);
   3803   1.703    rillig 
   3804   1.909    rillig 	/*
   3805   1.909    rillig 	 * At this point, only the first character of the modifier can
   3806   1.909    rillig 	 * be used since the end of the modifier is not yet known.
   3807   1.909    rillig 	 */
   3808   1.909    rillig 
   3809   1.909    rillig 	if (!Expr_ShouldEval(expr)) {
   3810   1.909    rillig 		debug_printf("Parsing modifier ${%s:%c%s}\n",
   3811   1.909    rillig 		    expr->name, mod[0], is_single_char ? "" : "...");
   3812   1.909    rillig 		return;
   3813   1.909    rillig 	}
   3814   1.909    rillig 
   3815  1.1041    rillig 	if (ShouldLogInSimpleFormat(expr)) {
   3816   1.910    rillig 		debug_printf(
   3817   1.910    rillig 		    "Evaluating modifier ${%s:%c%s} on value \"%s\"\n",
   3818   1.910    rillig 		    expr->name, mod[0], is_single_char ? "" : "...",
   3819   1.965    rillig 		    Expr_Str(expr));
   3820   1.910    rillig 		return;
   3821   1.910    rillig 	}
   3822   1.910    rillig 
   3823   1.909    rillig 	debug_printf(
   3824   1.909    rillig 	    "Evaluating modifier ${%s:%c%s} on value \"%s\" (%s, %s)\n",
   3825   1.965    rillig 	    expr->name, mod[0], is_single_char ? "" : "...", Expr_Str(expr),
   3826   1.910    rillig 	    VarEvalMode_Name[expr->emode], ExprDefined_Name[expr->defined]);
   3827   1.549    rillig }
   3828   1.549    rillig 
   3829   1.549    rillig static void
   3830   1.891    rillig LogAfterApply(const ModChain *ch, const char *p, const char *mod)
   3831   1.549    rillig {
   3832   1.891    rillig 	const Expr *expr = ch->expr;
   3833   1.965    rillig 	const char *value = Expr_Str(expr);
   3834   1.703    rillig 
   3835  1.1041    rillig 	if (ShouldLogInSimpleFormat(expr)) {
   3836  1.1150    rillig 		debug_printf("Result of ${%s:%.*s} is \"%s\"\n",
   3837  1.1150    rillig 		    expr->name, (int)(p - mod), mod, value);
   3838   1.912    rillig 		return;
   3839   1.912    rillig 	}
   3840   1.912    rillig 
   3841  1.1150    rillig 	debug_printf("Result of ${%s:%.*s} is \"%s\" (%s, %s)\n",
   3842  1.1150    rillig 	    expr->name, (int)(p - mod), mod, value,
   3843   1.906    rillig 	    VarEvalMode_Name[expr->emode],
   3844   1.825    rillig 	    ExprDefined_Name[expr->defined]);
   3845   1.549    rillig }
   3846   1.549    rillig 
   3847   1.551    rillig static ApplyModifierResult
   3848   1.891    rillig ApplyModifier(const char **pp, ModChain *ch)
   3849   1.551    rillig {
   3850   1.703    rillig 	switch (**pp) {
   3851   1.857    rillig 	case '!':
   3852   1.891    rillig 		return ApplyModifier_ShellCommand(pp, ch);
   3853   1.703    rillig 	case ':':
   3854   1.891    rillig 		return ApplyModifier_Assign(pp, ch);
   3855   1.857    rillig 	case '?':
   3856   1.891    rillig 		return ApplyModifier_IfElse(pp, ch);
   3857   1.703    rillig 	case '@':
   3858   1.891    rillig 		return ApplyModifier_Loop(pp, ch);
   3859   1.857    rillig 	case '[':
   3860   1.891    rillig 		return ApplyModifier_Words(pp, ch);
   3861   1.703    rillig 	case '_':
   3862   1.891    rillig 		return ApplyModifier_Remember(pp, ch);
   3863   1.857    rillig 	case 'C':
   3864   1.891    rillig 		return ApplyModifier_Regex(pp, ch);
   3865   1.703    rillig 	case 'D':
   3866   1.968    rillig 	case 'U':
   3867   1.891    rillig 		return ApplyModifier_Defined(pp, ch);
   3868   1.857    rillig 	case 'E':
   3869   1.891    rillig 		return ApplyModifier_WordFunc(pp, ch, ModifyWord_Suffix);
   3870   1.703    rillig 	case 'g':
   3871   1.995    rillig 	case 'l':
   3872   1.995    rillig 		return ApplyModifier_Time(pp, ch);
   3873   1.857    rillig 	case 'H':
   3874   1.891    rillig 		return ApplyModifier_WordFunc(pp, ch, ModifyWord_Head);
   3875   1.703    rillig 	case 'h':
   3876   1.891    rillig 		return ApplyModifier_Hash(pp, ch);
   3877   1.857    rillig 	case 'L':
   3878   1.891    rillig 		return ApplyModifier_Literal(pp, ch);
   3879   1.857    rillig 	case 'M':
   3880   1.703    rillig 	case 'N':
   3881   1.891    rillig 		return ApplyModifier_Match(pp, ch);
   3882  1.1051       sjg 	case 'm':
   3883  1.1051       sjg 		return ApplyModifier_Mtime(pp, ch);
   3884   1.857    rillig 	case 'O':
   3885   1.891    rillig 		return ApplyModifier_Order(pp, ch);
   3886   1.857    rillig 	case 'P':
   3887   1.891    rillig 		return ApplyModifier_Path(pp, ch);
   3888   1.857    rillig 	case 'Q':
   3889   1.703    rillig 	case 'q':
   3890   1.891    rillig 		return ApplyModifier_Quote(pp, ch);
   3891   1.703    rillig 	case 'R':
   3892   1.891    rillig 		return ApplyModifier_WordFunc(pp, ch, ModifyWord_Root);
   3893   1.703    rillig 	case 'r':
   3894   1.891    rillig 		return ApplyModifier_Range(pp, ch);
   3895   1.857    rillig 	case 'S':
   3896   1.891    rillig 		return ApplyModifier_Subst(pp, ch);
   3897   1.703    rillig 	case 's':
   3898   1.891    rillig 		return ApplyModifier_SunShell(pp, ch);
   3899   1.857    rillig 	case 'T':
   3900   1.891    rillig 		return ApplyModifier_WordFunc(pp, ch, ModifyWord_Tail);
   3901   1.857    rillig 	case 't':
   3902   1.891    rillig 		return ApplyModifier_To(pp, ch);
   3903   1.857    rillig 	case 'u':
   3904   1.891    rillig 		return ApplyModifier_Unique(pp, ch);
   3905   1.703    rillig 	default:
   3906   1.703    rillig 		return AMR_UNKNOWN;
   3907   1.703    rillig 	}
   3908   1.551    rillig }
   3909   1.551    rillig 
   3910   1.823    rillig static void ApplyModifiers(Expr *, const char **, char, char);
   3911   1.641    rillig 
   3912   1.641    rillig typedef enum ApplyModifiersIndirectResult {
   3913   1.752    rillig 	/* The indirect modifiers have been applied successfully. */
   3914   1.703    rillig 	AMIR_CONTINUE,
   3915   1.752    rillig 	/* Fall back to the SysV modifier. */
   3916   1.849    rillig 	AMIR_SYSV,
   3917   1.752    rillig 	/* Error out. */
   3918   1.703    rillig 	AMIR_OUT
   3919   1.641    rillig } ApplyModifiersIndirectResult;
   3920   1.641    rillig 
   3921   1.752    rillig /*
   3922  1.1075    rillig  * While expanding an expression, expand and apply indirect modifiers,
   3923   1.752    rillig  * such as in ${VAR:${M_indirect}}.
   3924   1.752    rillig  *
   3925  1.1075    rillig  * All indirect modifiers of a group must come from a single
   3926   1.752    rillig  * expression.  ${VAR:${M1}} is valid but ${VAR:${M1}${M2}} is not.
   3927   1.752    rillig  *
   3928   1.752    rillig  * Multiple groups of indirect modifiers can be chained by separating them
   3929   1.752    rillig  * with colons.  ${VAR:${M1}:${M2}} contains 2 indirect modifiers.
   3930   1.752    rillig  *
   3931  1.1075    rillig  * If the expression is not followed by ch->endc or ':', fall
   3932   1.752    rillig  * back to trying the SysV modifier, such as in ${VAR:${FROM}=${TO}}.
   3933   1.752    rillig  */
   3934   1.641    rillig static ApplyModifiersIndirectResult
   3935   1.891    rillig ApplyModifiersIndirect(ModChain *ch, const char **pp)
   3936   1.703    rillig {
   3937   1.891    rillig 	Expr *expr = ch->expr;
   3938   1.721    rillig 	const char *p = *pp;
   3939  1.1042    rillig 	FStr mods = Var_Parse(&p, expr->scope, expr->emode);
   3940   1.703    rillig 	/* TODO: handle errors */
   3941   1.641    rillig 
   3942  1.1032    rillig 	if (mods.str[0] != '\0' && !IsDelimiter(*p, ch)) {
   3943   1.743    rillig 		FStr_Done(&mods);
   3944   1.849    rillig 		return AMIR_SYSV;
   3945   1.703    rillig 	}
   3946   1.703    rillig 
   3947   1.708    rillig 	DEBUG3(VAR, "Indirect modifier \"%s\" from \"%.*s\"\n",
   3948   1.743    rillig 	    mods.str, (int)(p - *pp), *pp);
   3949   1.703    rillig 
   3950  1.1098    rillig 	if (ModChain_ShouldEval(ch) && mods.str[0] != '\0') {
   3951   1.743    rillig 		const char *modsp = mods.str;
   3952  1.1147    rillig 		EvalStack_Push(VSK_INDIRECT_MODIFIERS, mods.str, NULL);
   3953   1.823    rillig 		ApplyModifiers(expr, &modsp, '\0', '\0');
   3954  1.1147    rillig 		EvalStack_Pop();
   3955   1.965    rillig 		if (Expr_Str(expr) == var_Error || *modsp != '\0') {
   3956   1.743    rillig 			FStr_Done(&mods);
   3957   1.721    rillig 			*pp = p;
   3958   1.703    rillig 			return AMIR_OUT;	/* error already reported */
   3959   1.703    rillig 		}
   3960   1.703    rillig 	}
   3961   1.743    rillig 	FStr_Done(&mods);
   3962   1.641    rillig 
   3963   1.703    rillig 	if (*p == ':')
   3964   1.703    rillig 		p++;
   3965   1.891    rillig 	else if (*p == '\0' && ch->endc != '\0') {
   3966  1.1131    rillig 		Parse_Error(PARSE_FATAL,
   3967  1.1131    rillig 		    "Unclosed expression after indirect modifier, "
   3968  1.1131    rillig 		    "expecting '%c'",
   3969  1.1131    rillig 		    ch->endc);
   3970   1.721    rillig 		*pp = p;
   3971   1.703    rillig 		return AMIR_OUT;
   3972   1.641    rillig 	}
   3973   1.641    rillig 
   3974   1.721    rillig 	*pp = p;
   3975   1.703    rillig 	return AMIR_CONTINUE;
   3976   1.641    rillig }
   3977   1.641    rillig 
   3978   1.750    rillig static ApplyModifierResult
   3979   1.891    rillig ApplySingleModifier(const char **pp, ModChain *ch)
   3980   1.750    rillig {
   3981   1.750    rillig 	ApplyModifierResult res;
   3982   1.850    rillig 	const char *mod = *pp;
   3983   1.750    rillig 	const char *p = *pp;
   3984   1.750    rillig 
   3985   1.750    rillig 	if (DEBUG(VAR))
   3986   1.891    rillig 		LogBeforeApply(ch, mod);
   3987   1.750    rillig 
   3988  1.1158       sjg 	if (posix_state == PS_SET)
   3989  1.1158       sjg 		res = ApplyModifier_SysV(&p, ch);
   3990  1.1158       sjg 	else
   3991  1.1158       sjg 		res = AMR_UNKNOWN;
   3992  1.1158       sjg 	if (res == AMR_UNKNOWN)
   3993  1.1158       sjg 		res = ApplyModifier(&p, ch);
   3994   1.750    rillig 
   3995  1.1158       sjg 	if (res == AMR_UNKNOWN && posix_state != PS_SET) {
   3996   1.750    rillig 		assert(p == mod);
   3997   1.891    rillig 		res = ApplyModifier_SysV(&p, ch);
   3998   1.750    rillig 	}
   3999   1.750    rillig 
   4000   1.750    rillig 	if (res == AMR_UNKNOWN) {
   4001   1.750    rillig 		/*
   4002   1.750    rillig 		 * Guess the end of the current modifier.
   4003   1.750    rillig 		 * XXX: Skipping the rest of the modifier hides
   4004   1.750    rillig 		 * errors and leads to wrong results.
   4005   1.750    rillig 		 * Parsing should rather stop here.
   4006   1.750    rillig 		 */
   4007  1.1032    rillig 		for (p++; !IsDelimiter(*p, ch); p++)
   4008   1.750    rillig 			continue;
   4009  1.1151    rillig 		Parse_Error(PARSE_FATAL, "Unknown modifier \":%.*s\"",
   4010   1.851    rillig 		    (int)(p - mod), mod);
   4011   1.891    rillig 		Expr_SetValueRefer(ch->expr, var_Error);
   4012  1.1150    rillig 		res = AMR_CLEANUP;
   4013   1.750    rillig 	}
   4014  1.1150    rillig 	if (res != AMR_OK) {
   4015   1.750    rillig 		*pp = p;
   4016   1.750    rillig 		return res;
   4017   1.750    rillig 	}
   4018   1.750    rillig 
   4019   1.750    rillig 	if (DEBUG(VAR))
   4020   1.891    rillig 		LogAfterApply(ch, p, mod);
   4021   1.750    rillig 
   4022   1.891    rillig 	if (*p == '\0' && ch->endc != '\0') {
   4023  1.1131    rillig 		Parse_Error(PARSE_FATAL,
   4024  1.1074    rillig 		    "Unclosed expression, expecting '%c' for "
   4025  1.1131    rillig 		    "modifier \"%.*s\"",
   4026  1.1131    rillig 		    ch->endc, (int)(p - mod), mod);
   4027   1.750    rillig 	} else if (*p == ':') {
   4028   1.750    rillig 		p++;
   4029   1.891    rillig 	} else if (opts.strict && *p != '\0' && *p != ch->endc) {
   4030   1.750    rillig 		Parse_Error(PARSE_FATAL,
   4031   1.750    rillig 		    "Missing delimiter ':' after modifier \"%.*s\"",
   4032   1.750    rillig 		    (int)(p - mod), mod);
   4033   1.750    rillig 		/*
   4034   1.750    rillig 		 * TODO: propagate parse error to the enclosing
   4035   1.750    rillig 		 * expression
   4036   1.750    rillig 		 */
   4037   1.750    rillig 	}
   4038   1.750    rillig 	*pp = p;
   4039   1.750    rillig 	return AMR_OK;
   4040   1.750    rillig }
   4041   1.750    rillig 
   4042   1.897    rillig #if __STDC_VERSION__ >= 199901L
   4043  1.1079    rillig #define ModChain_Init(expr, startc, endc, sep, oneBigWord) \
   4044   1.897    rillig 	(ModChain) { expr, startc, endc, sep, oneBigWord }
   4045   1.897    rillig #else
   4046   1.897    rillig MAKE_INLINE ModChain
   4047  1.1079    rillig ModChain_Init(Expr *expr, char startc, char endc, char sep, bool oneBigWord)
   4048   1.897    rillig {
   4049   1.897    rillig 	ModChain ch;
   4050   1.897    rillig 	ch.expr = expr;
   4051   1.897    rillig 	ch.startc = startc;
   4052   1.897    rillig 	ch.endc = endc;
   4053   1.897    rillig 	ch.sep = sep;
   4054   1.897    rillig 	ch.oneBigWord = oneBigWord;
   4055   1.897    rillig 	return ch;
   4056   1.897    rillig }
   4057   1.897    rillig #endif
   4058   1.897    rillig 
   4059   1.419    rillig /* Apply any modifiers (such as :Mpattern or :@var@loop@ or :Q or ::=value). */
   4060   1.823    rillig static void
   4061   1.357    rillig ApplyModifiers(
   4062   1.823    rillig     Expr *expr,
   4063   1.821    rillig     const char **pp,	/* the parsing position, updated upon return */
   4064   1.821    rillig     char startc,	/* '(' or '{'; or '\0' for indirect modifiers */
   4065   1.823    rillig     char endc		/* ')' or '}'; or '\0' for indirect modifiers */
   4066   1.703    rillig )
   4067   1.703    rillig {
   4068  1.1079    rillig 	ModChain ch = ModChain_Init(expr, startc, endc, ' ', false);
   4069   1.703    rillig 	const char *p;
   4070   1.703    rillig 
   4071   1.703    rillig 	assert(startc == '(' || startc == '{' || startc == '\0');
   4072   1.703    rillig 	assert(endc == ')' || endc == '}' || endc == '\0');
   4073   1.965    rillig 	assert(Expr_Str(expr) != NULL);
   4074   1.703    rillig 
   4075   1.703    rillig 	p = *pp;
   4076   1.703    rillig 
   4077   1.703    rillig 	if (*p == '\0' && endc != '\0') {
   4078  1.1131    rillig 		Parse_Error(PARSE_FATAL,
   4079  1.1131    rillig 		    "Unclosed expression, expecting '%c'", ch.endc);
   4080   1.703    rillig 		goto cleanup;
   4081   1.703    rillig 	}
   4082   1.703    rillig 
   4083   1.703    rillig 	while (*p != '\0' && *p != endc) {
   4084   1.750    rillig 		ApplyModifierResult res;
   4085   1.703    rillig 
   4086   1.703    rillig 		if (*p == '$') {
   4087  1.1079    rillig 			/*
   4088  1.1079    rillig 			 * TODO: Only evaluate the expression once, no matter
   4089  1.1079    rillig 			 * whether it's an indirect modifier or the initial
   4090  1.1079    rillig 			 * part of a SysV modifier.
   4091  1.1079    rillig 			 */
   4092   1.849    rillig 			ApplyModifiersIndirectResult amir =
   4093   1.891    rillig 			    ApplyModifiersIndirect(&ch, &p);
   4094   1.703    rillig 			if (amir == AMIR_CONTINUE)
   4095   1.703    rillig 				continue;
   4096   1.703    rillig 			if (amir == AMIR_OUT)
   4097   1.752    rillig 				break;
   4098   1.703    rillig 		}
   4099   1.752    rillig 
   4100   1.891    rillig 		res = ApplySingleModifier(&p, &ch);
   4101   1.703    rillig 		if (res == AMR_CLEANUP)
   4102   1.703    rillig 			goto cleanup;
   4103   1.356    rillig 	}
   4104   1.752    rillig 
   4105   1.703    rillig 	*pp = p;
   4106   1.988    rillig 	assert(Expr_Str(expr) != NULL);	/* Use var_Error or varUndefined. */
   4107   1.823    rillig 	return;
   4108    1.25  christos 
   4109   1.240    rillig cleanup:
   4110   1.858    rillig 	/*
   4111   1.858    rillig 	 * TODO: Use p + strlen(p) instead, to stop parsing immediately.
   4112   1.858    rillig 	 *
   4113  1.1015    rillig 	 * In the unit tests, this generates a few shell commands with
   4114  1.1015    rillig 	 * unbalanced quotes.  Instead of producing these incomplete strings,
   4115  1.1015    rillig 	 * commands with evaluation errors should not be run at all.
   4116   1.858    rillig 	 *
   4117   1.858    rillig 	 * To make that happen, Var_Subst must report the actual errors
   4118  1.1044    rillig 	 * instead of returning the resulting string unconditionally.
   4119   1.858    rillig 	 */
   4120   1.703    rillig 	*pp = p;
   4121   1.823    rillig 	Expr_SetValueRefer(expr, var_Error);
   4122   1.108       sjg }
   4123    1.25  christos 
   4124   1.778    rillig /*
   4125  1.1015    rillig  * Only 4 of the 7 built-in local variables are treated specially as they are
   4126  1.1015    rillig  * the only ones that will be set when dynamic sources are expanded.
   4127   1.778    rillig  */
   4128   1.895    rillig static bool
   4129   1.916    rillig VarnameIsDynamic(Substring varname)
   4130   1.335    rillig {
   4131   1.916    rillig 	const char *name;
   4132   1.916    rillig 	size_t len;
   4133   1.916    rillig 
   4134   1.916    rillig 	name = varname.start;
   4135   1.916    rillig 	len = Substring_Length(varname);
   4136   1.703    rillig 	if (len == 1 || (len == 2 && (name[1] == 'F' || name[1] == 'D'))) {
   4137   1.703    rillig 		switch (name[0]) {
   4138   1.703    rillig 		case '@':
   4139   1.703    rillig 		case '%':
   4140   1.703    rillig 		case '*':
   4141   1.703    rillig 		case '!':
   4142   1.895    rillig 			return true;
   4143   1.703    rillig 		}
   4144   1.895    rillig 		return false;
   4145   1.335    rillig 	}
   4146   1.335    rillig 
   4147   1.703    rillig 	if ((len == 7 || len == 8) && name[0] == '.' && ch_isupper(name[1])) {
   4148   1.916    rillig 		return Substring_Equals(varname, ".TARGET") ||
   4149   1.916    rillig 		       Substring_Equals(varname, ".ARCHIVE") ||
   4150   1.916    rillig 		       Substring_Equals(varname, ".PREFIX") ||
   4151   1.916    rillig 		       Substring_Equals(varname, ".MEMBER");
   4152   1.703    rillig 	}
   4153   1.335    rillig 
   4154   1.895    rillig 	return false;
   4155   1.335    rillig }
   4156   1.335    rillig 
   4157   1.502    rillig static const char *
   4158   1.802    rillig UndefinedShortVarValue(char varname, const GNode *scope)
   4159   1.502    rillig {
   4160   1.802    rillig 	if (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL) {
   4161   1.703    rillig 		/*
   4162   1.802    rillig 		 * If substituting a local variable in a non-local scope,
   4163   1.703    rillig 		 * assume it's for dynamic source stuff. We have to handle
   4164   1.703    rillig 		 * this specially and return the longhand for the variable
   4165   1.703    rillig 		 * with the dollar sign escaped so it makes it back to the
   4166   1.703    rillig 		 * caller. Only four of the local variables are treated
   4167   1.703    rillig 		 * specially as they are the only four that will be set
   4168   1.703    rillig 		 * when dynamic sources are expanded.
   4169   1.703    rillig 		 */
   4170   1.703    rillig 		switch (varname) {
   4171   1.703    rillig 		case '@':
   4172   1.703    rillig 			return "$(.TARGET)";
   4173   1.703    rillig 		case '%':
   4174   1.703    rillig 			return "$(.MEMBER)";
   4175   1.703    rillig 		case '*':
   4176   1.703    rillig 			return "$(.PREFIX)";
   4177   1.703    rillig 		case '!':
   4178   1.703    rillig 			return "$(.ARCHIVE)";
   4179   1.703    rillig 		}
   4180   1.502    rillig 	}
   4181   1.769    rillig 	return NULL;
   4182   1.502    rillig }
   4183   1.502    rillig 
   4184   1.778    rillig /*
   4185   1.778    rillig  * Parse a variable name, until the end character or a colon, whichever
   4186   1.778    rillig  * comes first.
   4187   1.778    rillig  */
   4188   1.916    rillig static void
   4189   1.501    rillig ParseVarname(const char **pp, char startc, char endc,
   4190   1.906    rillig 	     GNode *scope, VarEvalMode emode,
   4191   1.916    rillig 	     LazyBuf *buf)
   4192   1.501    rillig {
   4193   1.703    rillig 	const char *p = *pp;
   4194  1.1066    rillig 	int depth = 0;
   4195   1.703    rillig 
   4196   1.923    rillig 	LazyBuf_Init(buf, p);
   4197   1.703    rillig 
   4198   1.703    rillig 	while (*p != '\0') {
   4199   1.854    rillig 		if ((*p == endc || *p == ':') && depth == 0)
   4200   1.854    rillig 			break;
   4201   1.703    rillig 		if (*p == startc)
   4202   1.703    rillig 			depth++;
   4203   1.854    rillig 		if (*p == endc)
   4204   1.854    rillig 			depth--;
   4205   1.501    rillig 
   4206   1.703    rillig 		if (*p == '$') {
   4207  1.1042    rillig 			FStr nested_val = Var_Parse(&p, scope, emode);
   4208   1.703    rillig 			/* TODO: handle errors */
   4209   1.916    rillig 			LazyBuf_AddStr(buf, nested_val.str);
   4210   1.743    rillig 			FStr_Done(&nested_val);
   4211   1.703    rillig 		} else {
   4212   1.916    rillig 			LazyBuf_Add(buf, *p);
   4213   1.703    rillig 			p++;
   4214   1.703    rillig 		}
   4215   1.501    rillig 	}
   4216   1.703    rillig 	*pp = p;
   4217   1.501    rillig }
   4218   1.501    rillig 
   4219  1.1023    rillig static bool
   4220  1.1023    rillig IsShortVarnameValid(char varname, const char *start)
   4221   1.507    rillig {
   4222   1.818    rillig 	if (varname != '$' && varname != ':' && varname != '}' &&
   4223   1.818    rillig 	    varname != ')' && varname != '\0')
   4224  1.1023    rillig 		return true;
   4225   1.507    rillig 
   4226   1.771    rillig 	if (!opts.strict)
   4227  1.1023    rillig 		return false;	/* XXX: Missing error message */
   4228   1.507    rillig 
   4229  1.1096       sjg 	if (varname == '$' && save_dollars)
   4230   1.703    rillig 		Parse_Error(PARSE_FATAL,
   4231   1.507    rillig 		    "To escape a dollar, use \\$, not $$, at \"%s\"", start);
   4232   1.703    rillig 	else if (varname == '\0')
   4233   1.703    rillig 		Parse_Error(PARSE_FATAL, "Dollar followed by nothing");
   4234  1.1096       sjg 	else if (save_dollars)
   4235   1.703    rillig 		Parse_Error(PARSE_FATAL,
   4236   1.507    rillig 		    "Invalid variable name '%c', at \"%s\"", varname, start);
   4237   1.507    rillig 
   4238  1.1023    rillig 	return false;
   4239   1.507    rillig }
   4240   1.507    rillig 
   4241   1.778    rillig /*
   4242   1.817    rillig  * Parse a single-character variable name such as in $V or $@.
   4243   1.778    rillig  * Return whether to continue parsing.
   4244   1.778    rillig  */
   4245   1.895    rillig static bool
   4246   1.817    rillig ParseVarnameShort(char varname, const char **pp, GNode *scope,
   4247   1.906    rillig 		  VarEvalMode emode,
   4248  1.1042    rillig 		  const char **out_false_val,
   4249   1.896    rillig 		  Var **out_true_var)
   4250   1.667    rillig {
   4251   1.703    rillig 	char name[2];
   4252   1.703    rillig 	Var *v;
   4253  1.1024    rillig 	const char *val;
   4254   1.622    rillig 
   4255  1.1023    rillig 	if (!IsShortVarnameValid(varname, *pp)) {
   4256  1.1025    rillig 		(*pp)++;	/* only skip the '$' */
   4257   1.896    rillig 		*out_false_val = var_Error;
   4258   1.895    rillig 		return false;
   4259   1.703    rillig 	}
   4260   1.622    rillig 
   4261   1.817    rillig 	name[0] = varname;
   4262   1.703    rillig 	name[1] = '\0';
   4263   1.895    rillig 	v = VarFind(name, scope, true);
   4264  1.1024    rillig 	if (v != NULL) {
   4265  1.1025    rillig 		/* No need to advance *pp, the calling code handles this. */
   4266  1.1024    rillig 		*out_true_var = v;
   4267  1.1024    rillig 		return true;
   4268  1.1024    rillig 	}
   4269   1.622    rillig 
   4270  1.1024    rillig 	*pp += 2;
   4271   1.769    rillig 
   4272  1.1024    rillig 	val = UndefinedShortVarValue(varname, scope);
   4273  1.1024    rillig 	if (val == NULL)
   4274  1.1144    rillig 		val = emode == VARE_EVAL_DEFINED
   4275  1.1144    rillig 		    || emode == VARE_EVAL_DEFINED_LOUD
   4276  1.1144    rillig 		    ? var_Error : varUndefined;
   4277   1.767    rillig 
   4278  1.1144    rillig 	if ((opts.strict || emode == VARE_EVAL_DEFINED_LOUD)
   4279  1.1144    rillig 	    && val == var_Error) {
   4280  1.1024    rillig 		Parse_Error(PARSE_FATAL,
   4281  1.1024    rillig 		    "Variable \"%s\" is undefined", name);
   4282   1.622    rillig 	}
   4283   1.622    rillig 
   4284  1.1024    rillig 	*out_false_val = val;
   4285  1.1024    rillig 	return false;
   4286   1.622    rillig }
   4287   1.622    rillig 
   4288   1.662    rillig /* Find variables like @F or <D. */
   4289   1.662    rillig static Var *
   4290   1.916    rillig FindLocalLegacyVar(Substring varname, GNode *scope,
   4291   1.662    rillig 		   const char **out_extraModifiers)
   4292   1.662    rillig {
   4293   1.916    rillig 	Var *v;
   4294   1.916    rillig 
   4295   1.802    rillig 	/* Only resolve these variables if scope is a "real" target. */
   4296   1.802    rillig 	if (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL)
   4297   1.703    rillig 		return NULL;
   4298   1.703    rillig 
   4299   1.916    rillig 	if (Substring_Length(varname) != 2)
   4300   1.703    rillig 		return NULL;
   4301   1.916    rillig 	if (varname.start[1] != 'F' && varname.start[1] != 'D')
   4302   1.703    rillig 		return NULL;
   4303   1.916    rillig 	if (strchr("@%?*!<>", varname.start[0]) == NULL)
   4304   1.703    rillig 		return NULL;
   4305   1.703    rillig 
   4306  1.1091    rillig 	v = VarFindSubstring(Substring_Init(varname.start, varname.start + 1),
   4307  1.1091    rillig 	    scope, false);
   4308   1.916    rillig 	if (v == NULL)
   4309   1.916    rillig 		return NULL;
   4310   1.897    rillig 
   4311   1.916    rillig 	*out_extraModifiers = varname.start[1] == 'D' ? "H:" : "T:";
   4312   1.916    rillig 	return v;
   4313   1.662    rillig }
   4314   1.662    rillig 
   4315  1.1044    rillig static FStr
   4316   1.916    rillig EvalUndefined(bool dynamic, const char *start, const char *p,
   4317  1.1159    rillig 	      Substring varname, VarEvalMode emode, int parseErrorsBefore)
   4318   1.667    rillig {
   4319  1.1044    rillig 	if (dynamic)
   4320  1.1044    rillig 		return FStr_InitOwn(bmake_strsedup(start, p));
   4321   1.703    rillig 
   4322  1.1144    rillig 	if (emode == VARE_EVAL_DEFINED_LOUD
   4323  1.1144    rillig 	    || (emode == VARE_EVAL_DEFINED && opts.strict)) {
   4324  1.1159    rillig 		if (parseErrors == parseErrorsBefore) {
   4325  1.1159    rillig 			Parse_Error(PARSE_FATAL,
   4326  1.1159    rillig 			    "Variable \"%.*s\" is undefined",
   4327  1.1159    rillig 			    (int) Substring_Length(varname), varname.start);
   4328  1.1159    rillig 		}
   4329  1.1044    rillig 		return FStr_InitRefer(var_Error);
   4330   1.703    rillig 	}
   4331   1.703    rillig 
   4332  1.1044    rillig 	return FStr_InitRefer(
   4333  1.1144    rillig 	    emode == VARE_EVAL_DEFINED_LOUD || emode == VARE_EVAL_DEFINED
   4334  1.1144    rillig 		? var_Error : varUndefined);
   4335   1.663    rillig }
   4336   1.663    rillig 
   4337   1.778    rillig /*
   4338   1.778    rillig  * Parse a long variable name enclosed in braces or parentheses such as $(VAR)
   4339   1.623    rillig  * or ${VAR}, up to the closing brace or parenthesis, or in the case of
   4340   1.623    rillig  * ${VAR:Modifiers}, up to the ':' that starts the modifiers.
   4341   1.778    rillig  * Return whether to continue parsing.
   4342   1.778    rillig  */
   4343   1.895    rillig static bool
   4344   1.623    rillig ParseVarnameLong(
   4345   1.922    rillig 	const char **pp,
   4346   1.624    rillig 	char startc,
   4347   1.802    rillig 	GNode *scope,
   4348   1.906    rillig 	VarEvalMode emode,
   4349  1.1144    rillig 	VarEvalMode nested_emode,
   4350  1.1159    rillig 	int parseErrorsBefore,
   4351   1.624    rillig 
   4352   1.896    rillig 	const char **out_false_pp,
   4353   1.896    rillig 	FStr *out_false_val,
   4354   1.896    rillig 
   4355   1.896    rillig 	char *out_true_endc,
   4356   1.896    rillig 	Var **out_true_v,
   4357   1.896    rillig 	bool *out_true_haveModifier,
   4358   1.896    rillig 	const char **out_true_extraModifiers,
   4359   1.896    rillig 	bool *out_true_dynamic,
   4360   1.896    rillig 	ExprDefined *out_true_exprDefined
   4361   1.703    rillig )
   4362   1.703    rillig {
   4363   1.916    rillig 	LazyBuf varname;
   4364   1.972       sjg 	Substring name;
   4365   1.703    rillig 	Var *v;
   4366   1.895    rillig 	bool haveModifier;
   4367   1.895    rillig 	bool dynamic = false;
   4368   1.703    rillig 
   4369   1.922    rillig 	const char *p = *pp;
   4370  1.1095    rillig 	const char *start = p;
   4371   1.703    rillig 	char endc = startc == '(' ? ')' : '}';
   4372   1.703    rillig 
   4373   1.703    rillig 	p += 2;			/* skip "${" or "$(" or "y(" */
   4374  1.1144    rillig 	ParseVarname(&p, startc, endc, scope, nested_emode, &varname);
   4375   1.972       sjg 	name = LazyBuf_Get(&varname);
   4376   1.703    rillig 
   4377  1.1093    rillig 	if (*p == ':')
   4378   1.895    rillig 		haveModifier = true;
   4379  1.1093    rillig 	else if (*p == endc)
   4380   1.895    rillig 		haveModifier = false;
   4381  1.1093    rillig 	else {
   4382   1.916    rillig 		Parse_Error(PARSE_FATAL, "Unclosed variable \"%.*s\"",
   4383   1.916    rillig 		    (int)Substring_Length(name), name.start);
   4384   1.916    rillig 		LazyBuf_Done(&varname);
   4385   1.896    rillig 		*out_false_pp = p;
   4386   1.896    rillig 		*out_false_val = FStr_InitRefer(var_Error);
   4387   1.895    rillig 		return false;
   4388   1.703    rillig 	}
   4389   1.623    rillig 
   4390   1.972       sjg 	v = VarFindSubstring(name, scope, true);
   4391   1.623    rillig 
   4392   1.988    rillig 	/*
   4393   1.988    rillig 	 * At this point, p points just after the variable name, either at
   4394   1.988    rillig 	 * ':' or at endc.
   4395   1.988    rillig 	 */
   4396   1.623    rillig 
   4397   1.974    rillig 	if (v == NULL && Substring_Equals(name, ".SUFFIXES")) {
   4398   1.974    rillig 		char *suffixes = Suff_NamesStr();
   4399   1.975    rillig 		v = VarNew(FStr_InitRefer(".SUFFIXES"), suffixes,
   4400   1.979    rillig 		    true, false, true);
   4401   1.974    rillig 		free(suffixes);
   4402   1.974    rillig 	} else if (v == NULL)
   4403   1.974    rillig 		v = FindLocalLegacyVar(name, scope, out_true_extraModifiers);
   4404   1.623    rillig 
   4405   1.703    rillig 	if (v == NULL) {
   4406   1.703    rillig 		/*
   4407   1.703    rillig 		 * Defer expansion of dynamic variables if they appear in
   4408   1.802    rillig 		 * non-local scope since they are not defined there.
   4409   1.703    rillig 		 */
   4410   1.972       sjg 		dynamic = VarnameIsDynamic(name) &&
   4411   1.802    rillig 			  (scope == SCOPE_CMDLINE || scope == SCOPE_GLOBAL);
   4412   1.703    rillig 
   4413   1.703    rillig 		if (!haveModifier) {
   4414   1.703    rillig 			p++;	/* skip endc */
   4415   1.896    rillig 			*out_false_pp = p;
   4416  1.1044    rillig 			*out_false_val = EvalUndefined(dynamic, start, p,
   4417  1.1159    rillig 			    name, emode, parseErrorsBefore);
   4418   1.986    rillig 			LazyBuf_Done(&varname);
   4419   1.895    rillig 			return false;
   4420   1.703    rillig 		}
   4421   1.623    rillig 
   4422   1.703    rillig 		/*
   4423  1.1075    rillig 		 * The expression is based on an undefined variable.
   4424   1.703    rillig 		 * Nevertheless it needs a Var, for modifiers that access the
   4425   1.703    rillig 		 * variable name, such as :L or :?.
   4426   1.703    rillig 		 *
   4427   1.703    rillig 		 * Most modifiers leave this expression in the "undefined"
   4428  1.1079    rillig 		 * state (DEF_UNDEF), only a few modifiers like :D, :U, :L,
   4429   1.703    rillig 		 * :P turn this undefined expression into a defined
   4430  1.1079    rillig 		 * expression (DEF_DEFINED).
   4431   1.703    rillig 		 *
   4432   1.830    rillig 		 * In the end, after applying all modifiers, if the expression
   4433   1.703    rillig 		 * is still undefined, Var_Parse will return an empty string
   4434   1.703    rillig 		 * instead of the actually computed value.
   4435   1.703    rillig 		 */
   4436   1.978    rillig 		v = VarNew(LazyBuf_DoneGet(&varname), "",
   4437   1.980    rillig 		    true, false, false);
   4438   1.896    rillig 		*out_true_exprDefined = DEF_UNDEF;
   4439   1.703    rillig 	} else
   4440   1.916    rillig 		LazyBuf_Done(&varname);
   4441   1.623    rillig 
   4442   1.922    rillig 	*pp = p;
   4443   1.896    rillig 	*out_true_endc = endc;
   4444   1.896    rillig 	*out_true_v = v;
   4445   1.896    rillig 	*out_true_haveModifier = haveModifier;
   4446   1.896    rillig 	*out_true_dynamic = dynamic;
   4447   1.895    rillig 	return true;
   4448   1.623    rillig }
   4449   1.623    rillig 
   4450   1.897    rillig #if __STDC_VERSION__ >= 199901L
   4451  1.1079    rillig #define Expr_Init(name, value, emode, scope, defined) \
   4452  1.1079    rillig 	(Expr) { name, value, emode, scope, defined }
   4453   1.897    rillig #else
   4454   1.897    rillig MAKE_INLINE Expr
   4455  1.1079    rillig Expr_Init(const char *name, FStr value,
   4456  1.1079    rillig 	  VarEvalMode emode, GNode *scope, ExprDefined defined)
   4457   1.897    rillig {
   4458   1.897    rillig 	Expr expr;
   4459   1.897    rillig 
   4460   1.898    rillig 	expr.name = name;
   4461   1.897    rillig 	expr.value = value;
   4462   1.917    rillig 	expr.emode = emode;
   4463   1.897    rillig 	expr.scope = scope;
   4464   1.897    rillig 	expr.defined = defined;
   4465   1.897    rillig 	return expr;
   4466   1.897    rillig }
   4467   1.897    rillig #endif
   4468   1.897    rillig 
   4469   1.666    rillig /*
   4470   1.913    rillig  * Expressions of the form ${:U...} with a trivial value are often generated
   4471  1.1079    rillig  * by .for loops and are boring, so evaluate them without debug logging.
   4472   1.913    rillig  */
   4473   1.913    rillig static bool
   4474  1.1106    rillig Var_Parse_U(const char **pp, VarEvalMode emode, FStr *out_value)
   4475   1.913    rillig {
   4476   1.913    rillig 	const char *p;
   4477   1.913    rillig 
   4478   1.913    rillig 	p = *pp;
   4479   1.913    rillig 	if (!(p[0] == '$' && p[1] == '{' && p[2] == ':' && p[3] == 'U'))
   4480   1.913    rillig 		return false;
   4481   1.913    rillig 
   4482   1.913    rillig 	p += 4;
   4483   1.915    rillig 	while (*p != '$' && *p != '{' && *p != ':' && *p != '\\' &&
   4484   1.915    rillig 	       *p != '}' && *p != '\0')
   4485   1.913    rillig 		p++;
   4486   1.913    rillig 	if (*p != '}')
   4487   1.913    rillig 		return false;
   4488   1.913    rillig 
   4489  1.1119    rillig 	*out_value = emode == VARE_PARSE
   4490  1.1093    rillig 	    ? FStr_InitRefer("")
   4491  1.1093    rillig 	    : FStr_InitOwn(bmake_strsedup(*pp + 4, p));
   4492   1.913    rillig 	*pp = p + 1;
   4493   1.913    rillig 	return true;
   4494   1.913    rillig }
   4495   1.913    rillig 
   4496   1.913    rillig /*
   4497  1.1079    rillig  * Given the start of an expression (such as $v, $(VAR), ${VAR:Mpattern}),
   4498  1.1079    rillig  * extract the variable name and the modifiers, if any.  While parsing, apply
   4499  1.1079    rillig  * the modifiers to the value of the expression.
   4500   1.579    rillig  *
   4501   1.108       sjg  * Input:
   4502   1.666    rillig  *	*pp		The string to parse.
   4503  1.1021    rillig  *			When called from CondParser_FuncCallEmpty, it can
   4504  1.1021    rillig  *			also point to the "y" of "empty(VARNAME:Modifiers)".
   4505  1.1079    rillig  *	scope		The scope for finding variables.
   4506  1.1079    rillig  *	emode		Controls the exact details of parsing and evaluation.
   4507   1.666    rillig  *
   4508   1.666    rillig  * Output:
   4509   1.666    rillig  *	*pp		The position where to continue parsing.
   4510   1.666    rillig  *			TODO: After a parse error, the value of *pp is
   4511   1.666    rillig  *			unspecified.  It may not have been updated at all,
   4512   1.666    rillig  *			point to some random character in the string, to the
   4513   1.666    rillig  *			location of the parse error, or at the end of the
   4514   1.666    rillig  *			string.
   4515  1.1075    rillig  *	return		The value of the expression, never NULL.
   4516  1.1042    rillig  *	return		var_Error if there was a parse error.
   4517  1.1042    rillig  *	return		var_Error if the base variable of the expression was
   4518  1.1119    rillig  *			undefined, emode is VARE_EVAL_DEFINED, and none of
   4519   1.666    rillig  *			the modifiers turned the undefined expression into a
   4520   1.666    rillig  *			defined expression.
   4521   1.666    rillig  *			XXX: It is not guaranteed that an error message has
   4522   1.666    rillig  *			been printed.
   4523  1.1042    rillig  *	return		varUndefined if the base variable of the expression
   4524  1.1119    rillig  *			was undefined, emode was not VARE_EVAL_DEFINED,
   4525   1.666    rillig  *			and none of the modifiers turned the undefined
   4526   1.666    rillig  *			expression into a defined expression.
   4527   1.108       sjg  */
   4528  1.1042    rillig FStr
   4529  1.1042    rillig Var_Parse(const char **pp, GNode *scope, VarEvalMode emode)
   4530   1.108       sjg {
   4531  1.1106    rillig 	const char *start, *p;
   4532  1.1021    rillig 	bool haveModifier;	/* true for ${VAR:...}, false for ${VAR} */
   4533  1.1021    rillig 	char startc;		/* the actual '{' or '(' or '\0' */
   4534  1.1021    rillig 	char endc;		/* the expected '}' or ')' or '\0' */
   4535   1.703    rillig 	/*
   4536  1.1021    rillig 	 * true if the expression is based on one of the 7 predefined
   4537  1.1021    rillig 	 * variables that are local to a target, and the expression is
   4538  1.1021    rillig 	 * expanded in a non-local scope.  The result is the text of the
   4539  1.1021    rillig 	 * expression, unaltered.  This is needed to support dynamic sources.
   4540   1.703    rillig 	 */
   4541   1.895    rillig 	bool dynamic;
   4542   1.703    rillig 	const char *extramodifiers;
   4543   1.703    rillig 	Var *v;
   4544  1.1144    rillig 	Expr expr = Expr_Init(NULL, FStr_InitRefer(NULL),
   4545  1.1144    rillig 	    emode == VARE_EVAL_DEFINED || emode == VARE_EVAL_DEFINED_LOUD
   4546  1.1144    rillig 		? VARE_EVAL : emode,
   4547   1.898    rillig 	    scope, DEF_REGULAR);
   4548  1.1042    rillig 	FStr val;
   4549  1.1159    rillig 	int parseErrorsBefore = parseErrors;
   4550   1.703    rillig 
   4551  1.1106    rillig 	if (Var_Parse_U(pp, emode, &val))
   4552  1.1042    rillig 		return val;
   4553   1.913    rillig 
   4554  1.1106    rillig 	p = *pp;
   4555  1.1106    rillig 	start = p;
   4556   1.906    rillig 	DEBUG2(VAR, "Var_Parse: %s (%s)\n", start, VarEvalMode_Name[emode]);
   4557   1.703    rillig 
   4558  1.1042    rillig 	val = FStr_InitRefer(NULL);
   4559   1.703    rillig 	extramodifiers = NULL;	/* extra modifiers to apply first */
   4560   1.895    rillig 	dynamic = false;
   4561   1.473    rillig 
   4562  1.1021    rillig 	endc = '\0';		/* Appease GCC. */
   4563   1.108       sjg 
   4564   1.703    rillig 	startc = p[1];
   4565   1.703    rillig 	if (startc != '(' && startc != '{') {
   4566  1.1042    rillig 		if (!ParseVarnameShort(startc, pp, scope, emode, &val.str, &v))
   4567  1.1042    rillig 			return val;
   4568   1.895    rillig 		haveModifier = false;
   4569   1.703    rillig 		p++;
   4570   1.703    rillig 	} else {
   4571  1.1144    rillig 		if (!ParseVarnameLong(&p, startc, scope, emode, expr.emode,
   4572  1.1159    rillig 		    parseErrorsBefore,
   4573  1.1044    rillig 		    pp, &val,
   4574   1.922    rillig 		    &endc, &v, &haveModifier, &extramodifiers,
   4575   1.825    rillig 		    &dynamic, &expr.defined))
   4576  1.1042    rillig 			return val;
   4577   1.703    rillig 	}
   4578   1.401    rillig 
   4579   1.898    rillig 	expr.name = v->name.str;
   4580  1.1028    rillig 	if (v->inUse && VarEvalMode_ShouldEval(emode)) {
   4581  1.1137    rillig 		Parse_Error(PARSE_FATAL, "Variable %s is recursive.",
   4582  1.1137    rillig 		    v->name.str);
   4583  1.1138    rillig 		FStr_Done(&val);
   4584  1.1138    rillig 		if (*p != '\0')
   4585  1.1138    rillig 			p++;
   4586  1.1138    rillig 		*pp = p;
   4587  1.1138    rillig 		return FStr_InitRefer(var_Error);
   4588  1.1008    rillig 	}
   4589   1.187  christos 
   4590   1.703    rillig 	/*
   4591  1.1078    rillig 	 * FIXME: This assignment creates an alias to the current value of the
   4592   1.703    rillig 	 * variable.  This means that as long as the value of the expression
   4593  1.1078    rillig 	 * stays the same, the value of the variable must not change, and the
   4594  1.1078    rillig 	 * variable must not be deleted.  Using the ':@' modifier, it is
   4595  1.1084    rillig 	 * possible (since var.c 1.212 from 2017-02-01) to delete the variable
   4596  1.1078    rillig 	 * while its value is still being used:
   4597  1.1078    rillig 	 *
   4598  1.1078    rillig 	 *	VAR=	value
   4599  1.1107    rillig 	 *	_:=	${VAR:${:U:@VAR@@}:S,^,prefix,}
   4600  1.1078    rillig 	 *
   4601  1.1078    rillig 	 * The same effect might be achievable using the '::=' or the ':_'
   4602  1.1078    rillig 	 * modifiers.
   4603  1.1021    rillig 	 *
   4604   1.703    rillig 	 * At the bottom of this function, the resulting value is compared to
   4605   1.703    rillig 	 * the then-current value of the variable.  This might also invoke
   4606   1.703    rillig 	 * undefined behavior.
   4607   1.703    rillig 	 */
   4608   1.823    rillig 	expr.value = FStr_InitRefer(v->val.data);
   4609   1.108       sjg 
   4610  1.1133    rillig 	if (!VarEvalMode_ShouldEval(emode))
   4611  1.1133    rillig 		EvalStack_Push(VSK_EXPR_PARSE, start, NULL);
   4612  1.1133    rillig 	else if (expr.name[0] != '\0')
   4613  1.1128    rillig 		EvalStack_Push(VSK_VARNAME, expr.name, &expr.value);
   4614  1.1102    rillig 	else
   4615  1.1132    rillig 		EvalStack_Push(VSK_EXPR, start, &expr.value);
   4616  1.1102    rillig 
   4617   1.703    rillig 	/*
   4618   1.703    rillig 	 * Before applying any modifiers, expand any nested expressions from
   4619   1.703    rillig 	 * the variable value.
   4620   1.703    rillig 	 */
   4621  1.1003    rillig 	if (VarEvalMode_ShouldEval(emode) &&
   4622  1.1003    rillig 	    strchr(Expr_Str(&expr), '$') != NULL) {
   4623   1.743    rillig 		char *expanded;
   4624   1.902    rillig 		v->inUse = true;
   4625  1.1144    rillig 		expanded = Var_Subst(Expr_Str(&expr), scope, expr.emode);
   4626   1.902    rillig 		v->inUse = false;
   4627   1.703    rillig 		/* TODO: handle errors */
   4628   1.823    rillig 		Expr_SetValueOwn(&expr, expanded);
   4629   1.191  dholland 	}
   4630   1.191  dholland 
   4631   1.855    rillig 	if (extramodifiers != NULL) {
   4632   1.855    rillig 		const char *em = extramodifiers;
   4633   1.855    rillig 		ApplyModifiers(&expr, &em, '\0', '\0');
   4634   1.855    rillig 	}
   4635   1.191  dholland 
   4636   1.855    rillig 	if (haveModifier) {
   4637   1.988    rillig 		p++;		/* Skip initial colon. */
   4638   1.855    rillig 		ApplyModifiers(&expr, &p, startc, endc);
   4639   1.191  dholland 	}
   4640   1.438    rillig 
   4641   1.703    rillig 	if (*p != '\0')		/* Skip past endc if possible. */
   4642   1.703    rillig 		p++;
   4643   1.519    rillig 
   4644   1.703    rillig 	*pp = p;
   4645    1.15  christos 
   4646   1.980    rillig 	if (expr.defined == DEF_UNDEF) {
   4647  1.1159    rillig 		Substring varname = Substring_InitStr(expr.name);
   4648  1.1159    rillig 		FStr value = EvalUndefined(dynamic, start, p, varname, emode,
   4649  1.1159    rillig 		    parseErrorsBefore);
   4650  1.1159    rillig 		Expr_SetValue(&expr, value);
   4651   1.980    rillig 	}
   4652   1.980    rillig 
   4653  1.1161    rillig 	EvalStack_Pop();
   4654  1.1161    rillig 
   4655   1.978    rillig 	if (v->shortLived) {
   4656   1.980    rillig 		if (expr.value.str == v->val.data) {
   4657   1.980    rillig 			/* move ownership */
   4658   1.980    rillig 			expr.value.freeIt = v->val.data;
   4659   1.980    rillig 			v->val.data = NULL;
   4660   1.703    rillig 		}
   4661   1.980    rillig 		VarFreeShortLived(v);
   4662    1.34  christos 	}
   4663   1.980    rillig 
   4664  1.1042    rillig 	return expr.value;
   4665     1.1       cgd }
   4666     1.1       cgd 
   4667   1.678    rillig static void
   4668   1.906    rillig VarSubstDollarDollar(const char **pp, Buffer *res, VarEvalMode emode)
   4669   1.768    rillig {
   4670   1.830    rillig 	/* A dollar sign may be escaped with another dollar sign. */
   4671   1.906    rillig 	if (save_dollars && VarEvalMode_ShouldKeepDollar(emode))
   4672   1.768    rillig 		Buf_AddByte(res, '$');
   4673   1.768    rillig 	Buf_AddByte(res, '$');
   4674   1.768    rillig 	*pp += 2;
   4675   1.768    rillig }
   4676   1.768    rillig 
   4677   1.768    rillig static void
   4678  1.1136    rillig VarSubstExpr(const char **pp, Buffer *buf, GNode *scope, VarEvalMode emode)
   4679   1.678    rillig {
   4680   1.703    rillig 	const char *p = *pp;
   4681   1.703    rillig 	const char *nested_p = p;
   4682  1.1042    rillig 	FStr val = Var_Parse(&nested_p, scope, emode);
   4683   1.703    rillig 	/* TODO: handle errors */
   4684   1.678    rillig 
   4685   1.743    rillig 	if (val.str == var_Error || val.str == varUndefined) {
   4686  1.1136    rillig 		if (!VarEvalMode_ShouldKeepUndef(emode)
   4687  1.1136    rillig 		    || val.str == var_Error) {
   4688   1.703    rillig 			p = nested_p;
   4689   1.703    rillig 		} else {
   4690   1.988    rillig 			/*
   4691   1.988    rillig 			 * Copy the initial '$' of the undefined expression,
   4692   1.703    rillig 			 * thereby deferring expansion of the expression, but
   4693   1.988    rillig 			 * expand nested expressions if already possible. See
   4694   1.988    rillig 			 * unit-tests/varparse-undef-partial.mk.
   4695   1.988    rillig 			 */
   4696   1.703    rillig 			Buf_AddByte(buf, *p);
   4697   1.703    rillig 			p++;
   4698   1.703    rillig 		}
   4699   1.678    rillig 	} else {
   4700   1.703    rillig 		p = nested_p;
   4701   1.743    rillig 		Buf_AddStr(buf, val.str);
   4702   1.678    rillig 	}
   4703   1.678    rillig 
   4704   1.743    rillig 	FStr_Done(&val);
   4705   1.678    rillig 
   4706   1.703    rillig 	*pp = p;
   4707   1.678    rillig }
   4708   1.678    rillig 
   4709   1.768    rillig /*
   4710  1.1075    rillig  * Skip as many characters as possible -- either to the end of the string,
   4711  1.1075    rillig  * or to the next dollar sign, which may start an expression.
   4712   1.768    rillig  */
   4713   1.768    rillig static void
   4714   1.768    rillig VarSubstPlain(const char **pp, Buffer *res)
   4715   1.768    rillig {
   4716   1.768    rillig 	const char *p = *pp;
   4717   1.768    rillig 	const char *start = p;
   4718   1.768    rillig 
   4719   1.768    rillig 	for (p++; *p != '$' && *p != '\0'; p++)
   4720   1.768    rillig 		continue;
   4721  1.1055    rillig 	Buf_AddRange(res, start, p);
   4722   1.768    rillig 	*pp = p;
   4723   1.768    rillig }
   4724   1.768    rillig 
   4725   1.778    rillig /*
   4726  1.1075    rillig  * Expand all expressions like $V, ${VAR}, $(VAR:Modifiers) in the
   4727   1.660    rillig  * given string.
   4728     1.1       cgd  *
   4729    1.70       wiz  * Input:
   4730  1.1105    rillig  *	str		The string in which the expressions are expanded.
   4731  1.1105    rillig  *	scope		The scope in which to start searching for variables.
   4732  1.1105    rillig  *			The other scopes are searched as well.
   4733   1.917    rillig  *	emode		The mode for parsing or evaluating subexpressions.
   4734     1.1       cgd  */
   4735  1.1043    rillig char *
   4736  1.1043    rillig Var_Subst(const char *str, GNode *scope, VarEvalMode emode)
   4737     1.1       cgd {
   4738   1.703    rillig 	const char *p = str;
   4739   1.703    rillig 	Buffer res;
   4740     1.1       cgd 
   4741   1.703    rillig 	Buf_Init(&res);
   4742   1.703    rillig 
   4743   1.703    rillig 	while (*p != '\0') {
   4744   1.768    rillig 		if (p[0] == '$' && p[1] == '$')
   4745   1.906    rillig 			VarSubstDollarDollar(&p, &res, emode);
   4746   1.768    rillig 		else if (p[0] == '$')
   4747  1.1136    rillig 			VarSubstExpr(&p, &res, scope, emode);
   4748   1.768    rillig 		else
   4749   1.768    rillig 			VarSubstPlain(&p, &res);
   4750     1.1       cgd 	}
   4751    1.15  christos 
   4752  1.1108    rillig 	return Buf_DoneData(&res);
   4753     1.1       cgd }
   4754     1.1       cgd 
   4755  1.1120    rillig char *
   4756  1.1120    rillig Var_SubstInTarget(const char *str, GNode *scope)
   4757  1.1120    rillig {
   4758  1.1120    rillig 	char *res;
   4759  1.1128    rillig 	EvalStack_Push(VSK_TARGET, scope->name, NULL);
   4760  1.1146    rillig 	EvalStack_Push(VSK_COMMAND, str, NULL);
   4761  1.1120    rillig 	res = Var_Subst(str, scope, VARE_EVAL);
   4762  1.1120    rillig 	EvalStack_Pop();
   4763  1.1146    rillig 	EvalStack_Pop();
   4764  1.1120    rillig 	return res;
   4765  1.1120    rillig }
   4766  1.1120    rillig 
   4767  1.1001    rillig void
   4768  1.1001    rillig Var_Expand(FStr *str, GNode *scope, VarEvalMode emode)
   4769  1.1001    rillig {
   4770  1.1001    rillig 	char *expanded;
   4771  1.1001    rillig 
   4772  1.1001    rillig 	if (strchr(str->str, '$') == NULL)
   4773  1.1001    rillig 		return;
   4774  1.1043    rillig 	expanded = Var_Subst(str->str, scope, emode);
   4775  1.1001    rillig 	/* TODO: handle errors */
   4776  1.1001    rillig 	FStr_Done(str);
   4777  1.1001    rillig 	*str = FStr_InitOwn(expanded);
   4778  1.1001    rillig }
   4779  1.1001    rillig 
   4780   1.286       sjg void
   4781   1.286       sjg Var_Stats(void)
   4782   1.286       sjg {
   4783   1.802    rillig 	HashTable_DebugStats(&SCOPE_GLOBAL->vars, "Global variables");
   4784     1.1       cgd }
   4785    1.15  christos 
   4786   1.964    rillig static int
   4787   1.964    rillig StrAsc(const void *sa, const void *sb)
   4788   1.964    rillig {
   4789   1.964    rillig 	return strcmp(
   4790   1.964    rillig 	    *((const char *const *)sa), *((const char *const *)sb));
   4791   1.964    rillig }
   4792   1.964    rillig 
   4793   1.964    rillig 
   4794   1.802    rillig /* Print all variables in a scope, sorted by name. */
   4795     1.5       cgd void
   4796   1.802    rillig Var_Dump(GNode *scope)
   4797     1.1       cgd {
   4798   1.703    rillig 	Vector /* of const char * */ vec;
   4799   1.703    rillig 	HashIter hi;
   4800   1.703    rillig 	size_t i;
   4801   1.703    rillig 	const char **varnames;
   4802   1.703    rillig 
   4803   1.703    rillig 	Vector_Init(&vec, sizeof(const char *));
   4804   1.703    rillig 
   4805   1.802    rillig 	HashIter_Init(&hi, &scope->vars);
   4806  1.1114    rillig 	while (HashIter_Next(&hi))
   4807   1.703    rillig 		*(const char **)Vector_Push(&vec) = hi.entry->key;
   4808   1.703    rillig 	varnames = vec.items;
   4809   1.703    rillig 
   4810   1.964    rillig 	qsort(varnames, vec.len, sizeof varnames[0], StrAsc);
   4811   1.703    rillig 
   4812   1.703    rillig 	for (i = 0; i < vec.len; i++) {
   4813   1.703    rillig 		const char *varname = varnames[i];
   4814  1.1035    rillig 		const Var *var = HashTable_FindValue(&scope->vars, varname);
   4815  1.1018    rillig 		debug_printf("%-16s = %s%s\n", varname,
   4816  1.1018    rillig 		    var->val.data, ValueDescription(var->val.data));
   4817   1.703    rillig 	}
   4818   1.573    rillig 
   4819   1.703    rillig 	Vector_Done(&vec);
   4820     1.1       cgd }
   4821