aboutsummaryrefslogtreecommitdiff
path: root/var.c
diff options
context:
space:
mode:
Diffstat (limited to 'var.c')
-rw-r--r--var.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/var.c b/var.c
index 09ae6744e001..e6f748f04fa7 100644
--- a/var.c
+++ b/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.1173 2025/11/12 22:14:07 sjg Exp $ */
+/* $NetBSD: var.c,v 1.1179 2026/03/13 04:22:03 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -93,7 +93,9 @@
* Var_Value Return the unexpanded value of a variable, or NULL if
* the variable is undefined.
*
- * Var_Subst Substitute all expressions in a string.
+ * Var_Subst Copy a string, expanding expressions on the way.
+ *
+ * Var_Expand Expand all expressions in a string, in-place.
*
* Var_Parse Parse an expression such as ${VAR:Mpattern}.
*
@@ -143,7 +145,7 @@
#endif
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.1173 2025/11/12 22:14:07 sjg Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.1179 2026/03/13 04:22:03 sjg Exp $");
/*
* Variables are defined using one of the VAR=value assignments. Their
@@ -319,31 +321,26 @@ static char varUndefined[] = "";
* Traditionally this make consumed $$ during := like any other expansion.
* Other make's do not, and this make follows straight since 2016-01-09.
*
- * This knob allows controlling the behavior:
+ * This knob (.MAKE.SAVE_DOLLARS) allows controlling the behavior:
* false to consume $$ during := assignment.
* true to preserve $$ during := assignment.
*/
-#define MAKE_SAVE_DOLLARS ".MAKE.SAVE_DOLLARS"
static bool save_dollars = false;
/*
* A scope collects variable names and their values.
*
- * The main scope is SCOPE_GLOBAL, which contains the variables that are set
- * in the makefiles. SCOPE_INTERNAL acts as a fallback for SCOPE_GLOBAL and
- * contains some internal make variables. These internal variables can thus
- * be overridden, they can also be restored by undefining the overriding
- * variable.
+ * Each target has its own scope, containing the 7 target-local variables
+ * .TARGET, .ALLSRC, etc. Variables set on dependency lines also go in
+ * this scope.
*
* SCOPE_CMDLINE contains variables from the command line arguments. These
* override variables from SCOPE_GLOBAL.
*
+ * SCOPE_GLOBAL contains the variables that are set in the makefiles.
+ *
* There is no scope for environment variables, these are generated on-the-fly
* whenever they are referenced.
- *
- * Each target has its own scope, containing the 7 target-local variables
- * .TARGET, .ALLSRC, etc. Variables set on dependency lines also go in
- * this scope.
*/
GNode *SCOPE_CMDLINE;
@@ -415,6 +412,7 @@ EvalStack_Details(Buffer *buf)
const char* value = elem->value != NULL
&& (kind == VSK_VARNAME || kind == VSK_EXPR)
? elem->value->str : NULL;
+ const GNode *gn;
Buf_AddStr(buf, "\t");
Buf_AddStr(buf, descr[kind]);
@@ -424,7 +422,16 @@ EvalStack_Details(Buffer *buf)
Buf_AddStr(buf, "\" with value \"");
Buf_AddStr(buf, value);
}
- Buf_AddStr(buf, "\"\n");
+ if (kind == VSK_TARGET
+ && (gn = Targ_FindNode(elem->str)) != NULL
+ && gn->fname != NULL) {
+ Buf_AddStr(buf, "\" from ");
+ Buf_AddStr(buf, gn->fname);
+ Buf_AddStr(buf, ":");
+ Buf_AddInt(buf, (int)gn->lineno);
+ Buf_AddStr(buf, "\n");
+ } else
+ Buf_AddStr(buf, "\"\n");
}
return evalStack.len > 0;
}
@@ -1282,12 +1289,8 @@ Var_Exists(GNode *scope, const char *name)
}
/*
- * See if the given variable exists, in the given scope or in other
- * fallback scopes.
- *
- * Input:
- * scope scope in which to start search
- * name name of the variable to find, is expanded once
+ * See if the given variable exists, in the given scope or in other fallback
+ * scopes. The variable name is expanded once.
*/
bool
Var_ExistsExpand(GNode *scope, const char *name)
@@ -2138,12 +2141,12 @@ typedef enum ApplyModifierResult {
* backslashes.
*/
static bool
-IsEscapedModifierPart(const char *p, char end1, char end2,
+IsEscapedModifierPart(const char *p, char delim1, char delim2,
struct ModifyWord_SubstArgs *subst)
{
if (p[0] != '\\' || p[1] == '\0')
return false;
- if (p[1] == end1 || p[1] == end2 || p[1] == '\\' || p[1] == '$')
+ if (p[1] == delim1 || p[1] == delim2 || p[1] == '\\' || p[1] == '$')
return true;
return p[1] == '&' && subst != NULL;
}
@@ -2224,10 +2227,10 @@ ParseModifierPart(
* For the first part of the ':S' modifier, set anchorEnd if the last
* character of the pattern is a $.
*/
- PatternFlags *out_pflags,
+ PatternFlags *pflags,
/*
- * For the second part of the ':S' modifier, allow ampersands to be
- * escaped and replace unescaped ampersands with subst->lhs.
+ * For the second part of the ':S' modifier, allow '&' to be
+ * escaped and replace each unescaped '&' with subst->lhs.
*/
struct ModifyWord_SubstArgs *subst
)
@@ -2246,8 +2249,8 @@ ParseModifierPart(
LazyBuf_Add(part, *p);
p++;
} else if (p[1] == end2) { /* Unescaped '$' at end */
- if (out_pflags != NULL)
- out_pflags->anchorEnd = true;
+ if (pflags != NULL)
+ pflags->anchorEnd = true;
else
LazyBuf_Add(part, *p);
p++;
@@ -3044,9 +3047,16 @@ ApplyModifier_Regex(const char **pp, ModChain *ch)
if (!ModChain_ShouldEval(ch))
goto done;
+ if (re.str[0] == '\0') {
+ /* not all regcomp() fail on this */
+ Parse_Error(PARSE_FATAL, "Regex compilation error: empty");
+ goto re_err;
+ }
+
error = regcomp(&args.re, re.str, REG_EXTENDED);
if (error != 0) {
RegexError(error, &args.re, "Regex compilation error");
+ re_err:
LazyBuf_Done(&replaceBuf);
FStr_Done(&re);
return AMR_CLEANUP;
@@ -3829,7 +3839,7 @@ ApplyModifier_SunShell1(const char **pp, ModChain *ch)
v = VarFind(cache_varname, SCOPE_GLOBAL, false);
if (v == NULL) {
char *output, *error;
-
+
output = Cmd_Exec(Expr_Str(expr), &error);
if (error != NULL) {
Parse_Error(PARSE_WARNING, "%s", error);
@@ -3846,7 +3856,7 @@ ApplyModifier_SunShell1(const char **pp, ModChain *ch)
return AMR_OK;
}
-
+
/*
* In cases where the evaluation mode and the definedness are the "standard"