1fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes/*	$OpenBSD: tree.c,v 1.21 2015/09/01 13:12:31 tedu Exp $	*/
25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*-
4c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes *		 2011, 2012, 2013, 2015, 2016
6fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes *	mirabilos <m@mirbsd.org>
75155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *
85155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Provided that these terms and disclaimer and all copyright notices
95155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are retained or reproduced in an accompanying document, permission
105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is granted to deal in this work without restriction, including un-
115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * limited rights to use, publicly perform, distribute, sell, modify,
125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * merge, give away, or sublicence.
135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *
145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the utmost extent permitted by applicable law, neither express nor
165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * implied; without malicious intent or gross negligence. In no event
175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * may a licensor, author or contributor be held liable for indirect,
185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * direct, other damage, loss, or other issues arising in any way out
195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of dealing in the work, even if advised of the possibility of such
205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * damage or existence of a defect, except proven that it results out
215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of said person's immediate fault when using the work as intended.
225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "sh.h"
255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.86 2016/07/25 00:04:48 tg Exp $");
275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define INDENT	8
295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void ptree(struct op *, int, struct shf *);
31811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserstatic void pioact(struct shf *, struct ioword *);
3203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *wdvarput(struct shf *, const char *, int, int);
335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void vfptreef(struct shf *, int, const char *, va_list);
345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct ioword **iocopy(struct ioword **, Area *);
355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void iofree(struct ioword **, Area *);
365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
3703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* "foo& ; bar" and "foo |& ; bar" are invalid */
3803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic bool prevent_semicolon;
3903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
40c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char Telif_pT[] = "elif %T";
41c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * print a command tree
445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruptree(struct op *t, int indent, struct shf *shf)
475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	const char **w;
495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword **ioact;
505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct op *t1;
5103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	int i;
5277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes	const char *ccp;
535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Chain:
555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t == NULL)
565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		return;
575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	switch (t->type) {
585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TCOM:
59c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		prevent_semicolon = false;
6077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		/* special-case 'var=<<EOF' (cf. exec.c:execute) */
61c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (
6277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    /* we have zero arguments, i.e. no program to run */
63c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    t->args[0] == NULL &&
64c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    /* we have exactly one variable assignment */
65c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    t->vars[0] != NULL && t->vars[1] == NULL &&
66c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    /* we have exactly one I/O redirection */
67c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    t->ioact != NULL && t->ioact[0] != NULL &&
68c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    t->ioact[1] == NULL &&
69c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    /* of type "here document" (or "here string") */
7077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    (t->ioact[0]->ioflag & IOTYPE) == IOHERE &&
7177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    /* the variable assignment begins with a valid varname */
7277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    (ccp = skip_wdvarname(t->vars[0], true)) != t->vars[0] &&
7377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    /* and has no right-hand side (i.e. "varname=") */
7477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    ccp[0] == CHAR && ((ccp[1] == '=' && ccp[2] == EOS) ||
7577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    /* or "varname+=" */ (ccp[1] == '+' && ccp[2] == CHAR &&
7677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    ccp[3] == '=' && ccp[4] == EOS))) {
7777740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			fptreef(shf, indent, Tf_S, t->vars[0]);
78c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			break;
79c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
80c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
8103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->vars) {
8203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
8303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w)
8477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				fptreef(shf, indent, Tf_S_, *w++);
8503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("#no-vars# ", shf);
8703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->args) {
8803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = t->args;
8903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w)
9077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				fptreef(shf, indent, Tf_S_, *w++);
9103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("#no-args# ", shf);
935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TEXEC:
955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		t = t->left;
965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		goto Chain;
975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TPAREN:
985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent + 2, "( %T) ", t->left);
995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TPIPE:
1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T| ", t->left);
1025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		t = t->right;
1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		goto Chain;
1045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TLIST:
1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T%;", t->left);
1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		t = t->right;
1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		goto Chain;
1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TOR:
1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TAND:
1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T%s %T",
11103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		    t->left, (t->type == TOR) ? "||" : "&&", t->right);
1125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TBANG:
1145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts("! ", shf);
11503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = false;
1165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		t = t->right;
1175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		goto Chain;
11803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	case TDBRACKET:
11903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		w = t->args;
1205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts("[[", shf);
12103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*w)
12277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			fptreef(shf, indent, Tf__S, *w++);
1235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts(" ]] ", shf);
1245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TSELECT:
1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TFOR:
12703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, indent, "%s %s ",
12803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		    (t->type == TFOR) ? "for" : Tselect, t->str);
1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (t->vars != NULL) {
1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("in ", shf);
13103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
13203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w)
13377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				fptreef(shf, indent, Tf_S_, *w++);
13477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			fptreef(shf, indent, Tft_end);
1355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
1365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent + INDENT, "do%N%T", t->left);
1375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%;done ");
1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TCASE:
1405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "case %S in", t->str);
1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		for (t1 = t->left; t1 != NULL; t1 = t1->right) {
1425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			fptreef(shf, indent, "%N(");
14303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t1->vars;
14403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
1455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				fptreef(shf, indent, "%S%c", *w,
1465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				    (w[1] != NULL) ? '|' : ')');
14703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				++w;
14803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
14903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			fptreef(shf, indent + INDENT, "%N%T%N;%c", t1->left,
15003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    t1->u.charflag);
1515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
1525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%Nesac ");
1535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TELIF:
15577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		internal_errorf(TELIF_unexpected);
15603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/* FALLTHROUGH */
15703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	case TIF:
15803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		i = 2;
159c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		t1 = t;
16003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto process_TIF;
16103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		do {
162c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			t1 = t1->right;
16303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
16477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			fptreef(shf, indent, Tft_end);
16503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra process_TIF:
16603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			/* 5 == strlen("elif ") */
167c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			fptreef(shf, indent + 5 - i, Telif_pT + i, t1->left);
168c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			t1 = t1->right;
169c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			if (t1->left != NULL) {
17077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				fptreef(shf, indent, Tft_end);
17103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				fptreef(shf, indent + INDENT, "%s%N%T",
172c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				    "then", t1->left);
1735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			}
174c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		} while (t1->right && t1->right->type == TELIF);
175c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (t1->right != NULL) {
17677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			fptreef(shf, indent, Tft_end);
17703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			fptreef(shf, indent + INDENT, "%s%N%T",
178c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			    "else", t1->right);
1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%;fi ");
1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TWHILE:
1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TUNTIL:
184c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* 6 == strlen("while "/"until ") */
18577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		fptreef(shf, indent + 6, Tf_s_T,
18603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		    (t->type == TWHILE) ? "while" : "until",
1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    t->left);
18877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		fptreef(shf, indent, Tft_end);
18903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, indent + INDENT, "do%N%T", t->right);
1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%;done ");
1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TBRACE:
19303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, indent + INDENT, "{%N%T", t->left);
1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%;} ");
1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TCOPROC:
1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T|& ", t->left);
19803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = true;
1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TASYNC:
2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T& ", t->left);
20203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = true;
2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TFUNCT:
20503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fpFUNCTf(shf, indent, tobool(t->u.ksh_func), t->str, t->left);
2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TTIME:
20877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		fptreef(shf, indent, Tf_s_T, Ttime, t->left);
2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	default:
2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts("<botch>", shf);
21203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = false;
2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if ((ioact = t->ioact) != NULL) {
21603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		bool need_nl = false;
2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		while (*ioact != NULL)
219811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			pioact(shf, *ioact++);
2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		/* Print here documents after everything else... */
22103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		ioact = t->ioact;
22203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*ioact != NULL) {
2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			struct ioword *iop = *ioact++;
2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
22503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			/* heredoc is NULL when tracing (set -x) */
226b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes			if ((iop->ioflag & (IOTYPE | IOHERESTR)) == IOHERE &&
22703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    iop->heredoc) {
22803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
2295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_puts(iop->heredoc, shf);
23077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				fptreef(shf, indent, Tf_s,
2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				    evalstr(iop->delim, 0));
23203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				need_nl = true;
2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			}
2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
23503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/*
23603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		 * Last delimiter must be followed by a newline (this
23703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		 * often leads to an extra blank line, but it's not
23803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		 * worth worrying about)
2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		 */
240c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (need_nl) {
24103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
242c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			prevent_semicolon = true;
243c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
248811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserpioact(struct shf *shf, struct ioword *iop)
2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
250b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes	unsigned short flag = iop->ioflag;
251b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes	unsigned short type = flag & IOTYPE;
252b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes	short expected;
2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	expected = (type == IOREAD || type == IORDWR || type == IOHERE) ? 0 :
2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	    (type == IOCAT || type == IOWRITE) ? 1 :
2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	    (type == IODUP && (iop->unit == !(flag & IORDUP))) ? iop->unit :
2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	    iop->unit + 1;
2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (iop->unit != expected)
25977740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		shf_fprintf(shf, Tf_d, (int)iop->unit);
2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	switch (type) {
2625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOREAD:
263811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		shf_putc('<', shf);
2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOHERE:
266811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		shf_puts("<<", shf);
267811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		if (flag & IOSKIP)
268811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc('-', shf);
269fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		else if (flag & IOHERESTR)
270fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			shf_putc('<', shf);
2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOCAT:
27303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts(">>", shf);
2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOWRITE:
276811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		shf_putc('>', shf);
277811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		if (flag & IOCLOB)
278811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc('|', shf);
2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IORDWR:
28103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts("<>", shf);
2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IODUP:
2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts(flag & IORDUP ? "<&" : ">&", shf);
2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
28703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* name/delim are NULL when printing syntax errors */
2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (type == IOHERE) {
289fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		if (iop->delim && !(iop->ioflag & IONDELIM))
290c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			wdvarput(shf, iop->delim, 0, WDS_TPUTS);
291fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes	} else if (iop->ioname) {
292b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes		if (flag & IONAMEXP)
293fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			print_value_quoted(shf, iop->ioname);
294811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		else
295fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			wdvarput(shf, iop->ioname, 0, WDS_TPUTS);
296811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser	}
297fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes	shf_putc(' ', shf);
29803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	prevent_semicolon = false;
2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
30103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* variant of fputs for ptreef and wdstrip */
30203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *
30303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrawdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
30503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	int c;
306c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	const char *cs;
3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
30803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/*-
30903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	 * problems:
3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	`...` -> $(...)
3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	'foo' -> "foo"
31203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	 *	x${foo:-"hi"} -> x${foo:-hi} unless WDS_TPUTS
313fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes	 *	x${foo:-'hi'} -> x${foo:-hi}
3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 * could change encoding to:
3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	OQUOTE ["'] ... CQUOTE ["']
3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	COMSUB [(`] ...\0	(handle $ ` \ and maybe " in `...` case)
3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 */
31803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1)
3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		switch (*wp++) {
3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EOS:
32103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (--wp);
3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case ADELIM:
323fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			if (*wp == /*{*/'}') {
324fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes				++wp;
325fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes				goto wdvarput_csubst;
326fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			}
32777740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			/* FALLTHROUGH */
3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CHAR:
32903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = *wp++;
33003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
33277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		case QCHAR:
3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			c = *wp++;
33477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			if (opmode & WDS_TPUTS)
33577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				switch (c) {
33677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				case '\n':
33777740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes					if (quotelevel == 0) {
33877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes						c = '\'';
33977740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes						shf_putc(c, shf);
34077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes						shf_putc('\n', shf);
34177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes					}
34277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes					break;
34377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				default:
34477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes					if (quotelevel == 0)
34577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes						/* FALLTHROUGH */
34677740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				case '"':
34777740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				case '`':
34877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				case '$':
34977740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				case '\\':
35077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes					  shf_putc('\\', shf);
35177740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes					break;
35277740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				}
35303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
3545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case COMSUB:
3565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("$(", shf);
357c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = ")";
358c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser pSUB:
35903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
36003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
361c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(cs, shf);
3625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
363c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
364811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			c = ' ';
365811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			if (0)
366811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser				/* FALLTHROUGH */
367811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		case VALSUB:
368811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			  c = '|';
369811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc('$', shf);
370811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc('{', shf);
371811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc(c, shf);
372c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = ";}";
373c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto pSUB;
3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EXPRSUB:
3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("$((", shf);
376c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = "))";
377c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto pSUB;
3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OQUOTE:
37903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_TPUTS) {
38003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				quotelevel++;
38103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('"', shf);
38203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CQUOTE:
38503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_TPUTS) {
38603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (quotelevel)
38703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					quotelevel--;
38803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('"', shf);
38903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OSUBST:
39203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('$', shf);
3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (*wp++ == '{')
39403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('{', shf);
3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while ((c = *wp++) != 0)
39603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
39703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			wp = wdvarput(shf, wp, 0, opmode);
3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CSUBST:
400fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			if (*wp++ == '}') {
401fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes wdvarput_csubst:
40203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('}', shf);
403fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			}
40403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (wp);
4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OPAT:
406fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			shf_putchar(*wp++, shf);
407fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			shf_putc('(', shf);
4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case SPAT:
41003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = '|';
41103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (0)
4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CPAT:
41303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				c = /*(*/ ')';
41403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is the _only_ way to reliably handle
4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * variable args with an ANSI compiler
4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* VARARGS */
42403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querufptreef(struct shf *shf, int indent, const char *fmt, ...)
4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_list va;
4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_start(va, fmt);
4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	vfptreef(shf, indent, fmt, va);
4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_end(va);
4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* VARARGS */
4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
43603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrasnptreef(char *s, ssize_t n, const char *fmt, ...)
4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_list va;
4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct shf shf;
4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	shf_sopen(s, n, SHF_WR | (s ? 0 : SHF_DYNAMIC), &shf);
4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_start(va, fmt);
4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	vfptreef(&shf, 0, fmt, va);
4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_end(va);
4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
44703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* shf_sclose NUL terminates */
44803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	return (shf_sclose(&shf));
4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int c;
4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	while ((c = *fmt++)) {
4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (c == '%') {
4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			switch ((c = *fmt++)) {
4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 'c':
46003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* character (octet, probably) */
46103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putchar(va_arg(va, int), shf);
4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 's':
46403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* string */
4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_puts(va_arg(va, char *), shf);
4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
46703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'S':
46803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* word */
46903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				wdvarput(shf, va_arg(va, char *), 0, WDS_TPUTS);
4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
47103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'd':
47203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* signed decimal */
47377740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				shf_fprintf(shf, Tf_d, va_arg(va, int));
4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
47503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'u':
47603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* unsigned decimal */
4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_fprintf(shf, "%u", va_arg(va, unsigned int));
4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
47903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'T':
48003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* format tree */
4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				ptree(va_arg(va, struct op *), indent, shf);
48203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				goto dont_trash_prevent_semicolon;
48303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case ';':
48403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* newline or ; */
48503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'N':
48603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* newline or space */
4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				if (shf->flags & SHF_STRING) {
48803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					if (c == ';' && !prevent_semicolon)
48903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc(';', shf);
49003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc(' ', shf);
4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				} else {
4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru					int i;
4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
49403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\n', shf);
49503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					i = indent;
49603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					while (i >= 8) {
49703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc('\t', shf);
49803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						i -= 8;
49903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					}
50003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					while (i--)
50103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc(' ', shf);
5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				}
5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 'R':
50503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* I/O redirection */
506811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser				pioact(shf, va_arg(va, struct ioword *));
5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			default:
50903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			}
5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		} else
51303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
51403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = false;
51503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dont_trash_prevent_semicolon:
51603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		;
5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * copy tree (for function definition)
5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct op *
5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutcopy(struct op *t, Area *ap)
5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct op *r;
5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	const char **tw;
5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	char **rw;
5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t == NULL)
5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		return (NULL);
5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r = alloc(sizeof(struct op), ap);
5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->type = t->type;
5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->u.evalflags = t->u.evalflags;
5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->type == TCASE)
5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->str = wdcopy(t->str, ap);
5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else
5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		strdupx(r->str, t->str, ap);
5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->vars == NULL)
5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->vars = NULL;
5455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else {
54603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = (const char **)t->vars;
54703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
54803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			++tw;
54903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		rw = r->vars = alloc2(tw - (const char **)t->vars + 1,
5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    sizeof(*tw), ap);
55103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = (const char **)t->vars;
55203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			*rw++ = wdcopy(*tw++, ap);
5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*rw = NULL;
5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->args == NULL)
5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->args = NULL;
5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else {
56003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = t->args;
56103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
56203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			++tw;
56303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		r->args = (const char **)(rw = alloc2(tw - t->args + 1,
5645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    sizeof(*tw), ap));
56503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = t->args;
56603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			*rw++ = wdcopy(*tw++, ap);
5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*rw = NULL;
5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->ioact = (t->ioact == NULL) ? NULL : iocopy(t->ioact, ap);
5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->left = tcopy(t->left, ap);
5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->right = tcopy(t->right, ap);
5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->lineno = t->lineno;
5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (r);
5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwdcopy(const char *wp, Area *ap)
5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
58303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	size_t len;
58403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
58503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	len = wdscan(wp, EOS) - wp;
5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (memcpy(alloc(len, ap), wp, len));
5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* return the position of prefix c in wp plus 1 */
5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst char *
5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwdscan(const char *wp, int c)
5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int nest = 0;
5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
59503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1)
5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		switch (*wp++) {
5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EOS:
5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			return (wp);
5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case ADELIM:
600fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			if (c == ADELIM && nest == 0)
6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp + 1);
602fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			if (*wp == /*{*/'}')
603fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes				goto wdscan_csubst;
6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			/* FALLTHROUGH */
6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CHAR:
6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case QCHAR:
6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case COMSUB:
610c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
611811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		case VALSUB:
6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EXPRSUB:
6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while (*wp++ != 0)
6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				;
6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OQUOTE:
6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CQUOTE:
6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OSUBST:
6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest++;
6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while (*wp++ != '\0')
6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				;
6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CSUBST:
625fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes wdscan_csubst:
6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (c == CSUBST && nest == 0)
6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp);
6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest--;
6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OPAT:
6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest++;
6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case SPAT:
6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CPAT:
6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (c == wp[-1] && nest == 0)
6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp);
6395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (wp[-1] == CPAT)
6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				nest--;
6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		default:
6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			internal_warningf(
64477740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			    "wdscan: unknown char 0x%X (carrying on)",
64577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			    (unsigned char)wp[-1]);
6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
64903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*
65003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * return a copy of wp without any of the mark up characters and with
65103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * quote characters (" ' \) stripped. (string is allocated from ATEMP)
6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
65403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrawdstrip(const char *wp, int opmode)
6555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct shf shf;
6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	shf_sopen(NULL, 32, SHF_WR | SHF_DYNAMIC, &shf);
65903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	wdvarput(&shf, wp, 0, opmode);
66003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* shf_sclose NUL terminates */
66103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	return (shf_sclose(&shf));
6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct ioword **
6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruiocopy(struct ioword **iow, Area *ap)
6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword **ior;
6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int i;
6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
67003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	ior = iow;
67103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (*ior)
67203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		++ior;
67303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	ior = alloc2(ior - iow + 1, sizeof(struct ioword *), ap);
6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	for (i = 0; iow[i] != NULL; i++) {
6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		struct ioword *p, *q;
6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		p = iow[i];
6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		q = alloc(sizeof(struct ioword), ap);
6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		ior[i] = q;
6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*q = *p;
682fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		if (p->ioname != NULL)
683fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			q->ioname = wdcopy(p->ioname, ap);
6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->delim != NULL)
6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			q->delim = wdcopy(p->delim, ap);
6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->heredoc != NULL)
6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			strdupx(q->heredoc, p->heredoc, ap);
6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	ior[i] = NULL;
6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (ior);
6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * free tree (for function definition)
6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid
6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutfree(struct op *t, Area *ap)
6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	char **w;
7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t == NULL)
7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		return;
7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
705fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes	afree(t->str, ap);
7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->vars != NULL) {
7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		for (w = t->vars; *w != NULL; w++)
7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(*w, ap);
7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(t->vars, ap);
7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->args != NULL) {
71403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/*XXX we assume the caller is right */
7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		union mksh_ccphack cw;
71603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		cw.ro = t->args;
7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		for (w = cw.rw; *w != NULL; w++)
7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(*w, ap);
7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(t->args, ap);
7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->ioact != NULL)
7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		iofree(t->ioact, ap);
7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	tfree(t->left, ap);
7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	tfree(t->right, ap);
7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	afree(t, ap);
7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
7335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruiofree(struct ioword **iow, Area *ap)
7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword **iop;
7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword *p;
7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
73803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	iop = iow;
73903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while ((p = *iop++) != NULL) {
740fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		afree(p->ioname, ap);
741fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		afree(p->delim, ap);
742fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		afree(p->heredoc, ap);
7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(p, ap);
7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	afree(iow, ap);
7465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
74703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
74803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
74903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy CondrafpFUNCTf(struct shf *shf, int i, bool isksh, const char *k, struct op *v)
75003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
75103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	if (isksh)
75203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, i, "%s %s %T", Tfunction, k, v);
753fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes	else if (ktsearch(&keywords, k, hash(k)))
754fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		fptreef(shf, i, "%s %s() %T", Tfunction, k, v);
75503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	else
75603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, i, "%s() %T", k, v);
75703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
75803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
75903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
76003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* for jobs.c */
76103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
76203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravistree(char *dst, size_t sz, struct op *t)
76303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
764c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	unsigned int c;
76503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	char *cp, *buf;
766c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	size_t n;
76703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
768811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser	buf = alloc(sz + 16, ATEMP);
76977740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes	snptreef(buf, sz + 16, Tf_T, t);
77003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	cp = buf;
771c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vist_loop:
772c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if (UTFMODE && (n = utf_mbtowc(&c, cp)) != (size_t)-1) {
773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (c == 0 || n >= sz)
774c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			/* NUL or not enough free space */
775c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto vist_out;
776c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* copy multibyte char */
777c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		sz -= n;
778c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		while (n--)
779c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			*dst++ = *cp++;
780c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		goto vist_loop;
781c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	}
782c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if (--sz == 0 || (c = (unsigned char)(*cp++)) == 0)
783c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* NUL or not enough free space */
784c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		goto vist_out;
785737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes	if (ISCTRL(c & 0x7F)) {
786c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* C0 or C1 control character or DEL */
787c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (--sz == 0)
788c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			/* not enough free space for two chars */
789c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto vist_out;
790c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		*dst++ = (c & 0x80) ? '$' : '^';
791737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes		c = UNCTRL(c & 0x7F);
792c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	} else if (UTFMODE && c > 0x7F) {
793c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* better not try to display broken multibyte chars */
794737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes		/* also go easy on the Unicode: no U+FFFD here */
795c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		c = '?';
79603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
797c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	*dst++ = c;
798c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	goto vist_loop;
799c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
800c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vist_out:
80103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	*dst = '\0';
80203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	afree(buf, ATEMP);
80303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
80403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
80503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef DEBUG
80603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
80703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumpchar(struct shf *shf, int c)
80803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
809737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes	if (ISCTRL(c & 0x7F)) {
81003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/* C0 or C1 control character or DEL */
81103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc((c & 0x80) ? '$' : '^', shf);
812737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes		c = UNCTRL(c & 0x7F);
81303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
81403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_putc(c, shf);
81503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
81603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
81703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* see: wdvarput */
81803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *
819c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserdumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
82003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
82103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	int c;
82203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
82303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1) {
82403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		switch(*wp++) {
82503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case EOS:
82603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("EOS", shf);
82703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (--wp);
82803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case ADELIM:
829fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			if (*wp == /*{*/'}') {
83077740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes				shf_puts(/*{*/ "]ADELIM(})", shf);
831fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes				return (wp + 1);
832fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes			}
83303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("ADELIM=", shf);
83403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (0)
83503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CHAR:
83603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_puts("CHAR=", shf);
83703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
83803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
83903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case QCHAR:
84003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("QCHAR<", shf);
84103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = *wp++;
84203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (quotelevel == 0 ||
84303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    (c == '"' || c == '`' || c == '$' || c == '\\'))
84403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\\', shf);
84503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, c);
84603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto closeandout;
84703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case COMSUB:
84803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("COMSUB<", shf);
84903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpsub:
85003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
85103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpchar(shf, c);
85203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra closeandout:
85303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('>', shf);
85403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
855c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
856c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts("FUNSUB<", shf);
857c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto dumpsub;
858811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		case VALSUB:
859811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_puts("VALSUB<", shf);
860811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			goto dumpsub;
86103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case EXPRSUB:
86203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("EXPRSUB<", shf);
86303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto dumpsub;
86403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OQUOTE:
86577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			shf_fprintf(shf, "OQUOTE{%d" /*}*/, ++quotelevel);
86603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
86703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CQUOTE:
86877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes			shf_fprintf(shf, /*{*/ "%d}CQUOTE", quotelevel);
86903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (quotelevel)
87003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				quotelevel--;
87103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			else
87203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_puts("(err)", shf);
87303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
87403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OSUBST:
87503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("OSUBST(", shf);
87603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
87703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(")[", shf);
87803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
87903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpchar(shf, c);
88003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('|', shf);
881c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			wp = dumpwdvar_i(shf, wp, 0);
88203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
88303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CSUBST:
88403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("]CSUBST(", shf);
88503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
88603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(')', shf);
88703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (wp);
88803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OPAT:
88903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("OPAT=", shf);
89003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
89103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
89203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case SPAT:
89303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("SPAT", shf);
89403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
89503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CPAT:
89603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("CPAT", shf);
89703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
89803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		default:
89903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, "INVAL<%u>", (uint8_t)wp[-1]);
90003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
90103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
90203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc(' ', shf);
90303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
90403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
90503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
90603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumpwdvar(struct shf *shf, const char *wp)
90703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
908c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	dumpwdvar_i(shf, wp, 0);
909c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser}
910c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
911c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaservoid
912c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserdumpioact(struct shf *shf, struct op *t)
913c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{
914c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	struct ioword **ioact, *iop;
915c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
916c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if ((ioact = t->ioact) == NULL)
917c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		return;
918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
919c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	shf_puts("{IOACT", shf);
920c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	while ((iop = *ioact++) != NULL) {
921b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes		unsigned short type = iop->ioflag & IOTYPE;
922c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define DT(x) case x: shf_puts(#x, shf); break;
923b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes#define DB(x) if (iop->ioflag & x) shf_puts("|" #x, shf);
924c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
925c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		shf_putc(';', shf);
926c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		switch (type) {
927c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOREAD)
928c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOWRITE)
929c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IORDWR)
930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOHERE)
931c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOCAT)
932c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IODUP)
933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		default:
934c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_fprintf(shf, "unk%d", type);
935c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
936c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOEVAL)
937c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOSKIP)
938c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOCLOB)
939c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IORDUP)
940c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IONAMEXP)
941c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOBASH)
942c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOHERESTR)
943c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IONDELIM)
944b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes		shf_fprintf(shf, ",unit=%d", (int)iop->unit);
945fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		if (iop->delim && !(iop->ioflag & IONDELIM)) {
946c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(",delim<", shf);
947c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpwdvar(shf, iop->delim);
948c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_putc('>', shf);
949c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
950fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes		if (iop->ioname) {
951b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes			if (iop->ioflag & IONAMEXP) {
952c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_puts(",name=", shf);
953fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes				print_value_quoted(shf, iop->ioname);
954c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			} else {
955c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_puts(",name<", shf);
956fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes				dumpwdvar(shf, iop->ioname);
957c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_putc('>', shf);
958c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			}
959c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
960c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->heredoc) {
961c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(",heredoc=", shf);
962c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			print_value_quoted(shf, iop->heredoc);
963c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
964c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#undef DT
965c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#undef DB
966c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	}
967c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	shf_putc('}', shf);
96803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
96903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
97003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
97103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumptree(struct shf *shf, struct op *t)
97203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
973c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	int i, j;
97403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	const char **w, *name;
97503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	struct op *t1;
976c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	static int nesting;
97703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
97803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	for (i = 0; i < nesting; ++i)
97903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\t', shf);
98003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	++nesting;
98103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_puts("{tree:" /*}*/, shf);
98203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	if (t == NULL) {
98303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		name = "(null)";
98403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto out;
98503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
986c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	dumpioact(shf, t);
98703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	switch (t->type) {
98803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define OPEN(x) case x: name = #x; shf_puts(" {" #x ":", shf); /*}*/
98903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
99003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCOM)
99103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->vars) {
99203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
99303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
99403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
99503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
996c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
99703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
99803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " var%d<", i++);
99903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
100003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
100103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
100203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
100303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" #no-vars#", shf);
100403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->args) {
100503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
100603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = t->args;
100703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
100803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
1009c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
101003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
101103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " arg%d<", i++);
101203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
101303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
101403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
101503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
101603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" #no-args#", shf);
101703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
101803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TEXEC)
101903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpleftandout:
102003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->left;
102103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpandout:
102203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
102303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t);
102403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
102503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPAREN)
102603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
102703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPIPE)
102803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpleftmidrightandout:
102903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
103003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t->left);
103103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* middumprightandout: (unused) */
103203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, "/%s:", name);
103303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumprightandout:
103403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->right;
103503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpandout;
103603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TLIST)
103703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
103803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TOR)
103903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
104003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TAND)
104103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
104203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TBANG)
104303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumprightandout;
104403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TDBRACKET)
104503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		i = 0;
104603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		w = t->args;
104703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*w) {
104803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
1049c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			for (j = 0; j < nesting; ++j)
105003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\t', shf);
105103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " arg%d<", i++);
105203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpwdvar(shf, *w++);
105303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('>', shf);
105403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
105503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
105603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TFOR)
105703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpfor:
105803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s>", t->str);
105903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->vars != NULL) {
106003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
106103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
106203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
106303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
1064c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
106503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
106603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " var%d<", i++);
106703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
106803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
106903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
107003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
107103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
107203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TSELECT)
107303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpfor;
107403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCASE)
107503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s>", t->str);
107603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		i = 0;
107703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		for (t1 = t->left; t1 != NULL; t1 = t1->right) {
107803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
1079c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			for (j = 0; j < nesting; ++j)
108003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\t', shf);
108103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " sub%d[(", i);
108203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t1->vars;
108303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
108403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w);
108503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (w[1] != NULL)
108603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('|', shf);
108703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				++w;
108803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
108903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(')', shf);
1090c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpioact(shf, t);
109103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
109203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t1->left);
109303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " ;%c/%d]", t1->u.charflag, i++);
109403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
109503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
109603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TWHILE)
109703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
109803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TUNTIL)
109903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
110003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TBRACE)
110103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
110203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCOPROC)
110303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
110403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TASYNC)
110503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
110603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TFUNCT)
110703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s> ksh<%s>", t->str,
110877740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		    t->u.ksh_func ? Ttrue : Tfalse);
110903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
111003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TTIME)
111103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
111203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TIF)
111303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpif:
111403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
111503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t->left);
111603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->right;
1117c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		dumpioact(shf, t);
111803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->left != NULL) {
111903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TTHEN:\n", shf);
112003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t->left);
112103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
112203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->right && t->right->type == TELIF) {
112303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TELIF:", shf);
112403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			t = t->right;
1125c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpioact(shf, t);
112603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto dumpif;
112703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
112803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->right != NULL) {
112903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TELSE:\n", shf);
113003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t->right);
113103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
113203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
113303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TEOF)
113403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpunexpected:
113577740fcd3dfcd2a78a8ad0ea0f0314dd6b23ecb6Elliott Hughes		shf_puts(Tunexpected, shf);
113603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
113703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TELIF)
113803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
113903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPAT)
114003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
114103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	default:
114203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		name = "TINVALID";
114303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, "{T<%d>:" /*}*/, t->type);
114403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
114503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
114603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#undef OPEN
114703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
114803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra out:
114903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_fprintf(shf, /*{*/ " /%s}\n", name);
115003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	--nesting;
115103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
115203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif
1153