diff --git a/src/frontend/variable.c b/src/frontend/variable.c index 3a241bb2a..5bc2c1f93 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -789,7 +789,7 @@ cp_getvar(char *name, enum cp_types type, void *retval, size_t rsize) * isset is TRUE if the variable is being set, FALSE if unset. Also * required is a routine cp_enqvar(name) which returns a struct * variable *, which allows the host program to provide values for - * non-cshpar variables. See line 855 */ + * non-cshpar variables. */ /* Non-alphanumeric characters that may appear in variable names. < is very * special... @@ -806,10 +806,11 @@ cp_getvar(char *name, enum cp_types type, void *retval, size_t rsize) * Return value * Address of the first character after the variable name. */ -char *span_var_expr(char *t) +char *span_var_expr(char *s) { - int parenthesis = 0; - int brackets = 0; + char *t = s; + int parenthesis = 0; + int brackets = 0; while (*t && (isalnum_c(*t) || strchr(VALIDCHARS, *t))) switch (*t++) @@ -832,6 +833,14 @@ char *span_var_expr(char *t) if (--parenthesis <= 0) return t; break; + case '$': + if (brackets <= 0 && parenthesis <= 0) { + if (t == s + 1) // Special case: "$$". + return t; + else + return t-1; + } + break; default: break; } @@ -1000,6 +1009,8 @@ wordlist *vareval(/* NOT const */ char *string) if (eq(v->va_name, string)) break; if (!v && isdigit_c(*string)) { + /* Treat $i for some integer i as argv[i] - positional parameters. */ + for (v = variables; v; v = v->va_next) { if (eq(v->va_name, "argv")) { break;