aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
Diffstat (limited to 'toys')
-rw-r--r--toys/pending/sh.c138
1 files changed, 20 insertions, 118 deletions
diff --git a/toys/pending/sh.c b/toys/pending/sh.c
index 939048ae..482639da 100644
--- a/toys/pending/sh.c
+++ b/toys/pending/sh.c
@@ -353,7 +353,6 @@ static void expand_arg(struct sh_arg *arg, char *old, unsigned flags,
{
struct brace {
struct brace *next, *prev, *stack;
-int debug;
int active, cnt, idx, commas[];
} *bb = 0, *blist = 0, *bstk, *bnext;
int i, j;
@@ -366,25 +365,20 @@ int debug;
if (bb && (!old[i] || old[i] == '}')) {
bb->active = bb->commas[bb->cnt+1] = i;
for (bnext = bb; bb && bb->active; bb = (bb==blist)?0:bb->prev);
-dprintf(2, "}[%d]%p@%d\n", bnext->cnt, bb, i);
- // discard commaless brace (from start of list or middle)
- if (!old[i] || !bnext->cnt)
+ if (!old[i] || !bnext->cnt) // discard commaless brace from start/middle
free(dlist_pop((blist == bnext) ? &blist : &bnext));
} else if (old[i] == '{') {
dlist_add_nomalloc((void *)&blist,
(void *)(bb = xzalloc(sizeof(struct brace)+34*4)));
-dprintf(2, "{%p@%d %c\n", bb, i, bb->debug = old[i+1]);
bb->commas[0] = i;
} else if (!bb) continue;
else if (bb && old[i] == ',') {
-dprintf(2, ",%p@%d\t%c\n", bb, i, old[i+1]);
if (bb->cnt && !(bb->cnt&31)) {
dlist_lpop(&blist);
dlist_add_nomalloc((void *)&blist,
(void *)(bb = xrealloc(bb, sizeof(struct brace)+(bb->cnt+34)*4)));
}
bb->commas[++bb->cnt] = i;
-dprintf(2, "cnt %c %d\n", bb->debug, bb->cnt);
}
}
@@ -392,33 +386,6 @@ dprintf(2, "cnt %c %d\n", bb->debug, bb->cnt);
// If none, pass on verbatim
if (!blist) return expand_arg_nobrace(arg, old, flags, delete);
-dprintf(2, "got here\n");
-for (bstk = blist; bstk; bstk = (bstk->next == blist) ? 0 : bstk->next) {
- dprintf(2, "murf %c %d %p", bstk->debug, bstk->cnt, bstk);
- for (i = 0; i<=bstk->cnt+1; i++) dprintf(2, " %d", bstk->commas[i]);
- dprintf(2, "\n");
-}
-
-// span from "{ to }" or ", to }" or "{ to ," uninterrupted by other spans
-// span from "{ to {" or ", to {" or "start to {"
-// span from "} to }" or "} to ," or "} to end"
-// span from } to {
-
-/*
-A prefix - because new { with no parent
- B prefix - becaue new - in comma span
- C span - because next after this comma span
- E suffix - because next after this comma span
- skipped comma span
- J sibling -
- K span -
-*/
-
-//the problem is we need previous bstk at _same_ level when sibling.
-//postprocess bb to next, so can't be _here.
-
-// span is active if ~parent or in parent's active comma span
-
// enclose entire range in top level brace.
(bstk = xzalloc(sizeof(struct brace)+8))->commas[1] = strlen(old)+1;
bstk->commas[0] = -1;
@@ -426,150 +393,85 @@ A prefix - because new { with no parent
// loop through each combination
for (;;) {
-dprintf(2, "combination");
-for (bb = blist; bb; bb = (bb->next == blist) ? 0 : bb->next)
- dprintf(2, " %c %d", bb->debug, bb->idx);
-dprintf(2, "\n");
-
// Brace expansion can't be longer than original string. Keep start to {
s = ss = xmalloc(bstk->commas[1]);
// Append output from active braces (in "saved" list)
for (bb = blist; bb;) {
-dprintf(2, "--- start loop span %c stk %c\n", bb->debug, bstk->debug);
+
// keep prefix and push self onto stack
if (bstk == bb) bstk = bstk->stack; // pop self
i = bstk->commas[bstk->idx]+1;
-dprintf(2, "idx=%d i=%d o=%d cc=%d\n", bb->idx, i, bb->commas[0], bstk->commas[bstk->cnt+1]);
if (bstk->commas[bstk->cnt+1]>bb->commas[0])
s = stpncpy(s, old+i, bb->commas[0]-i);
-//murgle this is wrong for post-sibling span
-//how to distinguish enclosing stack from left sibling?
-
-//murgle: _end_ of previous segment stack output, not start.
-//but enclosing one had no comma, so no end?
-dprintf(2, "========%ld %.*s prefix for %c\n", s-ss, (int)(s-ss), ss, bb->debug);
// pop sibling
- if (bstk->commas[bstk->cnt+1]<bb->commas[0]) {
-dprintf(2, "sibling pop %c to %c\n", bstk->debug, bstk->stack->debug);
- bstk = bstk->stack;
-}
+ if (bstk->commas[bstk->cnt+1]<bb->commas[0]) bstk = bstk->stack;
bb->stack = bstk; // push
bb->active = 1;
bstk = bnext = bb;
-dprintf(2, "pushed %c\n", bb->debug);
-dprintf(2, "bnext %p\n",bnext);
+
// skip inactive spans from earlier or later commas
while ((bnext = (bnext->next==blist) ? 0 : bnext->next)) {
-dprintf(2, "bnext %p\n", bnext);
-dprintf(2, "maybe %c %d %d\n", bnext->debug, bnext->commas[0], bb->commas[bb->idx]);
i = bnext->commas[0];
+
// past end of this brace
- if (i>bb->commas[bb->cnt+1]) {
-dprintf(2, "exit 1 %d %d\n", i, bb->commas[bb->cnt+1]);
- break;
-}
-dprintf(2, "bnext=%c\n", bnext->debug);
+ if (i>bb->commas[bb->cnt+1]) break;
+
// in this brace but not this selection
if (i<bb->commas[bb->idx] || i>bb->commas[bb->idx+1]) {
bnext->active = 0;
bnext->stack = 0;
- // in this selection!
- } else {
-dprintf(2, "exit 2\n");
- break;
-}
-dprintf(2, "skipped %c because %d < %d\n", bnext->debug, bnext->commas[0], bb->commas[bb->idx]);
+
+ // in this selection
+ } else break;
}
-dprintf(2, "bnext now %p\n", bnext);
-if (bnext) dprintf(2, "bnext=%c\n", bnext->debug);
+
// is next span past this range?
-if (bnext) dprintf(2, "bnexts=%c %c %d %d\n", bnext->debug, bb->debug, bnext->commas[0], bb->commas[bb->idx]+1);
if (!bnext || bnext->commas[0]>bb->commas[bb->idx+1]) {
-dprintf(2, "span %d\n", bstk->idx);
+
// output uninterrupted span
i = bb->commas[bstk->idx]+1;
s = stpncpy(s, old+i, bb->commas[bb->idx+1]-i);
-dprintf(2, "span output %d %d\n", i, bstk->commas[bstk->idx+1]);
-dprintf(2, "=======2=%ld %.*s span for %c\n", s-ss, (int)(s-ss), ss, bstk->debug);
// While not sibling, output tail and pop
while (!bnext || bnext->commas[0] > bstk->commas[bstk->cnt+1]) {
-dprintf(2, "bstk=%p bnext=%p\n", bstk, bnext);
-if (bnext) dprintf(2, "pop %c vs %c because %d > %d\n", bstk->debug, bnext->debug, bnext->commas[0], bstk->commas[bstk->cnt+1]);
if (!(bb = bstk->stack)) break;
-
-/*
- ok, failing active span is e,f: 4th span, print nothing after it (20,20)
- first 20: 4[cnt+1], second 20: 1[idx+1]
- j=1[idx+1]-i=4[cnt+1]
-*/
-
-if (bnext) dprintf(2, "parent %c next %c\n", bb->debug, bnext->debug);
i = bstk->commas[bstk->cnt+1]+1; // start of span
j = bb->commas[bb->idx+1]; // enclosing comma span
-char *typetype = "tail";
-dprintf(2, "what j=%d bb->idx=%d\n", j, bb->idx);
-dprintf(2, "bnext %c %d %d\n", bnext ? bnext->debug : '.', bnext ? bnext->commas[0] : 0, bnext ? bnext->commas[1] : 0);
-if (bnext) dprintf(2, "j=%d or j=%d\n", j, bnext->commas[0]);
-if (bnext) dprintf(2, "%c vs %c %d %d\n", bnext->debug, bstk->debug, bnext->commas[0], bstk->stack->commas[bstk->stack->cnt+1]);
while (bnext) {
if (bnext->commas[0]<j) {
j = bnext->commas[0];// sibling
break;
-typetype="sibling";
} else if (bb->commas[bb->cnt+1]>bnext->commas[0])
bnext = (bnext->next == blist) ? 0 : bnext->next;
else break;
-if (bnext) dprintf(2, "bnext=%c %c nc=%d bbc=%d\n", bnext->debug, bb->debug, bnext->commas[0], bb->commas[bb->cnt+1]);
}
-dprintf(2, "emit %d to %d\n", i, j);
s = stpncpy(s, old+i, j-i);
-dprintf(2, "=======3=%ld %.*s suffix for %c is %s\n", s-ss, (int)(s-ss), ss, bstk->debug, typetype);
// if next is sibling but parent _not_ a sibling, don't pop
if (bnext && bnext->commas[0]<bstk->stack->commas[bstk->stack->cnt+1])
break;
-
-dprintf(2, "pop %c", bstk->debug);
bstk = bstk->stack;
-dprintf(2, " now %c with %p\n", bstk ? bstk->debug : '.', bnext);
}
-dprintf(2, "out\n");
}
-if (bb && bnext) dprintf(2, "advance %c to %c (%c)\n", bb->debug, bnext->debug, blist->debug);
bb = (bnext == blist) ? 0 : bnext;
-dprintf(2, "down\n");
}
-dprintf(2, "increment\n");
- // increment
-
-//dprintf(1, "ss=%s\n", ss);
+ // Save result
expand_arg_nobrace(arg, ss, flags|FORCE_KEEP, delete);
+ // increment
for (bb = blist->prev; bb; bb = (bb == blist) ? 0 : bb->prev) {
-dprintf(2, "inky %c %p\n", bb->debug, bb->stack);
- if (!bb->stack) {
-dprintf(2, "skip\n");
- continue;
-}
- else if (++bb->idx > bb->cnt) {
-dprintf(2, "roll bb->idx=%d bb->cnt=%d\n", bb->idx, bb->cnt);
- bb->idx = 0;
-}
- else {
-dprintf(2, "Incremented %c to %d\n", bb->debug, bb->idx);
- break;
-}
- }
- if (!bb) {
- llist_traverse(blist, free);
- return;
+ if (!bb->stack) continue;
+ else if (++bb->idx > bb->cnt) bb->idx = 0;
+ else break;
}
+
+ // if increment went off left edge, done expanding
+ if (!bb) return llist_traverse(blist, free);
}
}