summaryrefslogtreecommitdiff
path: root/devel/bmake/files/var.c
diff options
context:
space:
mode:
authorjoerg <joerg@pkgsrc.org>2009-09-18 20:55:21 +0000
committerjoerg <joerg@pkgsrc.org>2009-09-18 20:55:21 +0000
commit1869e779310e24b43754c694c616566fa8eca3d7 (patch)
tree46c780c45309611e0cafd1ae55a8046d1a4b07eb /devel/bmake/files/var.c
parentb952f7758718bf9fea8dc11ba8a00727a9a8cc6f (diff)
downloadpkgsrc-1869e779310e24b43754c694c616566fa8eca3d7.tar.gz
Import bmake-20090909:
- .MAKE.LEVEL, -C, SIGINFO support - fixes for :M and \: - vfork signal handling fixes e.g. for Solaris
Diffstat (limited to 'devel/bmake/files/var.c')
-rw-r--r--devel/bmake/files/var.c824
1 files changed, 418 insertions, 406 deletions
diff --git a/devel/bmake/files/var.c b/devel/bmake/files/var.c
index 1df6a575405..9744fae5747 100644
--- a/devel/bmake/files/var.c
+++ b/devel/bmake/files/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.1.1.4 2008/11/11 19:32:29 joerg Exp $ */
+/* $NetBSD: var.c,v 1.1.1.5 2009/09/18 20:55:32 joerg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.1.1.4 2008/11/11 19:32:29 joerg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.1.1.5 2009/09/18 20:55:32 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: var.c,v 1.1.1.4 2008/11/11 19:32:29 joerg Exp $");
+__RCSID("$NetBSD: var.c,v 1.1.1.5 2009/09/18 20:55:32 joerg Exp $");
#endif
#endif /* not lint */
#endif
@@ -86,31 +86,31 @@ __RCSID("$NetBSD: var.c,v 1.1.1.4 2008/11/11 19:32:29 joerg Exp $");
* Variable-handling functions
*
* Interface:
- * Var_Set Set the value of a variable in the given
- * context. The variable is created if it doesn't
- * yet exist. The value and variable name need not
- * be preserved.
+ * Var_Set Set the value of a variable in the given
+ * context. The variable is created if it doesn't
+ * yet exist. The value and variable name need not
+ * be preserved.
*
* Var_Append Append more characters to an existing variable
- * in the given context. The variable needn't
- * exist already -- it will be created if it doesn't.
- * A space is placed between the old value and the
- * new one.
+ * in the given context. The variable needn't
+ * exist already -- it will be created if it doesn't.
+ * A space is placed between the old value and the
+ * new one.
*
* Var_Exists See if a variable exists.
*
* Var_Value Return the value of a variable in a context or
- * NULL if the variable is undefined.
+ * NULL if the variable is undefined.
*
* Var_Subst Substitute named variable, or all variables if
* NULL in a string using
- * the given context as the top-most one. If the
- * third argument is non-zero, Parse_Error is
- * called if any variables are undefined.
+ * the given context as the top-most one. If the
+ * third argument is non-zero, Parse_Error is
+ * called if any variables are undefined.
*
* Var_Parse Parse a variable expansion from a string and
- * return the result and the number of characters
- * consumed.
+ * return the result and the number of characters
+ * consumed.
*
* Var_Delete Delete a variable in a context.
*
@@ -118,7 +118,7 @@ __RCSID("$NetBSD: var.c,v 1.1.1.4 2008/11/11 19:32:29 joerg Exp $");
*
* Debugging:
* Var_Dump Print out all variables defined in the given
- * context.
+ * context.
*
* XXX: There's a lot of duplication in these functions.
*/
@@ -175,8 +175,8 @@ GNode *VAR_CMD; /* variables defined on the command-line */
typedef struct Var {
char *name; /* the variable's name */
- Buffer val; /* its value */
- int flags; /* miscellaneous status flags */
+ Buffer val; /* its value */
+ int flags; /* miscellaneous status flags */
#define VAR_IN_USE 1 /* Variable's value currently being used.
* Used to avoid recursion */
#define VAR_FROM_ENV 2 /* Variable comes from the environment */
@@ -205,7 +205,7 @@ static int var_exportedVars = VAR_EXPORTED_NONE;
* We pass this to Var_Export when doing the initial export
* or after updating an exported var.
*/
-#define VAR_EXPORT_FORCE 1
+#define VAR_EXPORT_PARENT 1
/* Var*Pattern flags */
#define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */
@@ -232,28 +232,28 @@ typedef struct {
* several space-separated words). */
} Var_Parse_State;
-/* struct passed as ClientData to VarSubstitute() for ":S/lhs/rhs/",
+/* struct passed as 'void *' to VarSubstitute() for ":S/lhs/rhs/",
* to VarSYSVMatch() for ":lhs=rhs". */
typedef struct {
const char *lhs; /* String to match */
- int leftLen; /* Length of string */
+ int leftLen; /* Length of string */
const char *rhs; /* Replacement string (w/ &'s removed) */
- int rightLen; /* Length of replacement */
- int flags;
+ int rightLen; /* Length of replacement */
+ int flags;
} VarPattern;
-/* struct passed as ClientData to VarLoopExpand() for ":@tvar@str@" */
+/* struct passed as 'void *' to VarLoopExpand() for ":@tvar@str@" */
typedef struct {
GNode *ctxt; /* variable context */
char *tvar; /* name of temp var */
- int tvarLen;
+ int tvarLen;
char *str; /* string to expand */
- int strLen;
+ int strLen;
int errnum; /* errnum for not defined */
} VarLoop_t;
#ifndef NO_REGEX
-/* struct passed as ClientData to VarRESubstitute() for ":C///" */
+/* struct passed as 'void *' to VarRESubstitute() for ":C///" */
typedef struct {
regex_t re;
int nsub;
@@ -272,30 +272,30 @@ typedef struct {
static Var *VarFind(const char *, GNode *, int);
static void VarAdd(const char *, const char *, GNode *);
static Boolean VarHead(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
static Boolean VarTail(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
static Boolean VarSuffix(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
static Boolean VarRoot(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
static Boolean VarMatch(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
#ifdef SYSVVARSUB
static Boolean VarSYSVMatch(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
#endif
static Boolean VarNoMatch(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
#ifndef NO_REGEX
static void VarREError(int, regex_t *, const char *);
static Boolean VarRESubstitute(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
#endif
static Boolean VarSubstitute(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
static Boolean VarLoopExpand(GNode *, Var_Parse_State *,
- char *, Boolean, Buffer, ClientData);
+ char *, Boolean, Buffer *, void *);
static char *VarGetPattern(GNode *, Var_Parse_State *,
int, const char **, int, int *, int *,
VarPattern *);
@@ -303,12 +303,12 @@ static char *VarQuote(char *);
static char *VarChangeCase(char *, int);
static char *VarModify(GNode *, Var_Parse_State *,
const char *,
- Boolean (*)(GNode *, Var_Parse_State *, char *, Boolean, Buffer, ClientData),
- ClientData);
+ Boolean (*)(GNode *, Var_Parse_State *, char *, Boolean, Buffer *, void *),
+ void *);
static char *VarOrder(const char *, const char);
static char *VarUniq(const char *);
static int VarWordCompare(const void *, const void *);
-static void VarPrintVar(ClientData);
+static void VarPrintVar(void *);
#define BROPEN '{'
#define BRCLOSE '}'
@@ -331,7 +331,7 @@ static void VarPrintVar(ClientData);
*
* Results:
* A pointer to the structure describing the desired variable or
- * NIL if the variable does not exist.
+ * NULL if the variable does not exist.
*
* Side Effects:
* None
@@ -341,7 +341,7 @@ static Var *
VarFind(const char *name, GNode *ctxt, int flags)
{
Hash_Entry *var;
- Var *v;
+ Var *v;
/*
* If the variable name begins with a '.', it could very well be one of
@@ -397,15 +397,15 @@ VarFind(const char *name, GNode *ctxt, int flags)
char *env;
if ((env = getenv(name)) != NULL) {
- int len;
+ int len;
v = bmake_malloc(sizeof(Var));
v->name = bmake_strdup(name);
len = strlen(env);
- v->val = Buf_Init(len + 1);
- Buf_AddBytes(v->val, len, (Byte *)env);
+ Buf_Init(&v->val, len + 1);
+ Buf_AddBytes(&v->val, len, env);
v->flags = VAR_FROM_ENV;
return (v);
@@ -414,15 +414,15 @@ VarFind(const char *name, GNode *ctxt, int flags)
{
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
if (var == NULL) {
- return ((Var *)NIL);
+ return NULL;
} else {
return ((Var *)Hash_GetValue(var));
}
} else {
- return((Var *)NIL);
+ return NULL;
}
} else if (var == NULL) {
- return ((Var *)NIL);
+ return NULL;
} else {
return ((Var *)Hash_GetValue(var));
}
@@ -450,7 +450,7 @@ VarFreeEnv(Var *v, Boolean destroy)
if ((v->flags & VAR_FROM_ENV) == 0)
return FALSE;
free(v->name);
- Buf_Destroy(v->val, destroy);
+ Buf_Destroy(&v->val, destroy);
free(v);
return TRUE;
}
@@ -478,14 +478,14 @@ static void
VarAdd(const char *name, const char *val, GNode *ctxt)
{
Var *v;
- int len;
+ int len;
Hash_Entry *h;
v = bmake_malloc(sizeof(Var));
len = val ? strlen(val) : 0;
- v->val = Buf_Init(len+1);
- Buf_AddBytes(v->val, len, (const Byte *)val);
+ Buf_Init(&v->val, len+1);
+ Buf_AddBytes(&v->val, len, val);
v->flags = 0;
@@ -530,7 +530,7 @@ Var_Delete(const char *name, GNode *ctxt)
if (v->name != ln->name)
free(v->name);
Hash_DeleteEntry(&ctxt->context, ln);
- Buf_Destroy(v->val, TRUE);
+ Buf_Destroy(&v->val, TRUE);
free(v);
}
}
@@ -541,9 +541,10 @@ Var_Delete(const char *name, GNode *ctxt)
* We ignore make internal variables (those which start with '.')
* Also we jump through some hoops to avoid calling setenv
* more than necessary since it can leak.
+ * We only manipulate flags of vars if 'parent' is set.
*/
static int
-Var_Export1(const char *name, int force)
+Var_Export1(const char *name, int parent)
{
char tmp[BUFSIZ];
Var *v;
@@ -568,40 +569,44 @@ Var_Export1(const char *name, int force)
}
}
v = VarFind(name, VAR_GLOBAL, 0);
- if (v == (Var *)NIL) {
+ if (v == NULL) {
return 0;
}
- if (!force &&
+ if (!parent &&
(v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
return 0; /* nothing to do */
}
- val = (char *)Buf_GetAll(v->val, NULL);
+ val = Buf_GetAll(&v->val, NULL);
if (strchr(val, '$')) {
- /* Flag this as something we need to re-export */
- v->flags |= (VAR_EXPORTED|VAR_REEXPORT);
- if (force) {
+ if (parent) {
/*
+ * Flag this as something we need to re-export.
* No point actually exporting it now though,
* the child can do it at the last minute.
*/
+ v->flags |= (VAR_EXPORTED|VAR_REEXPORT);
return 1;
}
n = snprintf(tmp, sizeof(tmp), "${%s}", name);
- if (n < sizeof(tmp)) {
+ if (n < (int)sizeof(tmp)) {
val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
setenv(name, val, 1);
free(val);
}
} else {
- v->flags &= ~VAR_REEXPORT; /* once will do */
- if (force || !(v->flags & VAR_EXPORTED)) {
+ if (parent) {
+ v->flags &= ~VAR_REEXPORT; /* once will do */
+ }
+ if (parent || !(v->flags & VAR_EXPORTED)) {
setenv(name, val, 1);
}
}
/*
* This is so Var_Set knows to call Var_Export again...
*/
- v->flags |= VAR_EXPORTED;
+ if (parent) {
+ v->flags |= VAR_EXPORTED;
+ }
return 1;
}
@@ -637,12 +642,12 @@ Var_ExportVars(void)
* We have a number of exported vars,
*/
n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
- if (n < sizeof(tmp)) {
+ if (n < (int)sizeof(tmp)) {
char **av;
char *as;
int ac;
int i;
-
+
val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
av = brk_string(val, &ac, FALSE, &as);
for (i = 0; i < ac; i++) {
@@ -693,7 +698,7 @@ Var_Export(char *str, int isExport)
continue;
}
}
- if (Var_Export1(name, VAR_EXPORT_FORCE)) {
+ if (Var_Export1(name, VAR_EXPORT_PARENT)) {
if (VAR_EXPORTED_ALL != var_exportedVars)
var_exportedVars = VAR_EXPORTED_YES;
if (isExport) {
@@ -738,20 +743,29 @@ void
Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
{
Var *v;
- const char *cp = name;
-
+ char *expanded_name = NULL;
+
/*
* We only look for a variable in the given context since anything set
* here will override anything in a lower context, so there's not much
* point in searching them all just to save a bit of memory...
*/
- if ((name = strchr(cp, '$'))) {
- name = Var_Subst(NULL, cp, ctxt, 0);
- } else
- name = cp;
+ if (strchr(name, '$') != NULL) {
+ expanded_name = Var_Subst(NULL, name, ctxt, 0);
+ if (expanded_name[0] == 0) {
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) "
+ "name expands to empty string - ignored\n",
+ name, val);
+ }
+ free(expanded_name);
+ return;
+ }
+ name = expanded_name;
+ }
if (ctxt == VAR_GLOBAL) {
v = VarFind(name, VAR_CMD, 0);
- if (v != (Var *)NIL) {
+ if (v != NULL) {
if ((v->flags & VAR_FROM_CMD)) {
if (DEBUG(VAR)) {
fprintf(debug_file, "%s:%s = %s ignored!\n", ctxt->name, name, val);
@@ -762,17 +776,17 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
}
}
v = VarFind(name, ctxt, 0);
- if (v == (Var *)NIL) {
+ if (v == NULL) {
VarAdd(name, val, ctxt);
} else {
- Buf_Discard(v->val, Buf_Size(v->val));
- Buf_AddBytes(v->val, strlen(val), (const Byte *)val);
+ Buf_Empty(&v->val);
+ Buf_AddBytes(&v->val, strlen(val), val);
if (DEBUG(VAR)) {
fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
}
if ((v->flags & VAR_EXPORTED)) {
- Var_Export1(name, VAR_EXPORT_FORCE);
+ Var_Export1(name, VAR_EXPORT_PARENT);
}
}
/*
@@ -780,11 +794,12 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
* to the environment (as per POSIX standard)
*/
if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
- if (v == (Var *)NIL) {
+ if (v == NULL) {
/* we just added it */
v = VarFind(name, ctxt, 0);
}
- v->flags |= VAR_FROM_CMD;
+ if (v != NULL)
+ v->flags |= VAR_FROM_CMD;
/*
* If requested, don't export these in the environment
* individually. We still put them in MAKEOVERRIDES so
@@ -796,10 +811,27 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
}
+ /*
+ * Another special case.
+ * Several make's support this sort of mechanism for tracking
+ * recursion - but each uses a different name.
+ * We allow the makefiles to update .MAKE.LEVEL and ensure
+ * children see a correctly incremented value.
+ */
+ if (ctxt == VAR_GLOBAL && strcmp(MAKE_LEVEL, name) == 0) {
+ char tmp[64];
+ int level;
+
+ level = atoi(val);
+ snprintf(tmp, sizeof(tmp), "%u", level + 1);
+ setenv(MAKE_LEVEL, tmp, 1);
+ }
+
+
out:
- if (name != cp)
- free(UNCONST(name));
- if (v != (Var *)NIL)
+ if (expanded_name != NULL)
+ free(expanded_name);
+ if (v != NULL)
VarFreeEnv(v, TRUE);
}
@@ -835,24 +867,33 @@ Var_Append(const char *name, const char *val, GNode *ctxt)
{
Var *v;
Hash_Entry *h;
- const char *cp = name;
+ char *expanded_name = NULL;
+
+ if (strchr(name, '$') != NULL) {
+ expanded_name = Var_Subst(NULL, name, ctxt, 0);
+ if (expanded_name[0] == 0) {
+ if (DEBUG(VAR)) {
+ fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) "
+ "name expands to empty string - ignored\n",
+ name, val);
+ }
+ free(expanded_name);
+ return;
+ }
+ name = expanded_name;
+ }
- if ((name = strchr(cp, '$'))) {
- name = Var_Subst(NULL, cp, ctxt, 0);
- } else
- name = cp;
-
v = VarFind(name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
- if (v == (Var *)NIL) {
+ if (v == NULL) {
VarAdd(name, val, ctxt);
} else {
- Buf_AddByte(v->val, (Byte)' ');
- Buf_AddBytes(v->val, strlen(val), (const Byte *)val);
+ Buf_AddByte(&v->val, ' ');
+ Buf_AddBytes(&v->val, strlen(val), val);
if (DEBUG(VAR)) {
fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name,
- (char *)Buf_GetAll(v->val, NULL));
+ Buf_GetAll(&v->val, NULL));
}
if (v->flags & VAR_FROM_ENV) {
@@ -867,8 +908,8 @@ Var_Append(const char *name, const char *val, GNode *ctxt)
Hash_SetValue(h, v);
}
}
- if (name != cp)
- free(UNCONST(name));
+ if (expanded_name != NULL)
+ free(expanded_name);
}
/*-
@@ -891,7 +932,7 @@ Var_Append(const char *name, const char *val, GNode *ctxt)
Boolean
Var_Exists(const char *name, GNode *ctxt)
{
- Var *v;
+ Var *v;
char *cp;
if ((cp = strchr(name, '$')) != NULL) {
@@ -901,7 +942,7 @@ Var_Exists(const char *name, GNode *ctxt)
if (cp != NULL) {
free(cp);
}
- if (v == (Var *)NIL) {
+ if (v == NULL) {
return(FALSE);
} else {
(void)VarFreeEnv(v, TRUE);
@@ -932,13 +973,13 @@ Var_Value(const char *name, GNode *ctxt, char **frp)
v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
*frp = NULL;
- if (v != (Var *)NIL) {
- char *p = ((char *)Buf_GetAll(v->val, NULL));
+ if (v != NULL) {
+ char *p = (Buf_GetAll(&v->val, NULL));
if (VarFreeEnv(v, FALSE))
*frp = p;
return p;
} else {
- return (NULL);
+ return NULL;
}
}
@@ -965,8 +1006,8 @@ Var_Value(const char *name, GNode *ctxt, char **frp)
*/
static Boolean
VarHead(GNode *ctx __unused, Var_Parse_State *vpstate,
- char *word, Boolean addSpace, Buffer buf,
- ClientData dummy)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *dummy)
{
char *slash;
@@ -976,7 +1017,7 @@ VarHead(GNode *ctx __unused, Var_Parse_State *vpstate,
Buf_AddByte(buf, vpstate->varSpace);
}
*slash = '\0';
- Buf_AddBytes(buf, strlen(word), (Byte *)word);
+ Buf_AddBytes(buf, strlen(word), word);
*slash = '/';
return (TRUE);
} else {
@@ -985,7 +1026,7 @@ VarHead(GNode *ctx __unused, Var_Parse_State *vpstate,
*/
if (addSpace && vpstate->varSpace)
Buf_AddByte(buf, vpstate->varSpace);
- Buf_AddByte(buf, (Byte)'.');
+ Buf_AddByte(buf, '.');
}
return(dummy ? TRUE : TRUE);
}
@@ -1013,8 +1054,8 @@ VarHead(GNode *ctx __unused, Var_Parse_State *vpstate,
*/
static Boolean
VarTail(GNode *ctx __unused, Var_Parse_State *vpstate,
- char *word, Boolean addSpace, Buffer buf,
- ClientData dummy)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *dummy)
{
char *slash;
@@ -1025,10 +1066,10 @@ VarTail(GNode *ctx __unused, Var_Parse_State *vpstate,
slash = strrchr(word, '/');
if (slash != NULL) {
*slash++ = '\0';
- Buf_AddBytes(buf, strlen(slash), (Byte *)slash);
+ Buf_AddBytes(buf, strlen(slash), slash);
slash[-1] = '/';
} else {
- Buf_AddBytes(buf, strlen(word), (Byte *)word);
+ Buf_AddBytes(buf, strlen(word), word);
}
return (dummy ? TRUE : TRUE);
}
@@ -1055,8 +1096,8 @@ VarTail(GNode *ctx __unused, Var_Parse_State *vpstate,
*/
static Boolean
VarSuffix(GNode *ctx __unused, Var_Parse_State *vpstate,
- char *word, Boolean addSpace, Buffer buf,
- ClientData dummy)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *dummy)
{
char *dot;
@@ -1066,7 +1107,7 @@ VarSuffix(GNode *ctx __unused, Var_Parse_State *vpstate,
Buf_AddByte(buf, vpstate->varSpace);
}
*dot++ = '\0';
- Buf_AddBytes(buf, strlen(dot), (Byte *)dot);
+ Buf_AddBytes(buf, strlen(dot), dot);
dot[-1] = '.';
addSpace = TRUE;
}
@@ -1096,8 +1137,8 @@ VarSuffix(GNode *ctx __unused, Var_Parse_State *vpstate,
*/
static Boolean
VarRoot(GNode *ctx __unused, Var_Parse_State *vpstate,
- char *word, Boolean addSpace, Buffer buf,
- ClientData dummy)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *dummy)
{
char *dot;
@@ -1108,10 +1149,10 @@ VarRoot(GNode *ctx __unused, Var_Parse_State *vpstate,
dot = strrchr(word, '.');
if (dot != NULL) {
*dot = '\0';
- Buf_AddBytes(buf, strlen(word), (Byte *)word);
+ Buf_AddBytes(buf, strlen(word), word);
*dot = '.';
} else {
- Buf_AddBytes(buf, strlen(word), (Byte *)word);
+ Buf_AddBytes(buf, strlen(word), word);
}
return (dummy ? TRUE : TRUE);
}
@@ -1140,15 +1181,17 @@ VarRoot(GNode *ctx __unused, Var_Parse_State *vpstate,
*/
static Boolean
VarMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
- char *word, Boolean addSpace, Buffer buf,
- ClientData pattern)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *pattern)
{
+ if (DEBUG(VAR))
+ fprintf(debug_file, "VarMatch [%s] [%s]\n", word, (char *)pattern);
if (Str_Match(word, (char *)pattern)) {
if (addSpace && vpstate->varSpace) {
Buf_AddByte(buf, vpstate->varSpace);
}
addSpace = TRUE;
- Buf_AddBytes(buf, strlen(word), (Byte *)word);
+ Buf_AddBytes(buf, strlen(word), word);
}
return(addSpace);
}
@@ -1179,8 +1222,8 @@ VarMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
*/
static Boolean
VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
- char *word, Boolean addSpace, Buffer buf,
- ClientData patp)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *patp)
{
int len;
char *ptr;
@@ -1197,7 +1240,7 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
Str_SYSVSubst(buf, varexp, ptr, len);
free(varexp);
} else {
- Buf_AddBytes(buf, strlen(word), (Byte *)word);
+ Buf_AddBytes(buf, strlen(word), word);
}
return(addSpace);
@@ -1229,15 +1272,15 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
*/
static Boolean
VarNoMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
- char *word, Boolean addSpace, Buffer buf,
- ClientData pattern)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *pattern)
{
if (!Str_Match(word, (char *)pattern)) {
if (addSpace && vpstate->varSpace) {
Buf_AddByte(buf, vpstate->varSpace);
}
addSpace = TRUE;
- Buf_AddBytes(buf, strlen(word), (Byte *)word);
+ Buf_AddBytes(buf, strlen(word), word);
}
return(addSpace);
}
@@ -1266,8 +1309,8 @@ VarNoMatch(GNode *ctx __unused, Var_Parse_State *vpstate,
*/
static Boolean
VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
- char *word, Boolean addSpace, Buffer buf,
- ClientData patternp)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *patternp)
{
int wordLen; /* Length of word */
char *cp; /* General pointer */
@@ -1297,8 +1340,7 @@ VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
Buf_AddByte(buf, vpstate->varSpace);
}
addSpace = TRUE;
- Buf_AddBytes(buf, pattern->rightLen,
- (const Byte *)pattern->rhs);
+ Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
}
pattern->flags |= VAR_SUB_MATCHED;
} else if (pattern->flags & VAR_MATCH_END) {
@@ -1316,10 +1358,9 @@ VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
}
addSpace = TRUE;
}
- Buf_AddBytes(buf, pattern->rightLen,
- (const Byte *)pattern->rhs);
+ Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
Buf_AddBytes(buf, wordLen - pattern->leftLen,
- (Byte *)(word + pattern->leftLen));
+ (word + pattern->leftLen));
pattern->flags |= VAR_SUB_MATCHED;
}
} else if (pattern->flags & VAR_MATCH_START) {
@@ -1349,9 +1390,8 @@ VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
}
addSpace = TRUE;
}
- Buf_AddBytes(buf, cp - word, (const Byte *)word);
- Buf_AddBytes(buf, pattern->rightLen,
- (const Byte *)pattern->rhs);
+ Buf_AddBytes(buf, cp - word, word);
+ Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
pattern->flags |= VAR_SUB_MATCHED;
} else {
/*
@@ -1383,9 +1423,8 @@ VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
Buf_AddByte(buf, vpstate->varSpace);
addSpace = FALSE;
}
- Buf_AddBytes(buf, cp-word, (const Byte *)word);
- Buf_AddBytes(buf, pattern->rightLen,
- (const Byte *)pattern->rhs);
+ Buf_AddBytes(buf, cp-word, word);
+ Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
wordLen -= (cp - word) + pattern->leftLen;
word = cp + pattern->leftLen;
if (wordLen == 0) {
@@ -1403,7 +1442,7 @@ VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
if (addSpace && vpstate->varSpace) {
Buf_AddByte(buf, vpstate->varSpace);
}
- Buf_AddBytes(buf, wordLen, (Byte *)word);
+ Buf_AddBytes(buf, wordLen, word);
}
/*
* If added characters to the buffer, need to add a space
@@ -1418,7 +1457,7 @@ VarSubstitute(GNode *ctx __unused, Var_Parse_State *vpstate,
if (addSpace && vpstate->varSpace) {
Buf_AddByte(buf, vpstate->varSpace);
}
- Buf_AddBytes(buf, wordLen, (Byte *)word);
+ Buf_AddBytes(buf, wordLen, word);
return(TRUE);
}
@@ -1466,8 +1505,8 @@ VarREError(int errnum, regex_t *pat, const char *str)
*/
static Boolean
VarRESubstitute(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
- char *word, Boolean addSpace, Buffer buf,
- ClientData patternp)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *patternp)
{
VarREPattern *pat;
int xrv;
@@ -1606,8 +1645,8 @@ VarRESubstitute(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
*/
static Boolean
VarLoopExpand(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
- char *word, Boolean addSpace, Buffer buf,
- ClientData loopp)
+ char *word, Boolean addSpace, Buffer *buf,
+ void *loopp)
{
VarLoop_t *loop = (VarLoop_t *)loopp;
char *s;
@@ -1619,7 +1658,7 @@ VarLoopExpand(GNode *ctx __unused, Var_Parse_State *vpstate __unused,
if (s != NULL && *s != '\0') {
if (addSpace && *s != '\n')
Buf_AddByte(buf, ' ');
- Buf_AddBytes(buf, (slen = strlen(s)), (Byte *)s);
+ Buf_AddBytes(buf, (slen = strlen(s)), s);
addSpace = (slen > 0 && s[slen - 1] != '\n');
free(s);
}
@@ -1651,7 +1690,7 @@ static char *
VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
const char *str, VarSelectWords_t *seldata)
{
- Buffer buf; /* Buffer for the new string */
+ Buffer buf; /* Buffer for the new string */
Boolean addSpace; /* TRUE if need to add a space to the
* buffer before adding the trimmed
* word */
@@ -1659,8 +1698,8 @@ VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
char *as; /* word list memory */
int ac, i;
int start, end, step;
-
- buf = Buf_Init(0);
+
+ Buf_Init(&buf, 0);
addSpace = FALSE;
if (vpstate->oneBigWord) {
@@ -1703,9 +1742,9 @@ VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
i += step) {
if (av[i] && *av[i]) {
if (addSpace && vpstate->varSpace) {
- Buf_AddByte(buf, vpstate->varSpace);
+ Buf_AddByte(&buf, vpstate->varSpace);
}
- Buf_AddBytes(buf, strlen(av[i]), (Byte *)av[i]);
+ Buf_AddBytes(&buf, strlen(av[i]), av[i]);
addSpace = TRUE;
}
}
@@ -1713,10 +1752,7 @@ VarSelectWords(GNode *ctx __unused, Var_Parse_State *vpstate,
free(as);
free(av);
- Buf_AddByte(buf, '\0');
- as = (char *)Buf_GetAll(buf, NULL);
- Buf_Destroy(buf, FALSE);
- return (as);
+ return Buf_Destroy(&buf, FALSE);
}
/*-
@@ -1742,10 +1778,10 @@ static char *
VarModify(GNode *ctx, Var_Parse_State *vpstate,
const char *str,
Boolean (*modProc)(GNode *, Var_Parse_State *, char *,
- Boolean, Buffer, ClientData),
- ClientData datum)
+ Boolean, Buffer *, void *),
+ void *datum)
{
- Buffer buf; /* Buffer for the new string */
+ Buffer buf; /* Buffer for the new string */
Boolean addSpace; /* TRUE if need to add a space to the
* buffer before adding the trimmed
* word */
@@ -1753,7 +1789,7 @@ VarModify(GNode *ctx, Var_Parse_State *vpstate,
char *as; /* word list memory */
int ac, i;
- buf = Buf_Init(0);
+ Buf_Init(&buf, 0);
addSpace = FALSE;
if (vpstate->oneBigWord) {
@@ -1768,16 +1804,13 @@ VarModify(GNode *ctx, Var_Parse_State *vpstate,
}
for (i = 0; i < ac; i++) {
- addSpace = (*modProc)(ctx, vpstate, av[i], addSpace, buf, datum);
+ addSpace = (*modProc)(ctx, vpstate, av[i], addSpace, &buf, datum);
}
free(as);
free(av);
- Buf_AddByte(buf, '\0');
- as = (char *)Buf_GetAll(buf, NULL);
- Buf_Destroy(buf, FALSE);
- return (as);
+ return Buf_Destroy(&buf, FALSE);
}
@@ -1808,12 +1841,12 @@ VarWordCompare(const void *a, const void *b)
static char *
VarOrder(const char *str, const char otype)
{
- Buffer buf; /* Buffer for the new string */
+ Buffer buf; /* Buffer for the new string */
char **av; /* word list [first word does not count] */
char *as; /* word list memory */
int ac, i;
- buf = Buf_Init(0);
+ Buf_Init(&buf, 0);
av = brk_string(str, &ac, FALSE, &as);
@@ -1845,18 +1878,15 @@ VarOrder(const char *str, const char otype)
} /* end of switch */
for (i = 0; i < ac; i++) {
- Buf_AddBytes(buf, strlen(av[i]), (Byte *)av[i]);
+ Buf_AddBytes(&buf, strlen(av[i]), av[i]);
if (i != ac - 1)
- Buf_AddByte(buf, ' ');
+ Buf_AddByte(&buf, ' ');
}
free(as);
free(av);
- Buf_AddByte(buf, '\0');
- as = (char *)Buf_GetAll(buf, NULL);
- Buf_Destroy(buf, FALSE);
- return (as);
+ return Buf_Destroy(&buf, FALSE);
}
@@ -1879,12 +1909,12 @@ VarOrder(const char *str, const char otype)
static char *
VarUniq(const char *str)
{
- Buffer buf; /* Buffer for new string */
+ Buffer buf; /* Buffer for new string */
char **av; /* List of words to affect */
char *as; /* Word list memory */
int ac, i, j;
- buf = Buf_Init(0);
+ Buf_Init(&buf, 0);
av = brk_string(str, &ac, FALSE, &as);
if (ac > 1) {
@@ -1895,18 +1925,15 @@ VarUniq(const char *str)
}
for (i = 0; i < ac; i++) {
- Buf_AddBytes(buf, strlen(av[i]), (Byte *)av[i]);
+ Buf_AddBytes(&buf, strlen(av[i]), av[i]);
if (i != ac - 1)
- Buf_AddByte(buf, ' ');
+ Buf_AddByte(&buf, ' ');
}
free(as);
free(av);
- Buf_AddByte(buf, '\0');
- as = (char *)Buf_GetAll(buf, NULL);
- Buf_Destroy(buf, FALSE);
- return as;
+ return Buf_Destroy(&buf, FALSE);
}
@@ -1938,8 +1965,11 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate __unused,
int *length, VarPattern *pattern)
{
const char *cp;
- Buffer buf = Buf_Init(0);
+ char *rstr;
+ Buffer buf;
int junk;
+
+ Buf_Init(&buf, 0);
if (length == NULL)
length = &junk;
@@ -1955,12 +1985,12 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate __unused,
*/
for (cp = *tstr; *cp && (*cp != delim); cp++) {
if (IS_A_MATCH(cp, delim)) {
- Buf_AddByte(buf, (Byte)cp[1]);
+ Buf_AddByte(&buf, cp[1]);
cp++;
} else if (*cp == '$') {
if (cp[1] == delim) {
if (flags == NULL)
- Buf_AddByte(buf, (Byte)*cp);
+ Buf_AddByte(&buf, *cp);
else
/*
* Unescaped $ at end of pattern => anchor
@@ -1979,7 +2009,7 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate __unused,
* substitution and recurse.
*/
cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt);
- Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
+ Buf_AddBytes(&buf, strlen(cp2), cp2);
if (freeIt)
free(freeIt);
cp += len - 1;
@@ -2004,34 +2034,31 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate __unused,
--depth;
}
}
- Buf_AddBytes(buf, cp2 - cp, (const Byte *)cp);
+ Buf_AddBytes(&buf, cp2 - cp, cp);
cp = --cp2;
} else
- Buf_AddByte(buf, (Byte)*cp);
+ Buf_AddByte(&buf, *cp);
}
}
}
else if (pattern && *cp == '&')
- Buf_AddBytes(buf, pattern->leftLen, (const Byte *)pattern->lhs);
+ Buf_AddBytes(&buf, pattern->leftLen, pattern->lhs);
else
- Buf_AddByte(buf, (Byte)*cp);
+ Buf_AddByte(&buf, *cp);
}
- Buf_AddByte(buf, (Byte)'\0');
-
if (*cp != delim) {
*tstr = cp;
*length = 0;
return NULL;
}
- else {
- char *rstr;
- *tstr = ++cp;
- rstr = (char *)Buf_GetAll(buf, length);
- *length -= 1; /* Don't count the NULL */
- Buf_Destroy(buf, FALSE);
- return rstr;
- }
+
+ *tstr = ++cp;
+ *length = Buf_Size(&buf);
+ rstr = Buf_Destroy(&buf, FALSE);
+ if (DEBUG(VAR))
+ fprintf(debug_file, "Modifier pattern: \"%s\"\n", rstr);
+ return rstr;
}
/*-
@@ -2061,23 +2088,23 @@ VarQuote(char *str)
newline = "\\\n";
nlen = strlen(newline);
- buf = Buf_Init(0);
+ Buf_Init(&buf, 0);
while (*str != '\0') {
if ((len = strcspn(str, meta)) != 0) {
- Buf_AddBytes(buf, len, str);
+ Buf_AddBytes(&buf, len, str);
str += len;
} else if (*str == '\n') {
- Buf_AddBytes(buf, nlen, newline);
+ Buf_AddBytes(&buf, nlen, newline);
++str;
} else {
- Buf_AddByte(buf, (Byte)'\\');
- Buf_AddByte(buf, (Byte)*str);
+ Buf_AddByte(&buf, '\\');
+ Buf_AddByte(&buf, *str);
++str;
}
}
- Buf_AddByte(buf, (Byte)'\0');
- str = (char *)Buf_GetAll(buf, NULL);
- Buf_Destroy(buf, FALSE);
+ str = Buf_Destroy(&buf, FALSE);
+ if (DEBUG(VAR))
+ fprintf(debug_file, "QuoteMeta: [%s]\n", str);
return str;
}
@@ -2105,99 +2132,96 @@ VarChangeCase(char *str, int upper)
int (*modProc)(int);
modProc = (upper ? toupper : tolower);
- buf = Buf_Init(0);
+ Buf_Init(&buf, 0);
for (; *str ; str++) {
- Buf_AddByte(buf, (Byte)modProc(*str));
+ Buf_AddByte(&buf, modProc(*str));
}
- Buf_AddByte(buf, (Byte)'\0');
- str = (char *)Buf_GetAll(buf, NULL);
- Buf_Destroy(buf, FALSE);
- return str;
+ return Buf_Destroy(&buf, FALSE);
}
/*
* Now we need to apply any modifiers the user wants applied.
* These are:
* :M<pattern> words which match the given <pattern>.
- * <pattern> is of the standard file
- * wildcarding form.
+ * <pattern> is of the standard file
+ * wildcarding form.
* :N<pattern> words which do not match the given <pattern>.
* :S<d><pat1><d><pat2><d>[1gW]
- * Substitute <pat2> for <pat1> in the value
+ * Substitute <pat2> for <pat1> in the value
* :C<d><pat1><d><pat2><d>[1gW]
- * Substitute <pat2> for regex <pat1> in the value
- * :H Substitute the head of each word
- * :T Substitute the tail of each word
- * :E Substitute the extension (minus '.') of
- * each word
- * :R Substitute the root of each word
- * (pathname minus the suffix).
- * :O ("Order") Alphabeticaly sort words in variable.
- * :Ox ("intermiX") Randomize words in variable.
- * :u ("uniq") Remove adjacent duplicate words.
- * :tu Converts the variable contents to uppercase.
- * :tl Converts the variable contents to lowercase.
- * :ts[c] Sets varSpace - the char used to
- * separate words to 'c'. If 'c' is
- * omitted then no separation is used.
- * :tW Treat the variable contents as a single
- * word, even if it contains spaces.
- * (Mnemonic: one big 'W'ord.)
- * :tw Treat the variable contents as multiple
- * space-separated words.
- * (Mnemonic: many small 'w'ords.)
- * :[index] Select a single word from the value.
- * :[start..end] Select multiple words from the value.
- * :[*] or :[0] Select the entire value, as a single
- * word. Equivalent to :tW.
- * :[@] Select the entire value, as multiple
- * words. Undoes the effect of :[*].
- * Equivalent to :tw.
- * :[#] Returns the number of words in the value.
- *
- * :?<true-value>:<false-value>
- * If the variable evaluates to true, return
- * true value, else return the second value.
- * :lhs=rhs Like :S, but the rhs goes to the end of
- * the invocation.
- * :sh Treat the current value as a command
- * to be run, new value is its output.
+ * Substitute <pat2> for regex <pat1> in the value
+ * :H Substitute the head of each word
+ * :T Substitute the tail of each word
+ * :E Substitute the extension (minus '.') of
+ * each word
+ * :R Substitute the root of each word
+ * (pathname minus the suffix).
+ * :O ("Order") Alphabeticaly sort words in variable.
+ * :Ox ("intermiX") Randomize words in variable.
+ * :u ("uniq") Remove adjacent duplicate words.
+ * :tu Converts the variable contents to uppercase.
+ * :tl Converts the variable contents to lowercase.
+ * :ts[c] Sets varSpace - the char used to
+ * separate words to 'c'. If 'c' is
+ * omitted then no separation is used.
+ * :tW Treat the variable contents as a single
+ * word, even if it contains spaces.
+ * (Mnemonic: one big 'W'ord.)
+ * :tw Treat the variable contents as multiple
+ * space-separated words.
+ * (Mnemonic: many small 'w'ords.)
+ * :[index] Select a single word from the value.
+ * :[start..end] Select multiple words from the value.
+ * :[*] or :[0] Select the entire value, as a single
+ * word. Equivalent to :tW.
+ * :[@] Select the entire value, as multiple
+ * words. Undoes the effect of :[*].
+ * Equivalent to :tw.
+ * :[#] Returns the number of words in the value.
+ *
+ * :?<true-value>:<false-value>
+ * If the variable evaluates to true, return
+ * true value, else return the second value.
+ * :lhs=rhs Like :S, but the rhs goes to the end of
+ * the invocation.
+ * :sh Treat the current value as a command
+ * to be run, new value is its output.
* The following added so we can handle ODE makefiles.
- * :@<tmpvar>@<newval>@
- * Assign a temporary local variable <tmpvar>
- * to the current value of each word in turn
- * and replace each word with the result of
- * evaluating <newval>
- * :D<newval> Use <newval> as value if variable defined
- * :U<newval> Use <newval> as value if variable undefined
- * :L Use the name of the variable as the value.
- * :P Use the path of the node that has the same
- * name as the variable as the value. This
- * basically includes an implied :L so that
- * the common method of refering to the path
- * of your dependent 'x' in a rule is to use
- * the form '${x:P}'.
- * :!<cmd>! Run cmd much the same as :sh run's the
- * current value of the variable.
+ * :@<tmpvar>@<newval>@
+ * Assign a temporary local variable <tmpvar>
+ * to the current value of each word in turn
+ * and replace each word with the result of
+ * evaluating <newval>
+ * :D<newval> Use <newval> as value if variable defined
+ * :U<newval> Use <newval> as value if variable undefined
+ * :L Use the name of the variable as the value.
+ * :P Use the path of the node that has the same
+ * name as the variable as the value. This
+ * basically includes an implied :L so that
+ * the common method of refering to the path
+ * of your dependent 'x' in a rule is to use
+ * the form '${x:P}'.
+ * :!<cmd>! Run cmd much the same as :sh run's the
+ * current value of the variable.
* The ::= modifiers, actually assign a value to the variable.
* Their main purpose is in supporting modifiers of .for loop
* iterators and other obscure uses. They always expand to
* nothing. In a target rule that would otherwise expand to an
* empty line they can be preceded with @: to keep make happy.
* Eg.
- *
+ *
* foo: .USE
* .for i in ${.TARGET} ${.TARGET:R}.gz
- * @: ${t::=$i}
- * @echo blah ${t:T}
+ * @: ${t::=$i}
+ * @echo blah ${t:T}
* .endfor
- *
- * ::=<str> Assigns <str> as the new value of variable.
- * ::?=<str> Assigns <str> as value of variable if
- * it was not already set.
- * ::+=<str> Appends <str> to variable.
- * ::!=<cmd> Assigns output of <cmd> as the new value of
- * variable.
+ *
+ * ::=<str> Assigns <str> as the new value of variable.
+ * ::?=<str> Assigns <str> as value of variable if
+ * it was not already set.
+ * ::+=<str> Appends <str> to variable.
+ * ::!=<cmd> Assigns output of <cmd> as the new value of
+ * variable.
*/
static char *
@@ -2222,11 +2246,11 @@ ApplyModifiers(char *nstr, const char *tstr,
parsestate.varSpace = ' '; /* word separator */
start = cp = tstr;
-
+
while (*tstr && *tstr != endc) {
if (*tstr == '$') {
- /*
+ /*
* We have some complex modifiers in a variable.
*/
void *freeIt;
@@ -2261,7 +2285,7 @@ ApplyModifiers(char *nstr, const char *tstr,
if (*tstr == ':')
tstr++;
else if (!*tstr && endc) {
- Error("Unclosed variable specification for %s", v->name);
+ Error("Unclosed variable specification after complex modifier (expecting '%c') for %s", endc, v->name);
goto out;
}
continue;
@@ -2285,6 +2309,9 @@ ApplyModifiers(char *nstr, const char *tstr,
VarPattern pattern;
int how;
+ if (v->name[0] == 0)
+ goto bad_modifier;
+
v_ctxt = ctxt;
sv_name = NULL;
++tstr;
@@ -2297,12 +2324,12 @@ ApplyModifiers(char *nstr, const char *tstr,
v->name = bmake_strdup(v->name);
} else if (ctxt != VAR_GLOBAL) {
Var *gv = VarFind(v->name, ctxt, 0);
- if (gv == (Var *)NIL)
+ if (gv == NULL)
v_ctxt = VAR_GLOBAL;
else
VarFreeEnv(gv, TRUE);
}
-
+
switch ((how = *tstr)) {
case '+':
case '?':
@@ -2401,7 +2428,7 @@ ApplyModifiers(char *nstr, const char *tstr,
* the delimiter (expand the variable substitution).
* The result is left in the Buffer buf.
*/
- buf = Buf_Init(0);
+ Buf_Init(&buf, 0);
for (cp = tstr + 1;
*cp != endc && *cp != ':' && *cp != '\0';
cp++) {
@@ -2411,7 +2438,7 @@ ApplyModifiers(char *nstr, const char *tstr,
(cp[1] == endc) ||
(cp[1] == '\\')))
{
- Buf_AddByte(buf, (Byte)cp[1]);
+ Buf_AddByte(&buf, cp[1]);
cp++;
} else if (*cp == '$') {
/*
@@ -2423,15 +2450,14 @@ ApplyModifiers(char *nstr, const char *tstr,
void *freeIt;
cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt);
- Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
+ Buf_AddBytes(&buf, strlen(cp2), cp2);
if (freeIt)
free(freeIt);
cp += len - 1;
} else {
- Buf_AddByte(buf, (Byte)*cp);
+ Buf_AddByte(&buf, *cp);
}
}
- Buf_AddByte(buf, (Byte)'\0');
termc = *cp;
@@ -2442,11 +2468,10 @@ ApplyModifiers(char *nstr, const char *tstr,
if ((v->flags & VAR_JUNK) != 0)
v->flags |= VAR_KEEP;
if (wantit) {
- newStr = (char *)Buf_GetAll(buf, NULL);
- Buf_Destroy(buf, FALSE);
+ newStr = Buf_Destroy(&buf, FALSE);
} else {
newStr = nstr;
- Buf_Destroy(buf, TRUE);
+ Buf_Destroy(&buf, TRUE);
}
break;
}
@@ -2462,11 +2487,11 @@ ApplyModifiers(char *nstr, const char *tstr,
case 'P':
{
GNode *gn;
-
+
if ((v->flags & VAR_JUNK) != 0)
v->flags |= VAR_KEEP;
gn = Targ_FindNode(v->name, TARG_NOCREATE);
- if (gn == NILGNODE || gn->type & OP_NOPATH) {
+ if (gn == NULL || gn->type & OP_NOPATH) {
newStr = NULL;
} else if (gn->path) {
newStr = bmake_strdup(gn->path);
@@ -2515,7 +2540,7 @@ ApplyModifiers(char *nstr, const char *tstr,
* which we must free().
*/
char *estr;
-
+
cp = tstr+1; /* point to char after '[' */
delim = ']'; /* look for closing ']' */
estr = VarGetPattern(ctxt, &parsestate,
@@ -2678,7 +2703,7 @@ ApplyModifiers(char *nstr, const char *tstr,
default:
if (isdigit((unsigned char)tstr[3])) {
char *ep;
-
+
parsestate.varSpace =
strtoul(&tstr[3], &ep, 0);
if (*ep != ':' && *ep != endc)
@@ -2755,9 +2780,11 @@ ApplyModifiers(char *nstr, const char *tstr,
const char *endpat; /* points just after end of pattern */
char *cp2;
Boolean copy; /* pattern should be, or has been, copied */
+ Boolean needSubst;
int nest;
copy = FALSE;
+ needSubst = FALSE;
nest = 1;
/*
* In the loop below, ignore ':' unless we are at
@@ -2772,13 +2799,18 @@ ApplyModifiers(char *nstr, const char *tstr,
if (*cp == '\\' &&
(cp[1] == ':' ||
cp[1] == endc || cp[1] == startc)) {
- copy = TRUE;
+ if (!needSubst) {
+ copy = TRUE;
+ }
cp++;
continue;
}
- if (*cp == startc)
+ if (*cp == '$') {
+ needSubst = TRUE;
+ }
+ if (*cp == '(' || *cp == '{')
++nest;
- if (*cp == endc) {
+ if (*cp == ')' || *cp == '}') {
--nest;
if (nest == 0)
break;
@@ -2813,29 +2845,27 @@ ApplyModifiers(char *nstr, const char *tstr,
* nul-terminated string soon, so construct one now.
*/
pattern = bmake_strndup(tstr+1, endpat - (tstr + 1));
- copy = TRUE;
}
- if (strchr(pattern, '$') != NULL) {
+ if (needSubst) {
/*
* pattern contains embedded '$', so use Var_Subst to
* expand it.
*/
cp2 = pattern;
pattern = Var_Subst(NULL, cp2, ctxt, errnum);
- if (copy)
- free(cp2);
- copy = TRUE;
+ free(cp2);
}
- if (*tstr == 'M' || *tstr == 'm') {
+ if (DEBUG(VAR))
+ fprintf(debug_file, "Pattern for [%s] is [%s]\n", nstr,
+ pattern);
+ if (*tstr == 'M') {
newStr = VarModify(ctxt, &parsestate, nstr, VarMatch,
pattern);
} else {
newStr = VarModify(ctxt, &parsestate, nstr, VarNoMatch,
pattern);
}
- if (copy) {
- free(pattern);
- }
+ free(pattern);
break;
}
case 'S':
@@ -2903,7 +2933,7 @@ ApplyModifiers(char *nstr, const char *tstr,
free(UNCONST(pattern.rhs));
delim = '\0';
break;
- }
+ }
case '?':
{
VarPattern pattern;
@@ -2931,7 +2961,7 @@ ApplyModifiers(char *nstr, const char *tstr,
termc = *--cp;
delim = '\0';
- if (Cond_EvalExpression(1, v->name, &value, 0)
+ if (Cond_EvalExpression(NULL, v->name, &value, 0)
== COND_INVALID) {
Error("Bad conditional expression `%s' in %s?%s:%s",
v->name, v->name, pattern.lhs, pattern.rhs);
@@ -3104,7 +3134,7 @@ ApplyModifiers(char *nstr, const char *tstr,
goto default_case;
#endif
default:
- default_case:
+ default_case:
{
#ifdef SYSVVARSUB
/*
@@ -3143,7 +3173,7 @@ ApplyModifiers(char *nstr, const char *tstr,
*/
delim='=';
cp = tstr;
- if ((pattern.lhs = VarGetPattern(ctxt, &parsestate,
+ if ((pattern.lhs = VarGetPattern(ctxt, &parsestate,
errnum, &cp, delim, &pattern.flags,
&pattern.leftLen, NULL)) == NULL)
goto cleanup;
@@ -3192,7 +3222,7 @@ ApplyModifiers(char *nstr, const char *tstr,
}
}
if (termc == '\0' && endc != '\0') {
- Error("Unclosed variable specification for %s", v->name);
+ Error("Unclosed variable specification (expecting '%c') for \"%s\" (value \"%s\") modifier %c", endc, v->name, nstr, modifier);
} else if (termc == ':') {
cp++;
}
@@ -3252,11 +3282,11 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
void **freePtr)
{
const char *tstr; /* Pointer into str */
- Var *v; /* Variable in invocation */
+ Var *v; /* Variable in invocation */
Boolean haveModifier;/* TRUE if have modifiers for the variable */
char endc; /* Ending character when variable in parens
* or braces */
- char startc=0; /* Starting character when variable in parens
+ char startc; /* Starting character when variable in parens
* or braces */
int vlen; /* Length of variable name */
const char *start; /* Points to original start of str */
@@ -3266,6 +3296,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
* is done to support dynamic sources. The
* result is just the invocation, unaltered */
Var_Parse_State parsestate; /* Flags passed to helper functions */
+ char name[2];
*freePtr = NULL;
dynamic = FALSE;
@@ -3273,19 +3304,24 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
parsestate.oneBigWord = FALSE;
parsestate.varSpace = ' '; /* word separator */
- if (str[1] != PROPEN && str[1] != BROPEN) {
+ startc = str[1];
+ if (startc != PROPEN && startc != BROPEN) {
/*
* If it's not bounded by braces of some sort, life is much simpler.
* We just need to check for the first character and return the
* value if it exists.
*/
- char name[2];
- name[0] = str[1];
+ /* Error out some really stupid names */
+ if (startc == '\0' || strchr(")}:$", startc)) {
+ *lengthPtr = 1;
+ return var_Error;
+ }
+ name[0] = startc;
name[1] = '\0';
v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
- if (v == (Var *)NIL) {
+ if (v == NULL) {
*lengthPtr = 2;
if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
@@ -3318,15 +3354,11 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
tstr = &str[1];
endc = str[1];
}
- } else if (str[1] == '\0') {
- *lengthPtr = 1;
- return (errnum ? var_Error : varNoError);
} else {
Buffer buf; /* Holds the variable name */
- startc = str[1];
endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
- buf = Buf_Init(0);
+ Buf_Init(&buf, 0);
/*
* Skip to the end character or a colon, whichever comes first.
@@ -3343,14 +3375,14 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
void *freeIt;
char *rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt);
if (rval != NULL) {
- Buf_AddBytes(buf, strlen(rval), (Byte *)rval);
+ Buf_AddBytes(&buf, strlen(rval), rval);
}
if (freeIt)
free(freeIt);
tstr += rlen - 1;
}
else
- Buf_AddByte(buf, (Byte)*tstr);
+ Buf_AddByte(&buf, *tstr);
}
if (*tstr == ':') {
haveModifier = TRUE;
@@ -3363,12 +3395,10 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
* the end of the string, since that's what make does.
*/
*lengthPtr = tstr - str;
- Buf_Destroy(buf, TRUE);
+ Buf_Destroy(&buf, TRUE);
return (var_Error);
}
- Buf_AddByte(buf, (Byte)'\0');
- str = Buf_GetAll(buf, NULL);
- vlen = strlen(str);
+ str = Buf_GetAll(&buf, &vlen);
/*
* At this point, str points into newly allocated memory from
@@ -3382,65 +3412,50 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
*/
v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
- if ((v == (Var *)NIL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
- (vlen == 2) && (str[1] == 'F' || str[1] == 'D'))
- {
+ /*
+ * Check also for bogus D and F forms of local variables since we're
+ * in a local context and the name is the right length.
+ */
+ if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
+ (vlen == 2) && (str[1] == 'F' || str[1] == 'D') &&
+ strchr("@%*!<>", str[0]) != NULL) {
/*
- * Check for bogus D and F forms of local variables since we're
- * in a local context and the name is the right length.
+ * Well, it's local -- go look for it.
*/
- switch(*str) {
- case '@':
- case '%':
- case '*':
- case '!':
- case '>':
- case '<':
- {
- char vname[2];
- char *val;
-
- /*
- * Well, it's local -- go look for it.
- */
- vname[0] = *str;
- vname[1] = '\0';
- v = VarFind(vname, ctxt, 0);
+ name[0] = *str;
+ name[1] = '\0';
+ v = VarFind(name, ctxt, 0);
- if (v != (Var *)NIL) {
- /*
- * No need for nested expansion or anything, as we're
- * the only one who sets these things and we sure don't
- * but nested invocations in them...
- */
- val = (char *)Buf_GetAll(v->val, NULL);
+ if (v != NULL) {
+ /*
+ * No need for nested expansion or anything, as we're
+ * the only one who sets these things and we sure don't
+ * but nested invocations in them...
+ */
+ nstr = Buf_GetAll(&v->val, NULL);
- if (str[1] == 'D') {
- val = VarModify(ctxt, &parsestate, val, VarHead,
- NULL);
- } else {
- val = VarModify(ctxt, &parsestate, val, VarTail,
- NULL);
- }
- /*
- * Resulting string is dynamically allocated, so
- * tell caller to free it.
- */
- *freePtr = val;
- *lengthPtr = tstr-start+1;
- Buf_Destroy(buf, TRUE);
- VarFreeEnv(v, TRUE);
- return(val);
- }
- break;
+ if (str[1] == 'D') {
+ nstr = VarModify(ctxt, &parsestate, nstr, VarHead,
+ NULL);
+ } else {
+ nstr = VarModify(ctxt, &parsestate, nstr, VarTail,
+ NULL);
}
+ /*
+ * Resulting string is dynamically allocated, so
+ * tell caller to free it.
+ */
+ *freePtr = nstr;
+ *lengthPtr = tstr-start+1;
+ Buf_Destroy(&buf, TRUE);
+ VarFreeEnv(v, TRUE);
+ return nstr;
}
}
- if (v == (Var *)NIL) {
+ if (v == NULL) {
if (((vlen == 1) ||
- (((vlen == 2) && (str[1] == 'F' ||
- str[1] == 'D')))) &&
+ (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
{
/*
@@ -3485,10 +3500,10 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
if (dynamic) {
char *pstr = bmake_strndup(start, *lengthPtr);
*freePtr = pstr;
- Buf_Destroy(buf, TRUE);
+ Buf_Destroy(&buf, TRUE);
return(pstr);
} else {
- Buf_Destroy(buf, TRUE);
+ Buf_Destroy(&buf, TRUE);
return (errnum ? var_Error : varNoError);
}
} else {
@@ -3498,12 +3513,12 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
*/
v = bmake_malloc(sizeof(Var));
v->name = UNCONST(str);
- v->val = Buf_Init(1);
+ Buf_Init(&v->val, 1);
v->flags = VAR_JUNK;
- Buf_Destroy(buf, FALSE);
+ Buf_Destroy(&buf, FALSE);
}
} else
- Buf_Destroy(buf, TRUE);
+ Buf_Destroy(&buf, TRUE);
}
if (v->flags & VAR_IN_USE) {
@@ -3521,7 +3536,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
* been dynamically-allocated, so it will need freeing when we
* return.
*/
- nstr = (char *)Buf_GetAll(v->val, NULL);
+ nstr = Buf_GetAll(&v->val, NULL);
if (strchr(nstr, '$') != NULL) {
nstr = Var_Subst(NULL, nstr, ctxt, errnum);
*freePtr = nstr;
@@ -3549,7 +3564,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
if (v->flags & VAR_FROM_ENV) {
Boolean destroy = FALSE;
- if (nstr != (char *)Buf_GetAll(v->val, NULL)) {
+ if (nstr != Buf_GetAll(&v->val, NULL)) {
destroy = TRUE;
} else {
/*
@@ -3577,8 +3592,8 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
nstr = var_Error;
}
}
- if (nstr != (char *)Buf_GetAll(v->val, NULL))
- Buf_Destroy(v->val, TRUE);
+ if (nstr != Buf_GetAll(&v->val, NULL))
+ Buf_Destroy(&v->val, TRUE);
free(v->name);
free(v);
}
@@ -3608,22 +3623,22 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr,
char *
Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
{
- Buffer buf; /* Buffer for forming things */
+ Buffer buf; /* Buffer for forming things */
char *val; /* Value to substitute for a variable */
- int length; /* Length of the variable invocation */
+ int length; /* Length of the variable invocation */
Boolean trailingBslash; /* variable ends in \ */
void *freeIt = NULL; /* Set if it should be freed */
static Boolean errorReported; /* Set true if an error has already
* been reported to prevent a plethora
* of messages when recursing */
- buf = Buf_Init(0);
+ Buf_Init(&buf, 0);
errorReported = FALSE;
trailingBslash = FALSE;
while (*str) {
if (*str == '\n' && trailingBslash)
- Buf_AddByte(buf, ' ');
+ Buf_AddByte(&buf, ' ');
if (var == NULL && (*str == '$') && (str[1] == '$')) {
/*
* A dollar sign may be escaped either with another dollar sign.
@@ -3631,7 +3646,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
* dollar sign into the buffer directly.
*/
str++;
- Buf_AddByte(buf, (Byte)*str);
+ Buf_AddByte(&buf, *str);
str++;
} else if (*str != '$') {
/*
@@ -3642,19 +3657,19 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
for (cp = str++; *str != '$' && *str != '\0'; str++)
continue;
- Buf_AddBytes(buf, str - cp, (const Byte *)cp);
+ Buf_AddBytes(&buf, str - cp, cp);
} else {
if (var != NULL) {
int expand;
for (;;) {
if (str[1] == '\0') {
/* A trailing $ is kind of a special case */
- Buf_AddByte(buf, str[0]);
+ Buf_AddByte(&buf, str[0]);
str++;
expand = FALSE;
} else if (str[1] != PROPEN && str[1] != BROPEN) {
if (str[1] != *var || strlen(var) > 1) {
- Buf_AddBytes(buf, 2, (const Byte *)str);
+ Buf_AddBytes(&buf, 2, str);
str += 2;
expand = FALSE;
}
@@ -3678,7 +3693,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
* the nested one
*/
if (*p == '$') {
- Buf_AddBytes(buf, p - str, (const Byte *)str);
+ Buf_AddBytes(&buf, p - str, str);
str = p;
continue;
}
@@ -3691,7 +3706,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
*/
for (;*p != '$' && *p != '\0'; p++)
continue;
- Buf_AddBytes(buf, p - str, (const Byte *)str);
+ Buf_AddBytes(&buf, p - str, str);
str = p;
expand = FALSE;
}
@@ -3734,7 +3749,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
str += length;
errorReported = TRUE;
} else {
- Buf_AddByte(buf, (Byte)*str);
+ Buf_AddByte(&buf, *str);
str += 1;
}
} else {
@@ -3749,7 +3764,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
* into the new string.
*/
length = strlen(val);
- Buf_AddBytes(buf, length, (Byte *)val);
+ Buf_AddBytes(&buf, length, val);
trailingBslash = length > 0 && val[length - 1] == '\\';
}
if (freeIt) {
@@ -3759,10 +3774,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
}
}
- Buf_AddByte(buf, '\0');
- val = (char *)Buf_GetAll(buf, NULL);
- Buf_Destroy(buf, FALSE);
- return (val);
+ return Buf_Destroy(&buf, FALSE);
}
/*-
@@ -3843,10 +3855,10 @@ Var_End(void)
/****************** PRINT DEBUGGING INFO *****************/
static void
-VarPrintVar(ClientData vp)
+VarPrintVar(void *vp)
{
Var *v = (Var *)vp;
- fprintf(debug_file, "%-16s = %s\n", v->name, (char *)Buf_GetAll(v->val, NULL));
+ fprintf(debug_file, "%-16s = %s\n", v->name, Buf_GetAll(&v->val, NULL));
}
/*-