1c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/*	$OpenBSD: tree.c,v 1.20 2012/06/27 07:17:19 otto Exp $	*/
25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*-
4c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *		 2011, 2012
65155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *	Thorsten Glaser <tg@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
26c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.67 2012/12/04 01:10:35 tg Exp $");
275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define INDENT	8
295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void ptree(struct op *, int, struct shf *);
315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void pioact(struct shf *, int, 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;
525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Chain:
545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t == NULL)
555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		return;
565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	switch (t->type) {
575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TCOM:
58c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		prevent_semicolon = false;
59c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/*
60c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		 * special-case 'var=<<EOF' (rough; see
61c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		 * exec.c:execute() for full code)
62c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		 */
63c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (
64c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    /* we have zero arguments, i.e. no programme to run */
65c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    t->args[0] == NULL &&
66c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    /* we have exactly one variable assignment */
67c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    t->vars[0] != NULL && t->vars[1] == NULL &&
68c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    /* we have exactly one I/O redirection */
69c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    t->ioact != NULL && t->ioact[0] != NULL &&
70c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    t->ioact[1] == NULL &&
71c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    /* of type "here document" (or "here string") */
72c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		    (t->ioact[0]->flag & IOTYPE) == IOHERE) {
73c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			fptreef(shf, indent, "%S", t->vars[0]);
74c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			break;
75c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
76c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
7703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->vars) {
7803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
7903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w)
805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				fptreef(shf, indent, "%S ", *w++);
8103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("#no-vars# ", shf);
8303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->args) {
8403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = t->args;
8503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w)
865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				fptreef(shf, indent, "%S ", *w++);
8703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("#no-args# ", shf);
895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TEXEC:
915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		t = t->left;
925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		goto Chain;
935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TPAREN:
945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent + 2, "( %T) ", t->left);
955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TPIPE:
975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T| ", t->left);
985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		t = t->right;
995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		goto Chain;
1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TLIST:
1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T%;", t->left);
1025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		t = t->right;
1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		goto Chain;
1045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TOR:
1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TAND:
1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T%s %T",
10703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		    t->left, (t->type == TOR) ? "||" : "&&", t->right);
1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TBANG:
1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts("! ", shf);
11103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = false;
1125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		t = t->right;
1135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		goto Chain;
11403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	case TDBRACKET:
11503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		w = t->args;
1165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts("[[", shf);
11703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*w)
11803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			fptreef(shf, indent, " %S", *w++);
1195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts(" ]] ", shf);
1205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TSELECT:
1225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TFOR:
12303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, indent, "%s %s ",
12403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		    (t->type == TFOR) ? "for" : Tselect, t->str);
1255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (t->vars != NULL) {
1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("in ", shf);
12703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
12803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w)
1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				fptreef(shf, indent, "%S ", *w++);
1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			fptreef(shf, indent, "%;");
1315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
1325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent + INDENT, "do%N%T", t->left);
1335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%;done ");
1345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TCASE:
1365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "case %S in", t->str);
1375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		for (t1 = t->left; t1 != NULL; t1 = t1->right) {
1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			fptreef(shf, indent, "%N(");
13903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t1->vars;
14003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				fptreef(shf, indent, "%S%c", *w,
1425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				    (w[1] != NULL) ? '|' : ')');
14303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				++w;
14403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
14503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			fptreef(shf, indent + INDENT, "%N%T%N;%c", t1->left,
14603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    t1->u.charflag);
1475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
1485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%Nesac ");
1495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
150c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifdef DEBUG
1515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TELIF:
15203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		internal_errorf("TELIF in tree.c:ptree() unexpected");
15303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/* FALLTHROUGH */
15403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif
15503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	case TIF:
15603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		i = 2;
157c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		t1 = t;
15803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto process_TIF;
15903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		do {
160c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			t1 = t1->right;
16103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
16203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			fptreef(shf, indent, "%;");
16303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra process_TIF:
16403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			/* 5 == strlen("elif ") */
165c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			fptreef(shf, indent + 5 - i, Telif_pT + i, t1->left);
166c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			t1 = t1->right;
167c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			if (t1->left != NULL) {
1685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				fptreef(shf, indent, "%;");
16903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				fptreef(shf, indent + INDENT, "%s%N%T",
170c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				    "then", t1->left);
1715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			}
172c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		} while (t1->right && t1->right->type == TELIF);
173c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (t1->right != NULL) {
1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			fptreef(shf, indent, "%;");
17503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			fptreef(shf, indent + INDENT, "%s%N%T",
176c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			    "else", t1->right);
1775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%;fi ");
1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TWHILE:
1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TUNTIL:
182c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* 6 == strlen("while "/"until ") */
1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent + 6, "%s %T",
18403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		    (t->type == TWHILE) ? "while" : "until",
1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    t->left);
18603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, indent, "%;");
18703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, indent + INDENT, "do%N%T", t->right);
1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%;done ");
1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TBRACE:
19103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, indent + INDENT, "{%N%T", t->left);
1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%;} ");
1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TCOPROC:
1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T|& ", t->left);
19603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = true;
1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TASYNC:
1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, "%T& ", t->left);
20003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = true;
2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TFUNCT:
20303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fpFUNCTf(shf, indent, tobool(t->u.ksh_func), t->str, t->left);
2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case TTIME:
20603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, indent, "%s %T", "time", t->left);
2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	default:
2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts("<botch>", shf);
21003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = false;
2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if ((ioact = t->ioact) != NULL) {
21403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		bool need_nl = false;
2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		while (*ioact != NULL)
2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			pioact(shf, indent, *ioact++);
2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		/* Print here documents after everything else... */
21903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		ioact = t->ioact;
22003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*ioact != NULL) {
2215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			struct ioword *iop = *ioact++;
2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
22303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			/* heredoc is NULL when tracing (set -x) */
22403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if ((iop->flag & (IOTYPE | IOHERESTR)) == IOHERE &&
22503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    iop->heredoc) {
22603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_puts(iop->heredoc, shf);
2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				fptreef(shf, indent, "%s",
22903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				    iop->flag & IONDELIM ? "<<" :
2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				    evalstr(iop->delim, 0));
23103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				need_nl = true;
2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			}
2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
23403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/*
23503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		 * Last delimiter must be followed by a newline (this
23603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		 * often leads to an extra blank line, but it's not
23703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		 * worth worrying about)
2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		 */
239c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (need_nl) {
24003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
241c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			prevent_semicolon = true;
242c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupioact(struct shf *shf, int indent, struct ioword *iop)
2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int flag = iop->flag;
2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int type = flag & IOTYPE;
2515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int expected;
2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	expected = (type == IOREAD || type == IORDWR || type == IOHERE) ? 0 :
2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	    (type == IOCAT || type == IOWRITE) ? 1 :
2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	    (type == IODUP && (iop->unit == !(flag & IORDUP))) ? iop->unit :
2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	    iop->unit + 1;
2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (iop->unit != expected)
2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_fprintf(shf, "%d", iop->unit);
2595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	switch (type) {
2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOREAD:
26203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts("<", shf);
2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOHERE:
2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts(flag & IOSKIP ? "<<-" : "<<", shf);
2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOCAT:
26803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts(">>", shf);
2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOWRITE:
27103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts(flag & IOCLOB ? ">|" : ">", shf);
2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IORDWR:
27403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts("<>", shf);
2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IODUP:
2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts(flag & IORDUP ? "<&" : ">&", shf);
2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
28003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* name/delim are NULL when printing syntax errors */
2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (type == IOHERE) {
2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (iop->delim)
283c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			wdvarput(shf, iop->delim, 0, WDS_TPUTS);
284c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->flag & IOHERESTR)
28503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(' ', shf);
2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	} else if (iop->name)
2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		fptreef(shf, indent, (iop->flag & IONAMEXP) ? "%s " : "%S ",
2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    iop->name);
28903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	prevent_semicolon = false;
2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
2915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
29203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* variant of fputs for ptreef and wdstrip */
29303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *
29403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrawdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
29603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	int c;
297c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	const char *cs;
2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
29903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/*-
30003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	 * problems:
3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	`...` -> $(...)
3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	'foo' -> "foo"
30303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	 *	x${foo:-"hi"} -> x${foo:-hi} unless WDS_TPUTS
30403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	 *	x${foo:-'hi'} -> x${foo:-hi} unless WDS_KEEPQ
3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 * could change encoding to:
3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	OQUOTE ["'] ... CQUOTE ["']
3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	COMSUB [(`] ...\0	(handle $ ` \ and maybe " in `...` case)
3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 */
30903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1)
3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		switch (*wp++) {
3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EOS:
31203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (--wp);
3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case ADELIM:
3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CHAR:
31503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = *wp++;
31603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if ((opmode & WDS_MAGIC) &&
317c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			    (ISMAGIC(c) || c == '[' || c == '!' ||
31803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    c == '-' || c == ']' || c == '*' || c == '?'))
31903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(MAGIC, shf);
32003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
32203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case QCHAR: {
32303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			bool doq;
32403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			c = *wp++;
32603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			doq = (c == '"' || c == '`' || c == '$' || c == '\\');
32703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_TPUTS) {
32803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (quotelevel == 0)
32903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					doq = true;
33003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			} else {
33103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (!(opmode & WDS_KEEPQ))
33203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					doq = false;
33303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
33403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (doq)
33503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\\', shf);
33603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
33803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case COMSUB:
3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("$(", shf);
341c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = ")";
342c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser pSUB:
34303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
34403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
345c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(cs, shf);
3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
347c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
348c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts("${ ", shf);
349c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = ";}";
350c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto pSUB;
3515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EXPRSUB:
3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("$((", shf);
353c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = "))";
354c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto pSUB;
3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OQUOTE:
35603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_TPUTS) {
35703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				quotelevel++;
35803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('"', shf);
35903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CQUOTE:
36203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_TPUTS) {
36303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (quotelevel)
36403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					quotelevel--;
36503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('"', shf);
36603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OSUBST:
36903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('$', shf);
3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (*wp++ == '{')
37103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('{', shf);
3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while ((c = *wp++) != 0)
37303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
37403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			wp = wdvarput(shf, wp, 0, opmode);
3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CSUBST:
3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (*wp++ == '}')
37803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('}', shf);
37903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (wp);
3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OPAT:
38103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_MAGIC) {
38203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(MAGIC, shf);
38303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putchar(*wp++ | 0x80, shf);
38403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			} else {
38503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putchar(*wp++, shf);
38603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('(', shf);
38703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case SPAT:
39003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = '|';
39103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (0)
3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CPAT:
39303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				c = /*(*/ ')';
39403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_MAGIC)
39503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(MAGIC, shf);
39603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is the _only_ way to reliably handle
4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * variable args with an ANSI compiler
4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* VARARGS */
40603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querufptreef(struct shf *shf, int indent, const char *fmt, ...)
4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_list va;
4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_start(va, fmt);
4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	vfptreef(shf, indent, fmt, va);
4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_end(va);
4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* VARARGS */
4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
41803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrasnptreef(char *s, ssize_t n, const char *fmt, ...)
4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_list va;
4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct shf shf;
4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	shf_sopen(s, n, SHF_WR | (s ? 0 : SHF_DYNAMIC), &shf);
4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_start(va, fmt);
4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	vfptreef(&shf, 0, fmt, va);
4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_end(va);
4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
42903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* shf_sclose NUL terminates */
43003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	return (shf_sclose(&shf));
4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int c;
4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	while ((c = *fmt++)) {
4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (c == '%') {
4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			switch ((c = *fmt++)) {
4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 'c':
44203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* character (octet, probably) */
44303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putchar(va_arg(va, int), shf);
4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 's':
44603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* string */
4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_puts(va_arg(va, char *), shf);
4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
44903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'S':
45003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* word */
45103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				wdvarput(shf, va_arg(va, char *), 0, WDS_TPUTS);
4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
45303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'd':
45403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* signed decimal */
4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_fprintf(shf, "%d", va_arg(va, int));
4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
45703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'u':
45803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* unsigned decimal */
4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_fprintf(shf, "%u", va_arg(va, unsigned int));
4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
46103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'T':
46203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* format tree */
4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				ptree(va_arg(va, struct op *), indent, shf);
46403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				goto dont_trash_prevent_semicolon;
46503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case ';':
46603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* newline or ; */
46703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'N':
46803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* newline or space */
4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				if (shf->flags & SHF_STRING) {
47003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					if (c == ';' && !prevent_semicolon)
47103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc(';', shf);
47203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc(' ', shf);
4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				} else {
4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru					int i;
4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
47603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\n', shf);
47703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					i = indent;
47803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					while (i >= 8) {
47903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc('\t', shf);
48003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						i -= 8;
48103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					}
48203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					while (i--)
48303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc(' ', shf);
4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				}
4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 'R':
48703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* I/O redirection */
4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				pioact(shf, indent, va_arg(va, struct ioword *));
4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			default:
49103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			}
4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		} else
49503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
49603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = false;
49703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dont_trash_prevent_semicolon:
49803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		;
4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * copy tree (for function definition)
5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct op *
5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutcopy(struct op *t, Area *ap)
5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct op *r;
5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	const char **tw;
5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	char **rw;
5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t == NULL)
5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		return (NULL);
5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r = alloc(sizeof(struct op), ap);
5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->type = t->type;
5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->u.evalflags = t->u.evalflags;
5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->type == TCASE)
5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->str = wdcopy(t->str, ap);
5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else
5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		strdupx(r->str, t->str, ap);
5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->vars == NULL)
5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->vars = NULL;
5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else {
52803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = (const char **)t->vars;
52903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
53003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			++tw;
53103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		rw = r->vars = alloc2(tw - (const char **)t->vars + 1,
5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    sizeof(*tw), ap);
53303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = (const char **)t->vars;
53403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			*rw++ = wdcopy(*tw++, ap);
5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*rw = NULL;
5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->args == NULL)
5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->args = NULL;
5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else {
54203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = t->args;
54303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
54403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			++tw;
54503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		r->args = (const char **)(rw = alloc2(tw - t->args + 1,
5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    sizeof(*tw), ap));
54703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = t->args;
54803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
5495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			*rw++ = wdcopy(*tw++, ap);
5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*rw = NULL;
5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->ioact = (t->ioact == NULL) ? NULL : iocopy(t->ioact, ap);
5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->left = tcopy(t->left, ap);
5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->right = tcopy(t->right, ap);
5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->lineno = t->lineno;
5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (r);
5605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwdcopy(const char *wp, Area *ap)
5645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
56503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	size_t len;
56603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
56703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	len = wdscan(wp, EOS) - wp;
5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (memcpy(alloc(len, ap), wp, len));
5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* return the position of prefix c in wp plus 1 */
5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst char *
5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwdscan(const char *wp, int c)
5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int nest = 0;
5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
57703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1)
5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		switch (*wp++) {
5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EOS:
5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			return (wp);
5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case ADELIM:
5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (c == ADELIM)
5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp + 1);
5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			/* FALLTHROUGH */
5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CHAR:
5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case QCHAR:
5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case COMSUB:
590c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EXPRSUB:
5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while (*wp++ != 0)
5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				;
5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OQUOTE:
5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CQUOTE:
5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OSUBST:
5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest++;
6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while (*wp++ != '\0')
6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				;
6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CSUBST:
6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (c == CSUBST && nest == 0)
6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp);
6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest--;
6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OPAT:
6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest++;
6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case SPAT:
6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CPAT:
6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (c == wp[-1] && nest == 0)
6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp);
6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (wp[-1] == CPAT)
6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				nest--;
6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		default:
6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			internal_warningf(
6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			    "wdscan: unknown char 0x%x (carrying on)",
6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			    wp[-1]);
6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
62703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*
62803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * return a copy of wp without any of the mark up characters and with
62903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * quote characters (" ' \) stripped. (string is allocated from ATEMP)
6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
63203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrawdstrip(const char *wp, int opmode)
6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct shf shf;
6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	shf_sopen(NULL, 32, SHF_WR | SHF_DYNAMIC, &shf);
63703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	wdvarput(&shf, wp, 0, opmode);
63803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* shf_sclose NUL terminates */
63903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	return (shf_sclose(&shf));
6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct ioword **
6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruiocopy(struct ioword **iow, Area *ap)
6445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
6455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword **ior;
6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int i;
6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
64803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	ior = iow;
64903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (*ior)
65003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		++ior;
65103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	ior = alloc2(ior - iow + 1, sizeof(struct ioword *), ap);
6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	for (i = 0; iow[i] != NULL; i++) {
6545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		struct ioword *p, *q;
6555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		p = iow[i];
6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		q = alloc(sizeof(struct ioword), ap);
6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		ior[i] = q;
6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*q = *p;
6605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->name != NULL)
6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			q->name = wdcopy(p->name, ap);
6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->delim != NULL)
6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			q->delim = wdcopy(p->delim, ap);
6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->heredoc != NULL)
6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			strdupx(q->heredoc, p->heredoc, ap);
6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	ior[i] = NULL;
6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (ior);
6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * free tree (for function definition)
6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid
6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutfree(struct op *t, Area *ap)
6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	char **w;
6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t == NULL)
6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		return;
6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->str != NULL)
6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(t->str, ap);
6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->vars != NULL) {
6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		for (w = t->vars; *w != NULL; w++)
6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(*w, ap);
6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(t->vars, ap);
6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->args != NULL) {
69303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/*XXX we assume the caller is right */
6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		union mksh_ccphack cw;
69503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		cw.ro = t->args;
6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		for (w = cw.rw; *w != NULL; w++)
6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(*w, ap);
6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(t->args, ap);
7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->ioact != NULL)
7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		iofree(t->ioact, ap);
7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	tfree(t->left, ap);
7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	tfree(t->right, ap);
7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	afree(t, ap);
7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruiofree(struct ioword **iow, Area *ap)
7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword **iop;
7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword *p;
7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
71703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	iop = iow;
71803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while ((p = *iop++) != NULL) {
7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->name != NULL)
7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(p->name, ap);
7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->delim != NULL)
7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(p->delim, ap);
7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->heredoc != NULL)
7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(p->heredoc, ap);
7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(p, ap);
7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	afree(iow, ap);
7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
72903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
73003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
73103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy CondrafpFUNCTf(struct shf *shf, int i, bool isksh, const char *k, struct op *v)
73203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
73303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	if (isksh)
73403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, i, "%s %s %T", Tfunction, k, v);
73503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	else
73603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, i, "%s() %T", k, v);
73703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
73803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
73903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
74003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* for jobs.c */
74103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
74203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravistree(char *dst, size_t sz, struct op *t)
74303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
744c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	unsigned int c;
74503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	char *cp, *buf;
746c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	size_t n;
74703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
748c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	buf = alloc(sz + 8, ATEMP);
749c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	snptreef(buf, sz + 8, "%T", t);
75003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	cp = buf;
751c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vist_loop:
752c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if (UTFMODE && (n = utf_mbtowc(&c, cp)) != (size_t)-1) {
753c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (c == 0 || n >= sz)
754c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			/* NUL or not enough free space */
755c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto vist_out;
756c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* copy multibyte char */
757c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		sz -= n;
758c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		while (n--)
759c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			*dst++ = *cp++;
760c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		goto vist_loop;
761c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	}
762c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if (--sz == 0 || (c = (unsigned char)(*cp++)) == 0)
763c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* NUL or not enough free space */
764c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		goto vist_out;
765c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if ((c & 0x60) == 0 || (c & 0x7F) == 0x7F) {
766c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* C0 or C1 control character or DEL */
767c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (--sz == 0)
768c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			/* not enough free space for two chars */
769c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto vist_out;
770c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		*dst++ = (c & 0x80) ? '$' : '^';
771c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		c = (c & 0x7F) ^ 0x40;
772c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	} else if (UTFMODE && c > 0x7F) {
773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* better not try to display broken multibyte chars */
774c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		c = '?';
77503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
776c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	*dst++ = c;
777c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	goto vist_loop;
778c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
779c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vist_out:
78003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	*dst = '\0';
78103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	afree(buf, ATEMP);
78203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
78303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
78403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef DEBUG
78503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
78603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumpchar(struct shf *shf, int c)
78703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
78803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	if (((c & 0x60) == 0) || ((c & 0x7F) == 0x7F)) {
78903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/* C0 or C1 control character or DEL */
79003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc((c & 0x80) ? '$' : '^', shf);
79103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		c = (c & 0x7F) ^ 0x40;
79203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
79303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_putc(c, shf);
79403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
79503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
79603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* see: wdvarput */
79703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *
798c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserdumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
79903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
80003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	int c;
80103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
80203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1) {
80303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		switch(*wp++) {
80403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case EOS:
80503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("EOS", shf);
80603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (--wp);
80703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case ADELIM:
80803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("ADELIM=", shf);
80903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (0)
81003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CHAR:
81103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_puts("CHAR=", shf);
81203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
81303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
81403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case QCHAR:
81503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("QCHAR<", shf);
81603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = *wp++;
81703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (quotelevel == 0 ||
81803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    (c == '"' || c == '`' || c == '$' || c == '\\'))
81903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\\', shf);
82003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, c);
82103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto closeandout;
82203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case COMSUB:
82303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("COMSUB<", shf);
82403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpsub:
82503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
82603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpchar(shf, c);
82703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra closeandout:
82803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('>', shf);
82903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
830c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
831c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts("FUNSUB<", shf);
832c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto dumpsub;
83303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case EXPRSUB:
83403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("EXPRSUB<", shf);
83503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto dumpsub;
83603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OQUOTE:
83703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, "OQUOTE{%d", ++quotelevel);
83803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
83903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CQUOTE:
84003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, "%d}CQUOTE", quotelevel);
84103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (quotelevel)
84203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				quotelevel--;
84303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			else
84403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_puts("(err)", shf);
84503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
84603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OSUBST:
84703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("OSUBST(", shf);
84803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
84903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(")[", shf);
85003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
85103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpchar(shf, c);
85203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('|', shf);
853c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			wp = dumpwdvar_i(shf, wp, 0);
85403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
85503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CSUBST:
85603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("]CSUBST(", shf);
85703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
85803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(')', shf);
85903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (wp);
86003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OPAT:
86103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("OPAT=", shf);
86203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
86303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
86403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case SPAT:
86503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("SPAT", shf);
86603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
86703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CPAT:
86803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("CPAT", shf);
86903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
87003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		default:
87103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, "INVAL<%u>", (uint8_t)wp[-1]);
87203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
87303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
87403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc(' ', shf);
87503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
87603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
87703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
87803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumpwdvar(struct shf *shf, const char *wp)
87903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
880c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	dumpwdvar_i(shf, wp, 0);
881c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser}
882c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
883c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaservoid
884c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserdumpioact(struct shf *shf, struct op *t)
885c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{
886c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	struct ioword **ioact, *iop;
887c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
888c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if ((ioact = t->ioact) == NULL)
889c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		return;
890c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
891c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	shf_puts("{IOACT", shf);
892c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	while ((iop = *ioact++) != NULL) {
893c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		int type = iop->flag & IOTYPE;
894c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define DT(x) case x: shf_puts(#x, shf); break;
895c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define DB(x) if (iop->flag & x) shf_puts("|" #x, shf);
896c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
897c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		shf_putc(';', shf);
898c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		switch (type) {
899c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOREAD)
900c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOWRITE)
901c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IORDWR)
902c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOHERE)
903c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOCAT)
904c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IODUP)
905c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		default:
906c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_fprintf(shf, "unk%d", type);
907c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
908c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOEVAL)
909c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOSKIP)
910c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOCLOB)
911c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IORDUP)
912c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IONAMEXP)
913c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOBASH)
914c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOHERESTR)
915c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IONDELIM)
916c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		shf_fprintf(shf, ",unit=%d", iop->unit);
917c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->delim) {
918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(",delim<", shf);
919c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpwdvar(shf, iop->delim);
920c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_putc('>', shf);
921c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
922c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->name) {
923c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			if (iop->flag & IONAMEXP) {
924c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_puts(",name=", shf);
925c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				print_value_quoted(shf, iop->name);
926c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			} else {
927c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_puts(",name<", shf);
928c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				dumpwdvar(shf, iop->name);
929c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_putc('>', shf);
930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			}
931c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
932c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->heredoc) {
933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(",heredoc=", shf);
934c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			print_value_quoted(shf, iop->heredoc);
935c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
936c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#undef DT
937c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#undef DB
938c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	}
939c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	shf_putc('}', shf);
94003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
94103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
94203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
94303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumptree(struct shf *shf, struct op *t)
94403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
945c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	int i, j;
94603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	const char **w, *name;
94703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	struct op *t1;
948c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	static int nesting;
94903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
95003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	for (i = 0; i < nesting; ++i)
95103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\t', shf);
95203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	++nesting;
95303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_puts("{tree:" /*}*/, shf);
95403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	if (t == NULL) {
95503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		name = "(null)";
95603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto out;
95703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
958c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	dumpioact(shf, t);
95903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	switch (t->type) {
96003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define OPEN(x) case x: name = #x; shf_puts(" {" #x ":", shf); /*}*/
96103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
96203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCOM)
96303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->vars) {
96403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
96503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
96603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
96703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
968c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
96903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
97003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " var%d<", i++);
97103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
97203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
97303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
97403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
97503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" #no-vars#", shf);
97603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->args) {
97703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
97803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = t->args;
97903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
98003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
981c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
98203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
98303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " arg%d<", i++);
98403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
98503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
98603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
98703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
98803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" #no-args#", shf);
98903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
99003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TEXEC)
99103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpleftandout:
99203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->left;
99303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpandout:
99403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
99503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t);
99603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
99703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPAREN)
99803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
99903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPIPE)
100003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpleftmidrightandout:
100103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
100203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t->left);
100303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* middumprightandout: (unused) */
100403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, "/%s:", name);
100503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumprightandout:
100603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->right;
100703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpandout;
100803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TLIST)
100903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
101003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TOR)
101103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
101203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TAND)
101303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
101403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TBANG)
101503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumprightandout;
101603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TDBRACKET)
101703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		i = 0;
101803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		w = t->args;
101903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*w) {
102003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
1021c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			for (j = 0; j < nesting; ++j)
102203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\t', shf);
102303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " arg%d<", i++);
102403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpwdvar(shf, *w++);
102503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('>', shf);
102603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
102703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
102803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TFOR)
102903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpfor:
103003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s>", t->str);
103103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->vars != NULL) {
103203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
103303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
103403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
103503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
1036c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
103703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
103803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " var%d<", i++);
103903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
104003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
104103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
104203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
104303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
104403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TSELECT)
104503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpfor;
104603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCASE)
104703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s>", t->str);
104803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		i = 0;
104903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		for (t1 = t->left; t1 != NULL; t1 = t1->right) {
105003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
1051c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			for (j = 0; j < nesting; ++j)
105203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\t', shf);
105303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " sub%d[(", i);
105403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t1->vars;
105503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
105603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w);
105703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (w[1] != NULL)
105803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('|', shf);
105903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				++w;
106003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
106103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(')', shf);
1062c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpioact(shf, t);
106303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
106403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t1->left);
106503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " ;%c/%d]", t1->u.charflag, i++);
106603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
106703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
106803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TWHILE)
106903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
107003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TUNTIL)
107103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
107203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TBRACE)
107303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
107403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCOPROC)
107503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
107603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TASYNC)
107703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
107803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TFUNCT)
107903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s> ksh<%s>", t->str,
108003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		    t->u.ksh_func ? "yes" : "no");
108103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
108203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TTIME)
108303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
108403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TIF)
108503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpif:
108603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
108703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t->left);
108803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->right;
1089c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		dumpioact(shf, t);
109003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->left != NULL) {
109103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TTHEN:\n", shf);
109203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t->left);
109303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
109403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->right && t->right->type == TELIF) {
109503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TELIF:", shf);
109603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			t = t->right;
1097c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpioact(shf, t);
109803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto dumpif;
109903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
110003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->right != NULL) {
110103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TELSE:\n", shf);
110203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t->right);
110303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
110403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
110503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TEOF)
110603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpunexpected:
110703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts("unexpected", shf);
110803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
110903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TELIF)
111003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
111103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPAT)
111203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
111303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	default:
111403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		name = "TINVALID";
111503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, "{T<%d>:" /*}*/, t->type);
111603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
111703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
111803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#undef OPEN
111903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
112003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra out:
112103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_fprintf(shf, /*{*/ " /%s}\n", name);
112203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	--nesting;
112303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
112403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif
1125