commit 517ced5334f62771153cc16c73ba382c7da42f8e
parent 4648857ce124cff7bbe41f29cfadf0f8a2393b1e
Author: Toby Goodwin <toby@paccrat.org>
Date: Mon, 1 Sep 2014 22:39:21 +0100
fix both Zekoll and Neukirchen bugs
Diffstat:
3 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/footobar.c b/footobar.c
@@ -75,7 +75,8 @@ static bool Tconv(Format *f, int ignore) {
case nForin: fmtprint(f, "for(%T in %T)%T", n->u[0].p, n->u[1].p, n->u[2].p); break;
case nVarsub: fmtprint(f, "$%T(%T)", n->u[0].p, n->u[1].p); break;
case nWord:
- fmtprint(f, quotep(n->u[0].s, dollar) ? "%#S" : "%S", n->u[0].s);
+ fmtprint(f, n->u[2].i && quotep(n->u[0].s, dollar) ?
+ "%#S" : "%S", n->u[0].s);
break;
case nLappend: {
static bool inlist;
diff --git a/lex.c b/lex.c
@@ -35,6 +35,7 @@ static void getpair(int);
int lineno;
+/* lookup table for non-word characters */
const char nw[] = {
1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
@@ -46,6 +47,7 @@ const char nw[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
+/* lookup table for non-word characters in variable names */
const char dnw[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
@@ -57,6 +59,18 @@ const char dnw[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
+/* lookup table for quotable characters: nw + glob metachars */
+const char q[] = {
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
static size_t bufsize = BUFSIZE;
static char *realbuf = NULL;
static bool newline = FALSE;
@@ -76,7 +90,7 @@ extern bool quotep(char *s, bool dollar) {
unsigned char c;
const char *meta;
- meta = dollar ? dnw : nw;
+ meta = dollar ? dnw : q;
while ((c = *s++))
if (meta[c])
return TRUE;
@@ -97,7 +111,6 @@ extern int yylex() {
}
/* rc variable-names may contain only alnum, '*' and '_', so use dnw if we are scanning one. */
meta = (dollar ? dnw : nw);
- dollar = FALSE;
if (newline) {
--lineno; /* slight space optimization; nextline() always increments lineno */
nextline();
@@ -105,6 +118,7 @@ extern int yylex() {
}
top: while ((c = gchar()) == ' ' || c == '\t')
w = NW;
+ if (c != '(') dollar = FALSE;
if (c == EOF)
return END;
if (!meta[(unsigned char) c]) { /* it's a word or keyword. */
@@ -225,7 +239,7 @@ top: while ((c = gchar()) == ' ' || c == '\t')
i = 0;
goto bs;
case '(':
- if (w == RW) /* SUB's happen only after real words, not keyowrds, so if () and while () work */
+ if (w == RW) /* SUB's happen only after real words, not keywords, so if () and while () work */
c = SUB;
w = NW;
return c;
diff --git a/tree.c b/tree.c
@@ -81,7 +81,7 @@ extern Node *treecpy(Node *s, void *(*alloc)(size_t)) {
n->u[2].i = s->u[2].i;
break;
case nWord:
- n = (*alloc)(offsetof(Node, u[2]));
+ n = (*alloc)(offsetof(Node, u[3]));
n->u[0].s = strcpy((char *) (*alloc)(strlen(s->u[0].s) + 1), s->u[0].s);
if (s->u[1].s != NULL) {
size_t i = strlen(s->u[0].s);
@@ -89,6 +89,7 @@ extern Node *treecpy(Node *s, void *(*alloc)(size_t)) {
memcpy(n->u[1].s, s->u[1].s, i);
} else
n->u[1].s = NULL;
+ n->u[2].i = s->u[2].i;
break;
case nBang: case nNowait: case nCase:
case nCount: case nFlat: case nRmfn: case nSubshell: case nVar: