summaryrefslogtreecommitdiff
path: root/Src/text.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/text.c')
-rw-r--r--Src/text.c858
1 files changed, 550 insertions, 308 deletions
diff --git a/Src/text.c b/Src/text.c
index b7df8012f..ab6ca5eb9 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -31,7 +31,7 @@
#include "text.pro"
static char *tptr, *tbuf, *tlim;
-static int tsiz, tindent, tnewlins;
+static int tsiz, tindent, tnewlins, tjob;
/* add a character to the text buffer */
@@ -72,19 +72,18 @@ taddstr(char *s)
tptr += sl;
}
-#if 0
-/* add an integer to the text buffer */
-
/**/
-void
-taddint(int x)
+static void
+taddlist(Estate state, int num)
{
- char buf[DIGBUFSIZE];
-
- sprintf(buf, "%d", x);
- taddstr(buf);
+ if (num) {
+ while (num--) {
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddchr(' ');
+ }
+ tptr--;
+ }
}
-#endif
/* add a newline, or something equivalent, to the text buffer */
@@ -105,15 +104,26 @@ taddnl(void)
/* get a permanent textual representation of n */
/**/
-char *
-getpermtext(struct node *n)
+mod_export char *
+getpermtext(Eprog prog, Wordcode c)
{
+ struct estate s;
+
+ if (!c)
+ c = prog->prog;
+
+ s.prog = prog;
+ s.pc = c;
+ s.strs = prog->strs;
+
tnewlins = 1;
tbuf = (char *)zalloc(tsiz = 32);
tptr = tbuf;
tlim = tbuf + tsiz;
tindent = 1;
- gettext2(n);
+ tjob = 0;
+ if (prog->len)
+ gettext2(&s);
*tptr = '\0';
untokenize(tbuf);
return tbuf;
@@ -123,344 +133,587 @@ getpermtext(struct node *n)
/**/
char *
-getjobtext(struct node *n)
+getjobtext(Eprog prog, Wordcode c)
{
static char jbuf[JOBTEXTSIZE];
+ struct estate s;
+
+ if (!c)
+ c = prog->prog;
+
+ s.prog = prog;
+ s.pc = c;
+ s.strs = prog->strs;
+
tnewlins = 0;
tbuf = NULL;
tptr = jbuf;
tlim = tptr + JOBTEXTSIZE - 1;
tindent = 1;
- gettext2(n);
+ tjob = 1;
+ gettext2(&s);
*tptr = '\0';
untokenize(jbuf);
return jbuf;
}
-#define gt2(X) gettext2((struct node *) (X))
-
/*
- "gettext2" or "type checking and how to avoid it"
- an epic function by Paul Falstad
-*/
-
-#define _Cond(X) ((Cond) (X))
-#define _Cmd(X) ((Cmd) (X))
-#define _Pline(X) ((Pline) (X))
-#define _Sublist(X) ((Sublist) (X))
-#define _List(X) ((List) (X))
-#define _casecmd(X) ((struct casecmd *) (X))
-#define _ifcmd(X) ((struct ifcmd *) (X))
-#define _whilecmd(X) ((struct whilecmd *) (X))
+ * gettext2() shows one way to walk through the word code without
+ * recursion. We start by reading a word code and executing the
+ * action for it. Some codes have sub-structures (like, e.g. WC_FOR)
+ * and require something to be done after the sub-structure has been
+ * handled. For these codes a tstack structure which describes what
+ * has to be done is pushed onto a stack. Codes without sub-structures
+ * arrange for the next structure being taken from the stack so that
+ * the action for it is executed instead of the one for the next
+ * word code. If the stack is empty at this point, we have handled
+ * the whole structure we were called for.
+ */
+
+typedef struct tstack *Tstack;
+
+struct tstack {
+ Tstack prev;
+ wordcode code;
+ int pop;
+ union {
+ struct {
+ LinkList list;
+ } _redir;
+ struct {
+ char *strs;
+ Wordcode end;
+ } _funcdef;
+ struct {
+ Wordcode end;
+ } _case;
+ struct {
+ int cond;
+ Wordcode end;
+ } _if;
+ struct {
+ int par;
+ } _cond;
+ struct {
+ Wordcode end;
+ } _subsh;
+ } u;
+};
+
+static Tstack tstack, tfree;
+
+static Tstack
+tpush(wordcode code, int pop)
+{
+ Tstack s;
+
+ if ((s = tfree))
+ tfree = s->prev;
+ else
+ s = (Tstack) zalloc(sizeof(*s));
+
+ s->prev = tstack;
+ tstack = s;
+ s->code = code;
+ s->pop = pop;
+
+ return s;
+}
/**/
static void
-gettext2(struct node *n)
+gettext2(Estate state)
{
- Cmd nn;
-
- if (!n || ((List) n) == &dummy_list)
- return;
- switch (NT_TYPE(n->ntype)) {
- case N_LIST:
- gt2(_List(n)->left);
- if (_List(n)->type & Z_ASYNC) {
- taddstr(" &");
- if (_List(n)->type & Z_DISOWN)
- taddstr("|");
- }
- simplifyright(_List(n));
- if (_List(n)->right) {
- if (tnewlins)
- taddnl();
- else
- taddstr((_List(n)->type & Z_ASYNC) ? " " : "; ");
- gt2(_List(n)->right);
- }
- break;
- case N_SUBLIST:
- if (_Sublist(n)->flags & PFLAG_NOT)
- taddstr("! ");
- if (_Sublist(n)->flags & PFLAG_COPROC)
- taddstr("coproc ");
- gt2(_Sublist(n)->left);
- if (_Sublist(n)->right) {
- taddstr((_Sublist(n)->type == ORNEXT) ? " || " : " && ");
- gt2(_Sublist(n)->right);
- }
- break;
- case N_PLINE:
- gt2(_Pline(n)->left);
- if (_Pline(n)->type == PIPE) {
- taddstr(" | ");
- gt2(_Pline(n)->right);
+ Tstack s, n;
+ int stack = 0;
+ wordcode code;
+
+ while (1) {
+ if (stack) {
+ if (!(s = tstack))
+ return;
+ if (s->pop) {
+ tstack = s->prev;
+ s->prev = tfree;
+ tfree = s;
+ }
+ code = s->code;
+ stack = 0;
+ } else {
+ s = NULL;
+ code = *state->pc++;
}
- break;
- case N_CMD:
- nn = _Cmd(n);
- switch (nn->type) {
- case SIMPLE:
- getsimptext(nn);
+ switch (wc_code(code)) {
+ case WC_LIST:
+ if (!s) {
+ s = tpush(code, (WC_LIST_TYPE(code) & Z_END));
+ stack = 0;
+ } else {
+ if (WC_LIST_TYPE(code) & Z_ASYNC) {
+ taddstr(" &");
+ if (WC_LIST_TYPE(code) & Z_DISOWN)
+ taddstr("|");
+ }
+ if (!(stack = (WC_LIST_TYPE(code) & Z_END))) {
+ if (tnewlins)
+ taddnl();
+ else
+ taddstr((WC_LIST_TYPE(code) & Z_ASYNC) ? " " : "; ");
+ s->code = *state->pc++;
+ s->pop = (WC_LIST_TYPE(s->code) & Z_END);
+ }
+ }
+ if (!stack && (WC_LIST_TYPE(s->code) & Z_SIMPLE))
+ state->pc++;
+ break;
+ case WC_SUBLIST:
+ if (!s) {
+ if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_NOT)
+ taddstr("! ");
+ if (WC_SUBLIST_FLAGS(code) & WC_SUBLIST_COPROC)
+ taddstr("coproc ");
+ s = tpush(code, (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END));
+ } else {
+ if (!(stack = (WC_SUBLIST_TYPE(code) == WC_SUBLIST_END))) {
+ taddstr((WC_SUBLIST_TYPE(code) == WC_SUBLIST_OR) ?
+ " || " : " && ");
+ s->code = *state->pc++;
+ s->pop = (WC_SUBLIST_TYPE(s->code) == WC_SUBLIST_END);
+ if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_NOT)
+ taddstr("! ");
+ if (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_COPROC)
+ taddstr("coproc ");
+ }
+ }
+ if (!stack && (WC_SUBLIST_FLAGS(s->code) & WC_SUBLIST_SIMPLE))
+ state->pc++;
+ break;
+ case WC_PIPE:
+ if (!s) {
+ tpush(code, (WC_PIPE_TYPE(code) == WC_PIPE_END));
+ if (WC_PIPE_TYPE(code) == WC_PIPE_MID)
+ state->pc++;
+ } else {
+ if (!(stack = (WC_PIPE_TYPE(code) == WC_PIPE_END))) {
+ taddstr(" | ");
+ s->code = *state->pc++;
+ if (!(s->pop = (WC_PIPE_TYPE(s->code) == WC_PIPE_END)))
+ state->pc++;
+ }
+ }
break;
- case SUBSH:
- taddstr("( ");
- tindent++;
- gt2(nn->u.list);
- tindent--;
- taddstr(" )");
+ case WC_REDIR:
+ if (!s) {
+ state->pc--;
+ n = tpush(code, 1);
+ n->u._redir.list = ecgetredirs(state);
+ } else {
+ getredirs(s->u._redir.list);
+ stack = 1;
+ }
break;
- case ZCTIME:
- taddstr("time ");
- tindent++;
- gt2(nn->u.pline);
- tindent--;
+ case WC_ASSIGN:
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddchr('=');
+ if (WC_ASSIGN_TYPE(code) == WC_ASSIGN_ARRAY) {
+ taddchr('(');
+ taddlist(state, WC_ASSIGN_NUM(code));
+ taddstr(") ");
+ } else {
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddchr(' ');
+ }
break;
- case FUNCDEF:
- taddlist(nn->args);
- taddstr(" () {");
- tindent++;
- taddnl();
- gt2(nn->u.list);
- tindent--;
- taddnl();
- taddstr("}");
+ case WC_SIMPLE:
+ taddlist(state, WC_SIMPLE_ARGC(code));
+ stack = 1;
break;
- case CURSH:
- taddstr("{ ");
- tindent++;
- gt2(nn->u.list);
- tindent--;
- taddstr(" }");
+ case WC_SUBSH:
+ if (!s) {
+ taddstr("( ");
+ tindent++;
+ n = tpush(code, 1);
+ n->u._subsh.end = state->pc + WC_SUBSH_SKIP(code);
+ } else {
+ state->pc = s->u._subsh.end;
+ tindent--;
+ taddstr(" )");
+ stack = 1;
+ }
break;
- case CFOR:
- case CSELECT:
- taddstr((nn->type == CFOR) ? "for " : "select ");
- if (nn->u.forcmd->condition) {
- taddstr("((");
- taddstr(nn->u.forcmd->name);
- taddstr("; ");
- taddstr(nn->u.forcmd->condition);
- taddstr("; ");
- taddstr(nn->u.forcmd->advance);
- taddstr(")) do");
+ case WC_CURSH:
+ if (!s) {
+ taddstr("{ ");
+ tindent++;
+ n = tpush(code, 1);
+ n->u._subsh.end = state->pc + WC_CURSH_SKIP(code);
} else {
- taddstr(nn->u.forcmd->name);
- if (nn->u.forcmd->inflag) {
- taddstr(" in ");
- taddlist(nn->args);
- }
- taddnl();
- taddstr("do");
+ state->pc = s->u._subsh.end;
+ tindent--;
+ taddstr(" }");
+ stack = 1;
}
- tindent++;
- taddnl();
- gt2(nn->u.forcmd->list);
- tindent--;
- taddnl();
- taddstr("done");
break;
- case CIF:
- gt2(nn->u.ifcmd);
- taddstr("fi");
+ case WC_TIMED:
+ if (!s) {
+ taddstr("time");
+ if (WC_TIMED_TYPE(code) == WC_TIMED_PIPE) {
+ taddchr(' ');
+ tindent++;
+ tpush(code, 1);
+ } else
+ stack = 1;
+ } else {
+ tindent--;
+ stack = 1;
+ }
break;
- case CCASE:
- gt2(nn->u.casecmd);
+ case WC_FUNCDEF:
+ if (!s) {
+ Wordcode p = state->pc;
+ Wordcode end = p + WC_FUNCDEF_SKIP(code);
+
+ taddlist(state, *state->pc++);
+ if (tjob) {
+ taddstr(" () { ... }");
+ state->pc = end;
+ stack = 1;
+ } else {
+ taddstr(" () {");
+ tindent++;
+ taddnl();
+ n = tpush(code, 1);
+ n->u._funcdef.strs = state->strs;
+ n->u._funcdef.end = end;
+ state->strs += *state->pc;
+ state->pc += 3;
+ }
+ } else {
+ state->strs = s->u._funcdef.strs;
+ state->pc = s->u._funcdef.end;
+ tindent--;
+ taddnl();
+ taddstr("}");
+ stack = 1;
+ }
break;
- case COND:
- taddstr("[[ ");
- gt2(nn->u.cond);
- taddstr(" ]]");
+ case WC_FOR:
+ if (!s) {
+ taddstr("for ");
+ if (WC_FOR_TYPE(code) == WC_FOR_COND) {
+ taddstr("((");
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddstr("; ");
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddstr("; ");
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddstr(")) do");
+ } else {
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
+ taddstr(" in ");
+ taddlist(state, *state->pc++);
+ }
+ taddnl();
+ taddstr("do");
+ }
+ tindent++;
+ taddnl();
+ tpush(code, 1);
+ } else {
+ tindent--;
+ taddnl();
+ taddstr("done");
+ stack = 1;
+ }
break;
- case CARITH:
- taddstr("((");
- taddlist(nn->args);
- taddstr("))");
+ case WC_SELECT:
+ if (!s) {
+ taddstr("select ");
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ if (WC_SELECT_TYPE(code) == WC_SELECT_LIST) {
+ taddstr(" in ");
+ taddlist(state, *state->pc++);
+ }
+ tindent++;
+ taddnl();
+ tpush(code, 1);
+ } else {
+ tindent--;
+ taddnl();
+ taddstr("done");
+ stack = 1;
+ }
break;
- case CREPEAT:
- taddstr("repeat ");
- taddlist(nn->args);
- taddnl();
- taddstr("do");
- tindent++;
- taddnl();
- gt2(nn->u.list);
- tindent--;
- taddnl();
- taddstr("done");
+ case WC_WHILE:
+ if (!s) {
+ taddstr(WC_WHILE_TYPE(code) == WC_WHILE_UNTIL ?
+ "until " : "while ");
+ tindent++;
+ tpush(code, 0);
+ } else if (!s->pop) {
+ tindent--;
+ taddnl();
+ taddstr("do");
+ tindent++;
+ taddnl();
+ s->pop = 1;
+ } else {
+ tindent--;
+ taddnl();
+ taddstr("done");
+ stack = 1;
+ }
break;
- case CWHILE:
- gt2(nn->u.whilecmd);
+ case WC_REPEAT:
+ if (!s) {
+ taddstr("repeat ");
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddnl();
+ taddstr("do");
+ tindent++;
+ taddnl();
+ tpush(code, 1);
+ } else {
+ tindent--;
+ taddnl();
+ taddstr("done");
+ stack = 1;
+ }
break;
- }
- getredirs(nn);
- break;
- case N_COND:
- getcond(_Cond(n), 0);
- break;
- case N_CASE:
- {
- List *l;
- char **p;
-
- l = _casecmd(n)->lists;
- p = _casecmd(n)->pats;
-
- taddstr("case ");
- taddstr(*p++);
- taddstr(" in");
- tindent++;
- for (; *l; p++, l++) {
+ case WC_CASE:
+ if (!s) {
+ Wordcode end = state->pc + WC_CASE_SKIP(code);
+
+ taddstr("case ");
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddstr(" in");
+
+ if (state->pc >= end) {
+ if (tnewlins)
+ taddnl();
+ else
+ taddchr(' ');
+ taddstr("esac");
+ stack = 1;
+ } else {
+ tindent++;
+ if (tnewlins)
+ taddnl();
+ else
+ taddchr(' ');
+ code = *state->pc++;
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ state->pc++;
+ taddstr(") ");
+ tindent++;
+ n = tpush(code, 0);
+ n->u._case.end = end;
+ n->pop = (state->pc - 2 + WC_CASE_SKIP(code) >= end);
+ }
+ } else if (state->pc < s->u._case.end) {
+ tindent--;
+ taddstr(WC_CASE_TYPE(code) == WC_CASE_OR ? " ;;" : ";&");
if (tnewlins)
taddnl();
else
taddchr(' ');
- taddstr(*p + 1);
+ code = *state->pc++;
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ state->pc++;
taddstr(") ");
tindent++;
- gt2(*l);
+ s->code = code;
+ s->pop = ((state->pc - 2 + WC_CASE_SKIP(code)) >=
+ s->u._case.end);
+ } else {
+ tindent--;
+ taddstr(WC_CASE_TYPE(code) == WC_CASE_OR ? " ;;" : ";&");
tindent--;
- taddstr(" ;");
- taddchr(**p);
+ if (tnewlins)
+ taddnl();
+ else
+ taddchr(' ');
+ taddstr("esac");
+ stack = 1;
}
- tindent--;
- if (tnewlins)
- taddnl();
- else
- taddchr(' ');
- taddstr("esac");
break;
- }
- case N_IF:
- {
- List *i, *t;
+ case WC_IF:
+ if (!s) {
+ Wordcode end = state->pc + WC_IF_SKIP(code);
- taddstr("if ");
- for (i = _ifcmd(n)->ifls, t = _ifcmd(n)->thenls; *i; i++, t++) {
+ taddstr("if ");
tindent++;
- gt2(*i);
+ state->pc++;
+
+ n = tpush(code, 0);
+ n->u._if.end = end;
+ n->u._if.cond = 1;
+ } else if (s->pop) {
+ stack = 1;
+ } else if (s->u._if.cond) {
tindent--;
taddnl();
taddstr("then");
tindent++;
taddnl();
- gt2(*t);
+ s->u._if.cond = 0;
+ } else if (state->pc < s->u._if.end) {
tindent--;
taddnl();
- if (i[1]) {
+ code = *state->pc++;
+ if (WC_IF_TYPE(code) == WC_IF_ELIF) {
taddstr("elif ");
+ tindent++;
+ s->u._if.cond = 1;
+ } else {
+ taddstr("else");
+ tindent++;
+ taddnl();
}
- }
- if (*t) {
- taddstr("else");
- tindent++;
- taddnl();
- gt2(*t);
+ } else {
+ s->pop = 1;
tindent--;
taddnl();
+ taddstr("fi");
+ stack = 1;
}
break;
- }
- case N_WHILE:
- taddstr((_whilecmd(n)->cond) ? "until " : "while ");
- tindent++;
- gt2(_whilecmd(n)->cont);
- tindent--;
- taddnl();
- taddstr("do");
- tindent++;
- taddnl();
- gt2(_whilecmd(n)->loop);
- tindent--;
- taddnl();
- taddstr("done");
- break;
- }
-}
-
-/* Print a condition bracketed by [[ ... ]]. *
- * With addpar non-zero, parenthesise the subexpression. */
-
-/**/
-static void
-getcond(Cond nm, int addpar)
-{
- static char *c1[] =
- {
- "=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
- "-ne", "-lt", "-gt", "-le", "-ge"
- };
-
- if (addpar)
- taddstr("( ");
- switch (nm->type) {
- case COND_NOT:
- taddstr("! ");
- getcond(nm->left, _Cond(nm->left)->type <= COND_OR);
- break;
- case COND_AND:
- getcond(nm->left, _Cond(nm->left)->type == COND_OR);
- taddstr(" && ");
- getcond(nm->right, _Cond(nm->right)->type == COND_OR);
- break;
- case COND_OR:
- /* This is deliberately over-generous with parentheses: *
- * in fact omitting them gives correct precedence. */
- getcond(nm->left, _Cond(nm->left)->type == COND_AND);
- taddstr(" || ");
- getcond(nm->right, _Cond(nm->right)->type == COND_AND);
- break;
- default:
- if (nm->type <= COND_GE) {
- /* Binary test: `a = b' etc. */
- taddstr(nm->left);
- taddstr(" ");
- taddstr(c1[nm->type - COND_STREQ]);
- taddstr(" ");
- taddstr(nm->right);
- } else {
- /* Unary test: `-f foo' etc. */
- char c2[4];
-
- c2[0] = '-';
- c2[1] = nm->type;
- c2[2] = ' ';
- c2[3] = '\0';
- taddstr(c2);
- taddstr(nm->left);
- }
- break;
- }
- if (addpar)
- taddstr(" )");
-}
-
-/**/
-static void
-getsimptext(Cmd cmd)
-{
- LinkNode n;
-
- for (n = firstnode(cmd->vars); n; incnode(n)) {
- struct varasg *v = (struct varasg *)getdata(n);
-
- taddstr(v->name);
- taddchr('=');
- if (PM_TYPE(v->type) == PM_ARRAY) {
- taddchr('(');
- taddlist(v->arr);
- taddstr(") ");
- } else {
- taddstr(v->str);
- taddchr(' ');
+ case WC_COND:
+ {
+ static char *c1[] = {
+ "=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
+ "-ne", "-lt", "-gt", "-le", "-ge"
+ };
+
+ int ctype;
+
+ if (!s) {
+ taddstr("[[ ");
+ n = tpush(code, 1);
+ n->u._cond.par = 2;
+ } else if (s->u._cond.par == 2) {
+ taddstr(" ]]");
+ stack = 1;
+ break;
+ } else if (s->u._cond.par == 1) {
+ taddstr(" )");
+ stack = 1;
+ break;
+ } else if (WC_COND_TYPE(s->code) == COND_AND) {
+ taddstr(" && ");
+ code = *state->pc++;
+ if (WC_COND_TYPE(code) == COND_OR) {
+ taddstr("( ");
+ n = tpush(code, 1);
+ n->u._cond.par = 1;
+ }
+ } else if (WC_COND_TYPE(s->code) == COND_OR) {
+ taddstr(" || ");
+ code = *state->pc++;
+ if (WC_COND_TYPE(code) == COND_AND) {
+ taddstr("( ");
+ n = tpush(code, 1);
+ n->u._cond.par = 1;
+ }
+ }
+ while (!stack) {
+ switch ((ctype = WC_COND_TYPE(code))) {
+ case COND_NOT:
+ taddstr("! ");
+ code = *state->pc++;
+ if (WC_COND_TYPE(code) <= COND_OR) {
+ taddstr("( ");
+ n = tpush(code, 1);
+ n->u._cond.par = 1;
+ }
+ break;
+ case COND_AND:
+ n = tpush(code, 1);
+ n->u._cond.par = 0;
+ code = *state->pc++;
+ if (WC_COND_TYPE(code) == COND_OR) {
+ taddstr("( ");
+ n = tpush(code, 1);
+ n->u._cond.par = 1;
+ }
+ break;
+ case COND_OR:
+ n = tpush(code, 1);
+ n->u._cond.par = 0;
+ code = *state->pc++;
+ if (WC_COND_TYPE(code) == COND_AND) {
+ taddstr("( ");
+ n = tpush(code, 1);
+ n->u._cond.par = 1;
+ }
+ break;
+ case COND_MOD:
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddchr(' ');
+ taddlist(state, WC_COND_SKIP(code));
+ stack = 1;
+ break;
+ case COND_MODI:
+ {
+ char *name = ecgetstr(state, EC_NODUP, NULL);
+
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddchr(' ');
+ taddstr(name);
+ taddchr(' ');
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ stack = 1;
+ }
+ break;
+ default:
+ if (ctype <= COND_GE) {
+ /* Binary test: `a = b' etc. */
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddstr(" ");
+ taddstr(c1[ctype - COND_STREQ]);
+ taddstr(" ");
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ if (ctype == COND_STREQ ||
+ ctype == COND_STRNEQ)
+ state->pc++;
+ } else {
+ /* Unary test: `-f foo' etc. */
+ char c2[4];
+
+ c2[0] = '-';
+ c2[1] = ctype;
+ c2[2] = ' ';
+ c2[3] = '\0';
+ taddstr(c2);
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ }
+ stack = 1;
+ break;
+ }
+ }
+ }
+ break;
+ case WC_ARITH:
+ taddstr("((");
+ taddstr(ecgetstr(state, EC_NODUP, NULL));
+ taddstr("))");
+ stack = 1;
+ break;
+ case WC_END:
+ stack = 1;
+ break;
+ default:
+ DPUTS(1, "unknown word code in gettext2()");
+ return;
}
}
- taddlist(cmd->args);
}
/**/
void
-getredirs(Cmd cmd)
+getredirs(LinkList redirs)
{
LinkNode n;
static char *fstr[] =
@@ -468,10 +721,9 @@ getredirs(Cmd cmd)
">", ">|", ">>", ">>|", "&>", "&>|", "&>>", "&>>|", "<>", "<",
"<<", "<<-", "<<<", "<&", ">&", NULL /* >&- */, "<", ">"
};
-
taddchr(' ');
- for (n = firstnode(cmd->redir); n; incnode(n)) {
- struct redir *f = (struct redir *)getdata(n);
+ for (n = firstnode(redirs); n; incnode(n)) {
+ Redir f = (Redir) getdata(n);
switch (f->type) {
case WRITE:
@@ -493,7 +745,12 @@ getredirs(Cmd cmd)
taddchr('0' + f->fd1);
taddstr(fstr[f->type]);
taddchr(' ');
- taddstr(f->name);
+ if (f->type == HERESTR) {
+ taddchr('\'');
+ taddstr(bslashquote(f->name, NULL, 1));
+ taddchr('\'');
+ } else
+ taddstr(f->name);
taddchr(' ');
break;
#ifdef DEBUG
@@ -509,18 +766,3 @@ getredirs(Cmd cmd)
}
tptr--;
}
-
-/**/
-static void
-taddlist(LinkList l)
-{
- LinkNode n;
-
- if (!(n = firstnode(l)))
- return;
- for (; n; incnode(n)) {
- taddstr(getdata(n));
- taddchr(' ');
- }
- tptr--;
-}