diff options
-rw-r--r-- | usr.bin/make/arch.c | 2 | ||||
-rw-r--r-- | usr.bin/make/for.c | 2 | ||||
-rw-r--r-- | usr.bin/make/main.c | 2 | ||||
-rw-r--r-- | usr.bin/make/parse.c | 2 | ||||
-rw-r--r-- | usr.bin/make/suff.c | 2 | ||||
-rw-r--r-- | usr.bin/make/var.c | 112 | ||||
-rw-r--r-- | usr.bin/make/varmodifiers.c | 2 | ||||
-rw-r--r-- | usr.bin/make/varmodifiers.h | 2 |
8 files changed, 86 insertions, 40 deletions
diff --git a/usr.bin/make/arch.c b/usr.bin/make/arch.c index 9edc2c7eca1..d78184c855d 100644 --- a/usr.bin/make/arch.c +++ b/usr.bin/make/arch.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: arch.c,v 1.57 2007/07/24 18:52:47 espie Exp $ */ +/* $OpenBSD: arch.c,v 1.58 2007/07/24 18:56:15 espie Exp $ */ /* $NetBSD: arch.c,v 1.17 1996/11/06 17:58:59 christos Exp $ */ /* diff --git a/usr.bin/make/for.c b/usr.bin/make/for.c index 09982a7f595..f7106cb783c 100644 --- a/usr.bin/make/for.c +++ b/usr.bin/make/for.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: for.c,v 1.33 2007/07/24 18:52:47 espie Exp $ */ +/* $OpenBSD: for.c,v 1.34 2007/07/24 18:56:15 espie Exp $ */ /* $NetBSD: for.c,v 1.4 1996/11/06 17:59:05 christos Exp $ */ /* diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c index 244f7b51ece..4144e1edb2d 100644 --- a/usr.bin/make/main.c +++ b/usr.bin/make/main.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: main.c,v 1.72 2007/07/24 18:52:47 espie Exp $ */ +/* $OpenBSD: main.c,v 1.73 2007/07/24 18:56:15 espie Exp $ */ /* $NetBSD: main.c,v 1.34 1997/03/24 20:56:36 gwr Exp $ */ /* diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index b154544c34a..e61932047f2 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: parse.c,v 1.74 2007/07/24 18:52:47 espie Exp $ */ +/* $OpenBSD: parse.c,v 1.75 2007/07/24 18:56:15 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* diff --git a/usr.bin/make/suff.c b/usr.bin/make/suff.c index b8e3eb09add..fe420c2aff5 100644 --- a/usr.bin/make/suff.c +++ b/usr.bin/make/suff.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: suff.c,v 1.57 2007/07/24 18:52:47 espie Exp $ */ +/* $OpenBSD: suff.c,v 1.58 2007/07/24 18:56:15 espie Exp $ */ /* $NetBSD: suff.c,v 1.13 1996/11/06 17:59:25 christos Exp $ */ /* diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index 1f135dab8bd..5d891cc8445 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: var.c,v 1.68 2007/07/24 18:52:47 espie Exp $ */ +/* $OpenBSD: var.c,v 1.69 2007/07/24 18:56:15 espie Exp $ */ /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */ /* @@ -227,6 +227,9 @@ static const char *find_rparen(const char *); static const char *find_ket(const char *); typedef const char * (*find_t)(const char *); static find_t find_pos(int); +static void push_used(Var *); +static void pop_used(Var *); +static char *get_expanded_value(Var *, int, SymTable *, bool, bool *); @@ -880,6 +883,80 @@ Var_ParseBuffer(Buffer buf, const char *str, SymTable *ctxt, bool err, return true; } +/* Helper function for Var_Parse: still recursive, but we tag what variables + * we expand for better error messages. + */ +#define MAX_DEPTH 350 +static Var *call_trace[MAX_DEPTH]; +static int current_depth = 0; + +static void +push_used(Var *v) +{ + if (v->flags & VAR_IN_USE) { + int i; + fprintf(stderr, "Problem with variable expansion chain: "); + for (i = 0; + i < (current_depth > MAX_DEPTH ? MAX_DEPTH : current_depth); + i++) + fprintf(stderr, "%s -> ", call_trace[i]->name); + fprintf(stderr, "%s\n", v->name); + Fatal("\tVariable %s is recursive.", v->name); + /*NOTREACHED*/ + } + + v->flags |= VAR_IN_USE; + if (current_depth < MAX_DEPTH) + call_trace[current_depth] = v; + current_depth++; +} + +static void +pop_used(Var *v) +{ + v->flags &= ~VAR_IN_USE; + current_depth--; +} + +static char * +get_expanded_value(Var *v, int idx, SymTable *ctxt, bool err, bool *freePtr) +{ + char *val; + + if (v == NULL) + return NULL; + + if ((v->flags & POISONS) != 0) + poison_check(v); + if ((v->flags & VAR_DUMMY) != 0) + return NULL; + + /* Before doing any modification, we have to make sure the + * value has been fully expanded. If it looks like recursion + * might be necessary (there's a dollar sign somewhere in + * the variable's value) we just call Var_Subst to do any + * other substitutions that are necessary. Note that the + * value returned by Var_Subst will have been dynamically + * allocated, so it will need freeing when we return. + */ + val = var_get_value(v); + if (idx == GLOBAL_INDEX) { + if (strchr(val, '$') != NULL) { + push_used(v); + val = Var_Subst(val, ctxt, err); + pop_used(v); + *freePtr = true; + } + } else if (idx >= LOCAL_SIZE) { + if (IS_EXTENDED_F(idx)) + val = Var_GetTail(val); + else + val = Var_GetHead(val); + *freePtr = true; + } + return val; +} + char * Var_Parse(const char *str, /* The string to parse */ SymTable *ctxt, /* The context for the variable */ @@ -923,38 +1000,7 @@ Var_Parse(const char *str, /* The string to parse */ idx = classify_var(name.s, &name.e, &k); v = find_any_var(name.s, name.e, ctxt, idx, k); - if (v != NULL && (v->flags & POISONS) != 0) - poison_check(v); - if (v != NULL && (v->flags & VAR_DUMMY) == 0) { - if (v->flags & VAR_IN_USE) - Fatal("Variable %s is recursive.", v->name); - /*NOTREACHED*/ - else - v->flags |= VAR_IN_USE; - - /* Before doing any modification, we have to make sure the - * value has been fully expanded. If it looks like recursion - * might be necessary (there's a dollar sign somewhere in - * the variable's value) we just call Var_Subst to do any - * other substitutions that are necessary. Note that the - * value returned by Var_Subst will have been dynamically - * allocated, so it will need freeing when we return. - */ - val = var_get_value(v); - if (idx == GLOBAL_INDEX) { - if (strchr(val, '$') != NULL) { - val = Var_Subst(val, ctxt, err); - *freePtr = true; - } - } else if (idx >= LOCAL_SIZE) { - if (IS_EXTENDED_F(idx)) - val = Var_GetTail(val); - else - val = Var_GetHead(val); - *freePtr = true; - } - v->flags &= ~VAR_IN_USE; - } + val = get_expanded_value(v, idx, ctxt, err, freePtr); if (*tstr == ':' && paren != '\0') val = VarModifiers_Apply(val, &name, ctxt, err, freePtr, tstr, paren, lengthPtr); diff --git a/usr.bin/make/varmodifiers.c b/usr.bin/make/varmodifiers.c index 3efac907658..89804e4f430 100644 --- a/usr.bin/make/varmodifiers.c +++ b/usr.bin/make/varmodifiers.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: varmodifiers.c,v 1.16 2007/07/24 18:52:47 espie Exp $ */ +/* $OpenBSD: varmodifiers.c,v 1.17 2007/07/24 18:56:15 espie Exp $ */ /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */ /* diff --git a/usr.bin/make/varmodifiers.h b/usr.bin/make/varmodifiers.h index 057b109530f..2a11b45c819 100644 --- a/usr.bin/make/varmodifiers.h +++ b/usr.bin/make/varmodifiers.h @@ -2,7 +2,7 @@ #define VARMODIFIERS_H /* $OpenPackages$ */ -/* $OpenBSD: varmodifiers.h,v 1.5 2007/07/24 18:52:47 espie Exp $ */ +/* $OpenBSD: varmodifiers.h,v 1.6 2007/07/24 18:56:15 espie Exp $ */ /* * Copyright (c) 1999 Marc Espie. |