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,
5811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser *		 2011, 2012, 2013
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
26811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.71 2013/07/26 20:33:24 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;
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)
217811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			pioact(shf, *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
247811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserpioact(struct shf *shf, 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:
262811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		shf_putc('<', shf);
2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOHERE:
265811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		shf_puts("<<", shf);
266811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		if (flag & IOSKIP)
267811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc('-', shf);
2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOCAT:
27003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts(">>", shf);
2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IOWRITE:
273811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		shf_putc('>', shf);
274811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		if (flag & IOCLOB)
275811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc('|', shf);
2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IORDWR:
27803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts("<>", shf);
2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	case IODUP:
2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		shf_puts(flag & IORDUP ? "<&" : ">&", shf);
2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		break;
2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
28403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* name/delim are NULL when printing syntax errors */
2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (type == IOHERE) {
2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (iop->delim)
287c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			wdvarput(shf, iop->delim, 0, WDS_TPUTS);
288c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->flag & IOHERESTR)
28903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(' ', shf);
290811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser	} else if (iop->name) {
291811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		if (iop->flag & IONAMEXP)
292811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			print_value_quoted(shf, iop->name);
293811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		else
294811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			wdvarput(shf, iop->name, 0, WDS_TPUTS);
295811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		shf_putc(' ', shf);
296811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser	}
29703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	prevent_semicolon = false;
2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
30003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* variant of fputs for ptreef and wdstrip */
30103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *
30203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrawdvarput(struct shf *shf, const char *wp, int quotelevel, int opmode)
3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
30403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	int c;
305c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	const char *cs;
3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
30703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/*-
30803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	 * problems:
3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	`...` -> $(...)
3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	'foo' -> "foo"
31103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	 *	x${foo:-"hi"} -> x${foo:-hi} unless WDS_TPUTS
31203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	 *	x${foo:-'hi'} -> x${foo:-hi} unless WDS_KEEPQ
3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 * could change encoding to:
3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	OQUOTE ["'] ... CQUOTE ["']
3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 *	COMSUB [(`] ...\0	(handle $ ` \ and maybe " in `...` case)
3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	 */
31703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1)
3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		switch (*wp++) {
3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EOS:
32003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (--wp);
3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case ADELIM:
3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CHAR:
32303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = *wp++;
32403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if ((opmode & WDS_MAGIC) &&
325c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			    (ISMAGIC(c) || c == '[' || c == '!' ||
32603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    c == '-' || c == ']' || c == '*' || c == '?'))
32703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(MAGIC, shf);
32803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
33003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case QCHAR: {
33103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			bool doq;
33203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			c = *wp++;
33403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			doq = (c == '"' || c == '`' || c == '$' || c == '\\');
33503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_TPUTS) {
33603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (quotelevel == 0)
33703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					doq = true;
33803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			} else {
33903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (!(opmode & WDS_KEEPQ))
34003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					doq = false;
34103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
34203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (doq)
34303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\\', shf);
34403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
34603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case COMSUB:
3485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("$(", shf);
349c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = ")";
350c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser pSUB:
35103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
35203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
353c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(cs, shf);
3545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
355c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
356811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			c = ' ';
357811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			if (0)
358811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser				/* FALLTHROUGH */
359811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		case VALSUB:
360811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			  c = '|';
361811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc('$', shf);
362811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc('{', shf);
363811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_putc(c, shf);
364c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = ";}";
365c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto pSUB;
3665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EXPRSUB:
3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			shf_puts("$((", shf);
368c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			cs = "))";
369c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto pSUB;
3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OQUOTE:
37103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_TPUTS) {
37203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				quotelevel++;
37303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('"', shf);
37403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CQUOTE:
37703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_TPUTS) {
37803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (quotelevel)
37903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					quotelevel--;
38003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('"', shf);
38103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OSUBST:
38403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('$', shf);
3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (*wp++ == '{')
38603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('{', shf);
3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while ((c = *wp++) != 0)
38803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
38903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			wp = wdvarput(shf, wp, 0, opmode);
3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CSUBST:
3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (*wp++ == '}')
39303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('}', shf);
39403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (wp);
3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OPAT:
39603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_MAGIC) {
39703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(MAGIC, shf);
39803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putchar(*wp++ | 0x80, shf);
39903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			} else {
40003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putchar(*wp++, shf);
40103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('(', shf);
40203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case SPAT:
40503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = '|';
40603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (0)
4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CPAT:
40803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				c = /*(*/ ')';
40903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (opmode & WDS_MAGIC)
41003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(MAGIC, shf);
41103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is the _only_ way to reliably handle
4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * variable args with an ANSI compiler
4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* VARARGS */
42103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querufptreef(struct shf *shf, int indent, const char *fmt, ...)
4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_list va;
4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_start(va, fmt);
4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	vfptreef(shf, indent, fmt, va);
4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_end(va);
4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* VARARGS */
4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
43303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrasnptreef(char *s, ssize_t n, const char *fmt, ...)
4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_list va;
4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct shf shf;
4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	shf_sopen(s, n, SHF_WR | (s ? 0 : SHF_DYNAMIC), &shf);
4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_start(va, fmt);
4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	vfptreef(&shf, 0, fmt, va);
4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	va_end(va);
4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
44403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* shf_sclose NUL terminates */
44503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	return (shf_sclose(&shf));
4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvfptreef(struct shf *shf, int indent, const char *fmt, va_list va)
4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int c;
4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	while ((c = *fmt++)) {
4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (c == '%') {
4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			switch ((c = *fmt++)) {
4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 'c':
45703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* character (octet, probably) */
45803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putchar(va_arg(va, int), shf);
4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 's':
46103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* string */
4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_puts(va_arg(va, char *), shf);
4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
46403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'S':
46503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* word */
46603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				wdvarput(shf, va_arg(va, char *), 0, WDS_TPUTS);
4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
46803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'd':
46903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* signed decimal */
4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_fprintf(shf, "%d", va_arg(va, int));
4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
47203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'u':
47303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* unsigned decimal */
4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				shf_fprintf(shf, "%u", va_arg(va, unsigned int));
4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
47603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'T':
47703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* format tree */
4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				ptree(va_arg(va, struct op *), indent, shf);
47903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				goto dont_trash_prevent_semicolon;
48003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case ';':
48103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* newline or ; */
48203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			case 'N':
48303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* newline or space */
4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				if (shf->flags & SHF_STRING) {
48503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					if (c == ';' && !prevent_semicolon)
48603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc(';', shf);
48703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc(' ', shf);
4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				} else {
4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru					int i;
4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
49103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\n', shf);
49203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					i = indent;
49303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					while (i >= 8) {
49403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc('\t', shf);
49503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						i -= 8;
49603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					}
49703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					while (i--)
49803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra						shf_putc(' ', shf);
4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				}
5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			case 'R':
50203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				/* I/O redirection */
503811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser				pioact(shf, va_arg(va, struct ioword *));
5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			default:
50603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc(c, shf);
5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				break;
5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			}
5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		} else
51003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(c, shf);
51103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		prevent_semicolon = false;
51203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dont_trash_prevent_semicolon:
51303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		;
5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * copy tree (for function definition)
5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct op *
5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutcopy(struct op *t, Area *ap)
5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct op *r;
5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	const char **tw;
5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	char **rw;
5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t == NULL)
5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		return (NULL);
5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r = alloc(sizeof(struct op), ap);
5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->type = t->type;
5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->u.evalflags = t->u.evalflags;
5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->type == TCASE)
5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->str = wdcopy(t->str, ap);
5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else
5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		strdupx(r->str, t->str, ap);
5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->vars == NULL)
5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->vars = NULL;
5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else {
54303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = (const char **)t->vars;
54403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
54503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			++tw;
54603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		rw = r->vars = alloc2(tw - (const char **)t->vars + 1,
5475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    sizeof(*tw), ap);
54803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = (const char **)t->vars;
54903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			*rw++ = wdcopy(*tw++, ap);
5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*rw = NULL;
5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->args == NULL)
5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		r->args = NULL;
5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	else {
55703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = t->args;
55803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
55903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			++tw;
56003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		r->args = (const char **)(rw = alloc2(tw - t->args + 1,
5615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		    sizeof(*tw), ap));
56203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		tw = t->args;
56303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*tw)
5645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			*rw++ = wdcopy(*tw++, ap);
5655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*rw = NULL;
5665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->ioact = (t->ioact == NULL) ? NULL : iocopy(t->ioact, ap);
5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->left = tcopy(t->left, ap);
5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->right = tcopy(t->right, ap);
5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	r->lineno = t->lineno;
5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (r);
5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwdcopy(const char *wp, Area *ap)
5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
58003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	size_t len;
58103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
58203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	len = wdscan(wp, EOS) - wp;
5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (memcpy(alloc(len, ap), wp, len));
5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* return the position of prefix c in wp plus 1 */
5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst char *
5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwdscan(const char *wp, int c)
5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int nest = 0;
5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
59203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1)
5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		switch (*wp++) {
5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EOS:
5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			return (wp);
5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case ADELIM:
5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (c == ADELIM)
5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp + 1);
5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			/* FALLTHROUGH */
6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CHAR:
6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case QCHAR:
6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case COMSUB:
605c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
606811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		case VALSUB:
6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case EXPRSUB:
6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while (*wp++ != 0)
6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				;
6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OQUOTE:
6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CQUOTE:
6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OSUBST:
6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest++;
6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			while (*wp++ != '\0')
6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				;
6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CSUBST:
6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (c == CSUBST && nest == 0)
6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp);
6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest--;
6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case OPAT:
6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			nest++;
6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			wp++;
6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case SPAT:
6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		case CPAT:
6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (c == wp[-1] && nest == 0)
6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				return (wp);
6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			if (wp[-1] == CPAT)
6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru				nest--;
6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			break;
6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		default:
6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			internal_warningf(
6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			    "wdscan: unknown char 0x%x (carrying on)",
6395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			    wp[-1]);
6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		}
6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
64303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*
64403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * return a copy of wp without any of the mark up characters and with
64503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * quote characters (" ' \) stripped. (string is allocated from ATEMP)
6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar *
64803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrawdstrip(const char *wp, int opmode)
6495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct shf shf;
6515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	shf_sopen(NULL, 32, SHF_WR | SHF_DYNAMIC, &shf);
65303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	wdvarput(&shf, wp, 0, opmode);
65403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	/* shf_sclose NUL terminates */
65503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	return (shf_sclose(&shf));
6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct ioword **
6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruiocopy(struct ioword **iow, Area *ap)
6605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword **ior;
6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	int i;
6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
66403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	ior = iow;
66503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (*ior)
66603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		++ior;
66703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	ior = alloc2(ior - iow + 1, sizeof(struct ioword *), ap);
6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	for (i = 0; iow[i] != NULL; i++) {
6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		struct ioword *p, *q;
6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		p = iow[i];
6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		q = alloc(sizeof(struct ioword), ap);
6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		ior[i] = q;
6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		*q = *p;
6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->name != NULL)
6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			q->name = wdcopy(p->name, ap);
6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->delim != NULL)
6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			q->delim = wdcopy(p->delim, ap);
6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->heredoc != NULL)
6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			strdupx(q->heredoc, p->heredoc, ap);
6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	ior[i] = NULL;
6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	return (ior);
6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*
6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * free tree (for function definition)
6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */
6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid
6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutfree(struct op *t, Area *ap)
6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	char **w;
6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t == NULL)
6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		return;
6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->str != NULL)
7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(t->str, ap);
7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->vars != NULL) {
7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		for (w = t->vars; *w != NULL; w++)
7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(*w, ap);
7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(t->vars, ap);
7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->args != NULL) {
70903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/*XXX we assume the caller is right */
7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		union mksh_ccphack cw;
71103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		cw.ro = t->args;
7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		for (w = cw.rw; *w != NULL; w++)
7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(*w, ap);
7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(t->args, ap);
7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	if (t->ioact != NULL)
7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		iofree(t->ioact, ap);
7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	tfree(t->left, ap);
7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	tfree(t->right, ap);
7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	afree(t, ap);
7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void
7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruiofree(struct ioword **iow, Area *ap)
7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{
7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword **iop;
7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	struct ioword *p;
7325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru
73303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	iop = iow;
73403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while ((p = *iop++) != NULL) {
7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->name != NULL)
7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(p->name, ap);
7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->delim != NULL)
7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(p->delim, ap);
7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		if (p->heredoc != NULL)
7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru			afree(p->heredoc, ap);
7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru		afree(p, ap);
7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	}
7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru	afree(iow, ap);
7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}
74503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
74603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
74703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy CondrafpFUNCTf(struct shf *shf, int i, bool isksh, const char *k, struct op *v)
74803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
74903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	if (isksh)
75003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, i, "%s %s %T", Tfunction, k, v);
75103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	else
75203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		fptreef(shf, i, "%s() %T", k, v);
75303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
75403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
75503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
75603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* for jobs.c */
75703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
75803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravistree(char *dst, size_t sz, struct op *t)
75903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
760c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	unsigned int c;
76103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	char *cp, *buf;
762c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	size_t n;
76303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
764811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser	buf = alloc(sz + 16, ATEMP);
765811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser	snptreef(buf, sz + 16, "%T", t);
76603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	cp = buf;
767c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vist_loop:
768c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if (UTFMODE && (n = utf_mbtowc(&c, cp)) != (size_t)-1) {
769c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (c == 0 || n >= sz)
770c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			/* NUL or not enough free space */
771c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto vist_out;
772c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* copy multibyte char */
773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		sz -= n;
774c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		while (n--)
775c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			*dst++ = *cp++;
776c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		goto vist_loop;
777c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	}
778c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if (--sz == 0 || (c = (unsigned char)(*cp++)) == 0)
779c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* NUL or not enough free space */
780c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		goto vist_out;
781c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if ((c & 0x60) == 0 || (c & 0x7F) == 0x7F) {
782c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* C0 or C1 control character or DEL */
783c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (--sz == 0)
784c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			/* not enough free space for two chars */
785c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto vist_out;
786c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		*dst++ = (c & 0x80) ? '$' : '^';
787c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		c = (c & 0x7F) ^ 0x40;
788c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	} else if (UTFMODE && c > 0x7F) {
789c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		/* better not try to display broken multibyte chars */
790c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		c = '?';
79103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
792c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	*dst++ = c;
793c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	goto vist_loop;
794c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
795c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vist_out:
79603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	*dst = '\0';
79703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	afree(buf, ATEMP);
79803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
79903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
80003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef DEBUG
80103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
80203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumpchar(struct shf *shf, int c)
80303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
80403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	if (((c & 0x60) == 0) || ((c & 0x7F) == 0x7F)) {
80503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		/* C0 or C1 control character or DEL */
80603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc((c & 0x80) ? '$' : '^', shf);
80703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		c = (c & 0x7F) ^ 0x40;
80803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
80903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_putc(c, shf);
81003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
81103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
81203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* see: wdvarput */
81303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic const char *
814c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserdumpwdvar_i(struct shf *shf, const char *wp, int quotelevel)
81503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
81603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	int c;
81703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
81803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	while (/* CONSTCOND */ 1) {
81903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		switch(*wp++) {
82003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case EOS:
82103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("EOS", shf);
82203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (--wp);
82303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case ADELIM:
82403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("ADELIM=", shf);
82503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (0)
82603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CHAR:
82703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_puts("CHAR=", shf);
82803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
82903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
83003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case QCHAR:
83103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("QCHAR<", shf);
83203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			c = *wp++;
83303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (quotelevel == 0 ||
83403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			    (c == '"' || c == '`' || c == '$' || c == '\\'))
83503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\\', shf);
83603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, c);
83703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto closeandout;
83803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case COMSUB:
83903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("COMSUB<", shf);
84003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpsub:
84103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
84203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpchar(shf, c);
84303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra closeandout:
84403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('>', shf);
84503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
846c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		case FUNSUB:
847c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts("FUNSUB<", shf);
848c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			goto dumpsub;
849811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser		case VALSUB:
850811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			shf_puts("VALSUB<", shf);
851811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser			goto dumpsub;
85203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case EXPRSUB:
85303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("EXPRSUB<", shf);
85403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto dumpsub;
85503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OQUOTE:
85603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, "OQUOTE{%d", ++quotelevel);
85703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
85803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CQUOTE:
85903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, "%d}CQUOTE", quotelevel);
86003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			if (quotelevel)
86103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				quotelevel--;
86203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			else
86303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_puts("(err)", shf);
86403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
86503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OSUBST:
86603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("OSUBST(", shf);
86703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
86803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(")[", shf);
86903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while ((c = *wp++) != 0)
87003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpchar(shf, c);
87103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('|', shf);
872c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			wp = dumpwdvar_i(shf, wp, 0);
87303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
87403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CSUBST:
87503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("]CSUBST(", shf);
87603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
87703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(')', shf);
87803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			return (wp);
87903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case OPAT:
88003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("OPAT=", shf);
88103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpchar(shf, *wp++);
88203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
88303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case SPAT:
88403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("SPAT", shf);
88503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
88603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		case CPAT:
88703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts("CPAT", shf);
88803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
88903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		default:
89003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, "INVAL<%u>", (uint8_t)wp[-1]);
89103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			break;
89203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
89303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc(' ', shf);
89403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
89503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
89603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
89703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumpwdvar(struct shf *shf, const char *wp)
89803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
899c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	dumpwdvar_i(shf, wp, 0);
900c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser}
901c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
902c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaservoid
903c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserdumpioact(struct shf *shf, struct op *t)
904c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{
905c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	struct ioword **ioact, *iop;
906c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
907c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	if ((ioact = t->ioact) == NULL)
908c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		return;
909c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
910c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	shf_puts("{IOACT", shf);
911c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	while ((iop = *ioact++) != NULL) {
912c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		int type = iop->flag & IOTYPE;
913c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define DT(x) case x: shf_puts(#x, shf); break;
914c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define DB(x) if (iop->flag & x) shf_puts("|" #x, shf);
915c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser
916c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		shf_putc(';', shf);
917c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		switch (type) {
918c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOREAD)
919c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOWRITE)
920c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IORDWR)
921c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOHERE)
922c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IOCAT)
923c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DT(IODUP)
924c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		default:
925c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_fprintf(shf, "unk%d", type);
926c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
927c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOEVAL)
928c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOSKIP)
929c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOCLOB)
930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IORDUP)
931c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IONAMEXP)
932c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOBASH)
933c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IOHERESTR)
934c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		DB(IONDELIM)
935c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		shf_fprintf(shf, ",unit=%d", iop->unit);
936c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->delim) {
937c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(",delim<", shf);
938c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpwdvar(shf, iop->delim);
939c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_putc('>', shf);
940c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
941c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->name) {
942c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			if (iop->flag & IONAMEXP) {
943c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_puts(",name=", shf);
944c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				print_value_quoted(shf, iop->name);
945c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			} else {
946c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_puts(",name<", shf);
947c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				dumpwdvar(shf, iop->name);
948c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				shf_putc('>', shf);
949c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			}
950c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
951c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		if (iop->heredoc) {
952c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			shf_puts(",heredoc=", shf);
953c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			print_value_quoted(shf, iop->heredoc);
954c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		}
955c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#undef DT
956c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#undef DB
957c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	}
958c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	shf_putc('}', shf);
95903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
96003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
96103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid
96203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condradumptree(struct shf *shf, struct op *t)
96303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{
964c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	int i, j;
96503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	const char **w, *name;
96603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	struct op *t1;
967c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	static int nesting;
96803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
96903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	for (i = 0; i < nesting; ++i)
97003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\t', shf);
97103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	++nesting;
97203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_puts("{tree:" /*}*/, shf);
97303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	if (t == NULL) {
97403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		name = "(null)";
97503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto out;
97603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
977c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser	dumpioact(shf, t);
97803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	switch (t->type) {
97903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define OPEN(x) case x: name = #x; shf_puts(" {" #x ":", shf); /*}*/
98003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
98103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCOM)
98203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->vars) {
98303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
98403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
98503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
98603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
987c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
98803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
98903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " var%d<", i++);
99003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
99103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
99203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
99303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
99403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" #no-vars#", shf);
99503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->args) {
99603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
99703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = t->args;
99803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
99903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
1000c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
100103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
100203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " arg%d<", i++);
100303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
100403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
100503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
100603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		} else
100703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" #no-args#", shf);
100803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
100903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TEXEC)
101003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpleftandout:
101103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->left;
101203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpandout:
101303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
101403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t);
101503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
101603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPAREN)
101703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
101803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPIPE)
101903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpleftmidrightandout:
102003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
102103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t->left);
102203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* middumprightandout: (unused) */
102303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, "/%s:", name);
102403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumprightandout:
102503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->right;
102603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpandout;
102703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TLIST)
102803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
102903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TOR)
103003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
103103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TAND)
103203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
103303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TBANG)
103403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumprightandout;
103503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TDBRACKET)
103603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		i = 0;
103703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		w = t->args;
103803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		while (*w) {
103903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
1040c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			for (j = 0; j < nesting; ++j)
104103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\t', shf);
104203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " arg%d<", i++);
104303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumpwdvar(shf, *w++);
104403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('>', shf);
104503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
104603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
104703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TFOR)
104803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpfor:
104903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s>", t->str);
105003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->vars != NULL) {
105103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			i = 0;
105203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t->vars;
105303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
105403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\n', shf);
1055c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser				for (j = 0; j < nesting; ++j)
105603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('\t', shf);
105703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_fprintf(shf, " var%d<", i++);
105803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w++);
105903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('>', shf);
106003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
106103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
106203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
106303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TSELECT)
106403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpfor;
106503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCASE)
106603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s>", t->str);
106703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		i = 0;
106803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		for (t1 = t->left; t1 != NULL; t1 = t1->right) {
106903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
1070c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			for (j = 0; j < nesting; ++j)
107103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				shf_putc('\t', shf);
107203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " sub%d[(", i);
107303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			w = (const char **)t1->vars;
107403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			while (*w) {
107503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				dumpwdvar(shf, *w);
107603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				if (w[1] != NULL)
107703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra					shf_putc('|', shf);
107803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra				++w;
107903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			}
108003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc(')', shf);
1081c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpioact(shf, t);
108203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_putc('\n', shf);
108303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t1->left);
108403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_fprintf(shf, " ;%c/%d]", t1->u.charflag, i++);
108503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
108603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
108703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TWHILE)
108803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
108903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TUNTIL)
109003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftmidrightandout;
109103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TBRACE)
109203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
109303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TCOPROC)
109403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
109503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TASYNC)
109603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
109703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TFUNCT)
109803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, " str<%s> ksh<%s>", t->str,
109903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		    t->u.ksh_func ? "yes" : "no");
110003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
110103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TTIME)
110203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpleftandout;
110303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TIF)
110403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpif:
110503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_putc('\n', shf);
110603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		dumptree(shf, t->left);
110703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		t = t->right;
1108c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser		dumpioact(shf, t);
110903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->left != NULL) {
111003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TTHEN:\n", shf);
111103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t->left);
111203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
111303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->right && t->right->type == TELIF) {
111403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TELIF:", shf);
111503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			t = t->right;
1116c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser			dumpioact(shf, t);
111703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			goto dumpif;
111803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
111903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		if (t->right != NULL) {
112003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			shf_puts(" /TELSE:\n", shf);
112103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra			dumptree(shf, t->right);
112203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		}
112303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
112403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TEOF)
112503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dumpunexpected:
112603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_puts("unexpected", shf);
112703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		break;
112803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TELIF)
112903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
113003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	OPEN(TPAT)
113103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
113203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	default:
113303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		name = "TINVALID";
113403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		shf_fprintf(shf, "{T<%d>:" /*}*/, t->type);
113503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra		goto dumpunexpected;
113603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra
113703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#undef OPEN
113803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	}
113903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra out:
114003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	shf_fprintf(shf, /*{*/ " /%s}\n", name);
114103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra	--nesting;
114203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}
114303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif
1144