summaryrefslogtreecommitdiffstats
path: root/usr.bin/make/var.c
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2005-05-09 14:06:04 +0000
committerharti <harti@FreeBSD.org>2005-05-09 14:06:04 +0000
commitef37b341c376efaab6437df4baf8531dd11eb641 (patch)
tree5aba5fcd4ee95bf72b4b360ea351bf814500ce84 /usr.bin/make/var.c
parent7993c4292d145a1c61b5465ce3735a8c9b867e3f (diff)
downloadFreeBSD-src-ef37b341c376efaab6437df4baf8531dd11eb641.zip
FreeBSD-src-ef37b341c376efaab6437df4baf8531dd11eb641.tar.gz
Split Var_Subst() into two functions: Var_SubstOnly() which substitutes
only one variable and Var_Subst() which substitutes all. Split out the test whether a variable should not be expanded into match_var(). Make access to the input string consistently using str[]. Remove two unused functions: Var_GetTail() and Var_GetHead(). Patches: 7.184-7.189 Submitted by: Max Okumoto <okumoto@ucsd.edu>
Diffstat (limited to 'usr.bin/make/var.c')
-rw-r--r--usr.bin/make/var.c292
1 files changed, 152 insertions, 140 deletions
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c
index 6be737c..cb62da7 100644
--- a/usr.bin/make/var.c
+++ b/usr.bin/make/var.c
@@ -222,7 +222,7 @@ VarPossiblyExpand(const char *name, GNode *ctxt)
Buffer *buf;
if (strchr(name, '$') != NULL) {
- buf = Var_Subst(NULL, name, ctxt, 0);
+ buf = Var_Subst(name, ctxt, 0);
return (Buf_Peel(buf));
} else {
return estrdup(name);
@@ -882,7 +882,7 @@ VarExpand(Var *v, VarParser *vp)
} else {
Buffer *buf;
- buf = Var_Subst(NULL, value, vp->ctxt, vp->err);
+ buf = Var_Subst(value, vp->ctxt, vp->err);
result = Buf_Peel(buf);
}
@@ -1715,9 +1715,9 @@ Var_Parse(const char input[], GNode *ctxt, Boolean err,
*-----------------------------------------------------------------------
*/
Buffer *
-Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean err)
+Var_Subst(const char *str, GNode *ctxt, Boolean err)
{
- Boolean errorReported;
+ Boolean errorReported;
Buffer *buf; /* Buffer for forming things */
/*
@@ -1728,89 +1728,21 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean err)
errorReported = FALSE;
buf = Buf_Init(0);
- while (*str) {
- if (var == NULL && (str[0] == '$') && (str[1] == '$')) {
+ while (str[0] != '\0') {
+ if ((str[0] == '$') && (str[1] == '$')) {
/*
- * A dollar sign may be escaped either with another
- * dollar sign. In such a case, we skip over the
- * escape character and store the dollar sign into
- * the buffer directly.
+ * A dollar sign may be escaped with another dollar
+ * sign. In such a case, we skip over the escape
+ * character and store the dollar sign into the
+ * buffer directly.
*/
+ str++;
Buf_AddByte(buf, (Byte)str[0]);
- str += 2;
+ str++;
} else if (str[0] == '$') {
- /*
- * Variable invocation.
- */
- if (var != NULL) {
- int expand;
- for (;;) {
- if (str[1] == OPEN_PAREN || str[1] == OPEN_BRACE) {
- size_t ln;
- const char *p = str + 2;
-
- /*
- * Scan up to the end of the
- * variable name.
- */
- while (*p != '\0' &&
- *p != ':' &&
- *p != CLOSE_PAREN &&
- *p != CLOSE_BRACE &&
- *p != '$') {
- ++p;
- }
-
- /*
- * A variable inside the
- * variable. We cannot expand
- * the external variable yet,
- * so we try again with the
- * nested one
- */
- if (*p == '$') {
- Buf_AppendRange(buf, str, p);
- str = p;
- continue;
- }
- ln = p - (str + 2);
- if (var[ln] == '\0' && strncmp(var, str + 2, ln) == 0) {
- expand = TRUE;
- } else {
- /*
- * Not the variable
- * we want to expand,
- * scan until the
- * next variable
- */
- while (*p != '$' && *p != '\0')
- p++;
-
- Buf_AppendRange(buf, str, p);
- str = p;
- expand = FALSE;
- }
- } else {
- /*
- * Single letter variable
- * name
- */
- if (var[1] == '\0' && var[0] == str[1]) {
- expand = TRUE;
- } else {
- Buf_AddBytes(buf, 2, (const Byte *) str);
- str += 2;
- expand = FALSE;
- }
- }
- break;
- }
- if (!expand)
- continue;
- }
- {
- VarParser subvp = {
+ /* Variable invocation. */
+ VarParser subvp = {
str,
str,
ctxt,
@@ -1849,21 +1781,14 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean err)
Parse_Error(PARSE_FATAL,
"Undefined variable \"%.*s\"", subvp.ptr - subvp.input, str);
}
- str = subvp.ptr;
errorReported = TRUE;
+ str = subvp.ptr;
} else {
- Buf_AddByte(buf, (Byte)*str);
- str += 1;
+ Buf_AddByte(buf, (Byte)str[0]);
+ str++;
}
} else {
/*
- * We've now got a variable structure to
- * store in. But first, advance the string
- * pointer.
- */
- str = subvp.ptr;
-
- /*
* Copy all the characters from the variable
* value straight into the new string.
*/
@@ -1871,68 +1796,155 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean err)
if (rfree) {
free(rval);
}
+ str = subvp.ptr;
}
- }
} else {
- /*
- * Skip as many characters as possible -- either to
- * the end of the string or to the next dollar sign
- * (variable invocation).
- */
- const char *cp = str;
-
- do {
- str++;
- } while (str[0] != '$' && str[0] != '\0');
-
- Buf_AppendRange(buf, cp, str);
+ Buf_AddByte(buf, (Byte)str[0]);
+ str++;
}
}
return (buf);
}
-/*-
- *-----------------------------------------------------------------------
- * Var_GetTail --
- * Return the tail from each of a list of words. Used to set the
- * System V local variables.
- *
- * Results:
- * The resulting string.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-char *
-Var_GetTail(char *file)
+static int
+match_var(const char str[], const char var[])
{
+ const char *start = str;
+ size_t len;
+
+ str++; /* consume '$' */
- return (VarModify(file, VarTail, (void *)NULL));
+ if (str[0] == OPEN_PAREN || str[0] == OPEN_BRACE) {
+ str++; /* consume opening paren or brace */
+
+ while (str[0] != '\0') {
+ if (str[0] == '$') {
+ /*
+ * A variable inside the variable. We cannot
+ * expand the external variable yet.
+ */
+ return (str - start);
+ } else if (str[0] == ':' ||
+ str[0] == CLOSE_PAREN ||
+ str[0] == CLOSE_BRACE) {
+ len = str - (start + 2);
+
+ if (var[len] == '\0' && strncmp(var, start + 2, len) == 0) {
+ return (0); /* match */
+ } else {
+ /*
+ * Not the variable we want to
+ * expand.
+ */
+ return (str - start);
+ }
+ } else {
+ ++str;
+ }
+ }
+ return (str - start);
+ } else {
+ /* Single letter variable name */
+ if (var[1] == '\0' && var[0] == str[0]) {
+ return (0); /* match */
+ } else {
+ str++; /* consume variable name */
+ return (str - start);
+ }
+ }
}
-/*-
- *-----------------------------------------------------------------------
- * Var_GetHead --
- * Find the leading components of a (list of) filename(s).
- * XXX: VarHead does not replace foo by ., as (sun) System V make
- * does.
- *
- * Results:
- * The leading components.
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-char *
-Var_GetHead(char *file)
+Buffer *
+Var_SubstOnly(const char *var, const char *str, GNode *ctxt, Boolean err)
{
+ Boolean errorReported;
+ Buffer *buf; /* Buffer for forming things */
- return (VarModify(file, VarHead, (void *)NULL));
+ /*
+ * Set TRUE if an error has already been reported to prevent a
+ * plethora of messages when recursing. XXXHB this comment sounds
+ * wrong.
+ */
+ errorReported = FALSE;
+
+ buf = Buf_Init(0);
+ while (str[0] != '\0') {
+ if (str[0] == '$') {
+ int skip;
+
+ skip = match_var(str, var);
+ if (skip > 0) {
+ Buf_AddBytes(buf, skip, str);
+ str += skip;
+ } else {
+ /* Variable invocation. */
+ VarParser subvp = {
+ str,
+ str,
+ ctxt,
+ err
+ };
+ char *rval;
+ Boolean rfree;
+
+ rval = VarParse(&subvp, &rfree);
+
+ /*
+ * When we get down here, rval should either
+ * point to the value of this variable, or be
+ * NULL.
+ */
+ if (rval == var_Error || rval == varNoError) {
+ /*
+ * If performing old-time variable
+ * substitution, skip over the
+ * variable and continue with the
+ * substitution. Otherwise, store the
+ * dollar sign and advance str so we
+ * continue with the string...
+ */
+ if (oldVars) {
+ str = subvp.ptr;
+ } else if (err) {
+ /*
+ * If variable is undefined,
+ * complain and skip the
+ * variable. The complaint
+ * will stop us from doing
+ * anything when the file is
+ * parsed.
+ */
+ if (!errorReported) {
+ Parse_Error(PARSE_FATAL,
+ "Undefined variable \"%.*s\"", subvp.ptr - subvp.input, str);
+ }
+ errorReported = TRUE;
+ str = subvp.ptr;
+ } else {
+ Buf_AddByte(buf, (Byte)str[0]);
+ str++;
+ }
+ } else {
+ /*
+ * Copy all the characters from the
+ * variable value straight into the
+ * new string.
+ */
+ Buf_Append(buf, rval);
+ if (rfree) {
+ free(rval);
+ }
+ str = subvp.ptr;
+ }
+ }
+ } else {
+ Buf_AddByte(buf, (Byte)str[0]);
+ str++;
+ }
+ }
+
+ return (buf);
}
/*-
OpenPOWER on IntegriCloud