Home | History | Annotate | Download | only in src
      1 /*	$OpenBSD: syn.c,v 1.28 2008/07/23 16:34:38 jaredy Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011
      5  *	Thorsten Glaser <tg (at) mirbsd.org>
      6  *
      7  * Provided that these terms and disclaimer and all copyright notices
      8  * are retained or reproduced in an accompanying document, permission
      9  * is granted to deal in this work without restriction, including un-
     10  * limited rights to use, publicly perform, distribute, sell, modify,
     11  * merge, give away, or sublicence.
     12  *
     13  * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
     14  * the utmost extent permitted by applicable law, neither express nor
     15  * implied; without malicious intent or gross negligence. In no event
     16  * may a licensor, author or contributor be held liable for indirect,
     17  * direct, other damage, loss, or other issues arising in any way out
     18  * of dealing in the work, even if advised of the possibility of such
     19  * damage or existence of a defect, except proven that it results out
     20  * of said person's immediate fault when using the work as intended.
     21  */
     22 
     23 #include "sh.h"
     24 
     25 __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.69 2011/09/07 15:24:21 tg Exp $");
     26 
     27 extern short subshell_nesting_level;
     28 extern void yyskiputf8bom(void);
     29 
     30 struct nesting_state {
     31 	int start_token;	/* token than began nesting (eg, FOR) */
     32 	int start_line;		/* line nesting began on */
     33 };
     34 
     35 static void yyparse(void);
     36 static struct op *pipeline(int);
     37 static struct op *andor(void);
     38 static struct op *c_list(bool);
     39 static struct ioword *synio(int);
     40 static struct op *nested(int, int, int);
     41 static struct op *get_command(int);
     42 static struct op *dogroup(void);
     43 static struct op *thenpart(void);
     44 static struct op *elsepart(void);
     45 static struct op *caselist(void);
     46 static struct op *casepart(int);
     47 static struct op *function_body(char *, bool);
     48 static char **wordlist(void);
     49 static struct op *block(int, struct op *, struct op *, char **);
     50 static struct op *newtp(int);
     51 static void syntaxerr(const char *) MKSH_A_NORETURN;
     52 static void nesting_push(struct nesting_state *, int);
     53 static void nesting_pop(struct nesting_state *);
     54 static int assign_command(char *);
     55 static int inalias(struct source *);
     56 static Test_op dbtestp_isa(Test_env *, Test_meta);
     57 static const char *dbtestp_getopnd(Test_env *, Test_op, bool);
     58 static int dbtestp_eval(Test_env *, Test_op, const char *,
     59     const char *, bool);
     60 static void dbtestp_error(Test_env *, int, const char *) MKSH_A_NORETURN;
     61 
     62 static struct op *outtree;		/* yyparse output */
     63 static struct nesting_state nesting;	/* \n changed to ; */
     64 
     65 static bool reject;			/* token(cf) gets symbol again */
     66 static int symbol;			/* yylex value */
     67 
     68 #define REJECT		(reject = true)
     69 #define ACCEPT		(reject = false)
     70 #define token(cf)	((reject) ? (ACCEPT, symbol) : (symbol = yylex(cf)))
     71 #define tpeek(cf)	((reject) ? (symbol) : (REJECT, symbol = yylex(cf)))
     72 #define musthave(c,cf)	do { if (token(cf) != (c)) syntaxerr(NULL); } while (/* CONSTCOND */ 0)
     73 
     74 static void
     75 yyparse(void)
     76 {
     77 	int c;
     78 
     79 	ACCEPT;
     80 
     81 	outtree = c_list(source->type == SSTRING);
     82 	c = tpeek(0);
     83 	if (c == 0 && !outtree)
     84 		outtree = newtp(TEOF);
     85 	else if (c != '\n' && c != 0)
     86 		syntaxerr(NULL);
     87 }
     88 
     89 static struct op *
     90 pipeline(int cf)
     91 {
     92 	struct op *t, *p, *tl = NULL;
     93 
     94 	t = get_command(cf);
     95 	if (t != NULL) {
     96 		while (token(0) == '|') {
     97 			if ((p = get_command(CONTIN)) == NULL)
     98 				syntaxerr(NULL);
     99 			if (tl == NULL)
    100 				t = tl = block(TPIPE, t, p, NOWORDS);
    101 			else
    102 				tl = tl->right = block(TPIPE, tl->right, p, NOWORDS);
    103 		}
    104 		REJECT;
    105 	}
    106 	return (t);
    107 }
    108 
    109 static struct op *
    110 andor(void)
    111 {
    112 	struct op *t, *p;
    113 	int c;
    114 
    115 	t = pipeline(0);
    116 	if (t != NULL) {
    117 		while ((c = token(0)) == LOGAND || c == LOGOR) {
    118 			if ((p = pipeline(CONTIN)) == NULL)
    119 				syntaxerr(NULL);
    120 			t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS);
    121 		}
    122 		REJECT;
    123 	}
    124 	return (t);
    125 }
    126 
    127 static struct op *
    128 c_list(bool multi)
    129 {
    130 	struct op *t = NULL, *p, *tl = NULL;
    131 	int c;
    132 	bool have_sep;
    133 
    134 	while (/* CONSTCOND */ 1) {
    135 		p = andor();
    136 		/*
    137 		 * Token has always been read/rejected at this point, so
    138 		 * we don't worry about what flags to pass token()
    139 		 */
    140 		c = token(0);
    141 		have_sep = true;
    142 		if (c == '\n' && (multi || inalias(source))) {
    143 			if (!p)
    144 				/* ignore blank lines */
    145 				continue;
    146 		} else if (!p)
    147 			break;
    148 		else if (c == '&' || c == COPROC)
    149 			p = block(c == '&' ? TASYNC : TCOPROC,
    150 			    p, NOBLOCK, NOWORDS);
    151 		else if (c != ';')
    152 			have_sep = false;
    153 		if (!t)
    154 			t = p;
    155 		else if (!tl)
    156 			t = tl = block(TLIST, t, p, NOWORDS);
    157 		else
    158 			tl = tl->right = block(TLIST, tl->right, p, NOWORDS);
    159 		if (!have_sep)
    160 			break;
    161 	}
    162 	REJECT;
    163 	return (t);
    164 }
    165 
    166 static struct ioword *
    167 synio(int cf)
    168 {
    169 	struct ioword *iop;
    170 	static struct ioword *nextiop;
    171 	bool ishere;
    172 
    173 	if (nextiop != NULL) {
    174 		iop = nextiop;
    175 		nextiop = NULL;
    176 		return (iop);
    177 	}
    178 
    179 	if (tpeek(cf) != REDIR)
    180 		return (NULL);
    181 	ACCEPT;
    182 	iop = yylval.iop;
    183 	if (iop->flag & IONDELIM)
    184 		goto gotnulldelim;
    185 	ishere = (iop->flag & IOTYPE) == IOHERE;
    186 	musthave(LWORD, ishere ? HEREDELIM : 0);
    187 	if (ishere) {
    188 		iop->delim = yylval.cp;
    189 		if (*ident != 0)
    190 			/* unquoted */
    191  gotnulldelim:
    192 			iop->flag |= IOEVAL;
    193 		if (herep > &heres[HERES - 1])
    194 			yyerror("too many %ss\n", "<<");
    195 		*herep++ = iop;
    196 	} else
    197 		iop->name = yylval.cp;
    198 
    199 	if (iop->flag & IOBASH) {
    200 		char *cp;
    201 
    202 		nextiop = alloc(sizeof(*iop), ATEMP);
    203 		nextiop->name = cp = alloc(5, ATEMP);
    204 
    205 		if (iop->unit > 9) {
    206 			*cp++ = CHAR;
    207 			*cp++ = '0' + (iop->unit / 10);
    208 		}
    209 		*cp++ = CHAR;
    210 		*cp++ = '0' + (iop->unit % 10);
    211 		*cp = EOS;
    212 
    213 		iop->flag &= ~IOBASH;
    214 		nextiop->unit = 2;
    215 		nextiop->flag = IODUP;
    216 		nextiop->delim = NULL;
    217 		nextiop->heredoc = NULL;
    218 	}
    219 	return (iop);
    220 }
    221 
    222 static struct op *
    223 nested(int type, int smark, int emark)
    224 {
    225 	struct op *t;
    226 	struct nesting_state old_nesting;
    227 
    228 	nesting_push(&old_nesting, smark);
    229 	t = c_list(true);
    230 	musthave(emark, KEYWORD|ALIAS);
    231 	nesting_pop(&old_nesting);
    232 	return (block(type, t, NOBLOCK, NOWORDS));
    233 }
    234 
    235 static struct op *
    236 get_command(int cf)
    237 {
    238 	struct op *t;
    239 	int c, iopn = 0, syniocf;
    240 	struct ioword *iop, **iops;
    241 	XPtrV args, vars;
    242 	struct nesting_state old_nesting;
    243 
    244 	/* NUFILE is small enough to leave this addition unchecked */
    245 	iops = alloc2((NUFILE + 1), sizeof(struct ioword *), ATEMP);
    246 	XPinit(args, 16);
    247 	XPinit(vars, 16);
    248 
    249 	syniocf = KEYWORD|ALIAS;
    250 	switch (c = token(cf|KEYWORD|ALIAS|VARASN)) {
    251 	default:
    252 		REJECT;
    253 		afree(iops, ATEMP);
    254 		XPfree(args);
    255 		XPfree(vars);
    256 		/* empty line */
    257 		return (NULL);
    258 
    259 	case LWORD:
    260 	case REDIR:
    261 		REJECT;
    262 		syniocf &= ~(KEYWORD|ALIAS);
    263 		t = newtp(TCOM);
    264 		t->lineno = source->line;
    265 		while (/* CONSTCOND */ 1) {
    266 			cf = (t->u.evalflags ? ARRAYVAR : 0) |
    267 			    (XPsize(args) == 0 ? ALIAS|VARASN : CMDWORD);
    268 			switch (tpeek(cf)) {
    269 			case REDIR:
    270 				while ((iop = synio(cf)) != NULL) {
    271 					if (iopn >= NUFILE)
    272 						yyerror("too many %ss\n",
    273 						    "redirection");
    274 					iops[iopn++] = iop;
    275 				}
    276 				break;
    277 
    278 			case LWORD:
    279 				ACCEPT;
    280 				/*
    281 				 * the iopn == 0 and XPsize(vars) == 0 are
    282 				 * dubious but AT&T ksh acts this way
    283 				 */
    284 				if (iopn == 0 && XPsize(vars) == 0 &&
    285 				    XPsize(args) == 0 &&
    286 				    assign_command(ident))
    287 					t->u.evalflags = DOVACHECK;
    288 				if ((XPsize(args) == 0 || Flag(FKEYWORD)) &&
    289 				    is_wdvarassign(yylval.cp))
    290 					XPput(vars, yylval.cp);
    291 				else
    292 					XPput(args, yylval.cp);
    293 				break;
    294 
    295 			case '(':
    296 #ifndef MKSH_SMALL
    297 				if ((XPsize(args) == 0 || Flag(FKEYWORD)) &&
    298 				    XPsize(vars) == 1 && is_wdvarassign(yylval.cp))
    299 					goto is_wdarrassign;
    300 #endif
    301 				/*
    302 				 * Check for "> foo (echo hi)" which AT&T ksh
    303 				 * allows (not POSIX, but not disallowed)
    304 				 */
    305 				afree(t, ATEMP);
    306 				if (XPsize(args) == 0 && XPsize(vars) == 0) {
    307 					ACCEPT;
    308 					goto Subshell;
    309 				}
    310 
    311 				/* must be a function */
    312 				if (iopn != 0 || XPsize(args) != 1 ||
    313 				    XPsize(vars) != 0)
    314 					syntaxerr(NULL);
    315 				ACCEPT;
    316 				musthave(/*(*/')', 0);
    317 				t = function_body(XPptrv(args)[0], false);
    318 				goto Leave;
    319 #ifndef MKSH_SMALL
    320  is_wdarrassign:
    321 			{
    322 				static const char set_cmd0[] = {
    323 					CHAR, 's', CHAR, 'e',
    324 					CHAR, 't', EOS
    325 				};
    326 				static const char set_cmd1[] = {
    327 					CHAR, '-', CHAR, 'A', EOS
    328 				};
    329 				static const char set_cmd2[] = {
    330 					CHAR, '-', CHAR, '-', EOS
    331 				};
    332 				char *tcp;
    333 
    334 				ACCEPT;
    335 
    336 				/* manipulate the vars string */
    337 				tcp = *(--vars.cur);
    338 				/* 'varname=' -> 'varname' */
    339 				tcp[wdscan(tcp, EOS) - tcp - 3] = EOS;
    340 
    341 				/* construct new args strings */
    342 				XPput(args, wdcopy(set_cmd0, ATEMP));
    343 				XPput(args, wdcopy(set_cmd1, ATEMP));
    344 				XPput(args, tcp);
    345 				XPput(args, wdcopy(set_cmd2, ATEMP));
    346 
    347 				/* slurp in words till closing paren */
    348 				while (token(CONTIN) == LWORD)
    349 					XPput(args, yylval.cp);
    350 				if (symbol != /*(*/ ')')
    351 					syntaxerr(NULL);
    352 
    353 				goto Leave;
    354 			}
    355 #endif
    356 
    357 			default:
    358 				goto Leave;
    359 			}
    360 		}
    361  Leave:
    362 		break;
    363 
    364 	case '(':
    365  Subshell:
    366 		++subshell_nesting_level;
    367 		t = nested(TPAREN, '(', ')');
    368 		--subshell_nesting_level;
    369 		break;
    370 
    371 	case '{': /*}*/
    372 		t = nested(TBRACE, '{', '}');
    373 		break;
    374 
    375 	case MDPAREN: {
    376 		int lno;
    377 		static const char let_cmd[] = {
    378 			CHAR, 'l', CHAR, 'e',
    379 			CHAR, 't', EOS
    380 		};
    381 
    382 		/* leave KEYWORD in syniocf (allow if (( 1 )) then ...) */
    383 		lno = source->line;
    384 		ACCEPT;
    385 		switch (token(LETEXPR)) {
    386 		case LWORD:
    387 			break;
    388 		case '(': /*)*/
    389 			goto Subshell;
    390 		default:
    391 			syntaxerr(NULL);
    392 		}
    393 		t = newtp(TCOM);
    394 		t->lineno = lno;
    395 		XPput(args, wdcopy(let_cmd, ATEMP));
    396 		XPput(args, yylval.cp);
    397 		break;
    398 	}
    399 
    400 	case DBRACKET: /* [[ .. ]] */
    401 		/* leave KEYWORD in syniocf (allow if [[ -n 1 ]] then ...) */
    402 		t = newtp(TDBRACKET);
    403 		ACCEPT;
    404 		{
    405 			Test_env te;
    406 
    407 			te.flags = TEF_DBRACKET;
    408 			te.pos.av = &args;
    409 			te.isa = dbtestp_isa;
    410 			te.getopnd = dbtestp_getopnd;
    411 			te.eval = dbtestp_eval;
    412 			te.error = dbtestp_error;
    413 
    414 			test_parse(&te);
    415 		}
    416 		break;
    417 
    418 	case FOR:
    419 	case SELECT:
    420 		t = newtp((c == FOR) ? TFOR : TSELECT);
    421 		musthave(LWORD, ARRAYVAR);
    422 		if (!is_wdvarname(yylval.cp, true))
    423 			yyerror("%s: %s\n", c == FOR ? "for" : Tselect,
    424 			    "bad identifier");
    425 		strdupx(t->str, ident, ATEMP);
    426 		nesting_push(&old_nesting, c);
    427 		t->vars = wordlist();
    428 		t->left = dogroup();
    429 		nesting_pop(&old_nesting);
    430 		break;
    431 
    432 	case WHILE:
    433 	case UNTIL:
    434 		nesting_push(&old_nesting, c);
    435 		t = newtp((c == WHILE) ? TWHILE : TUNTIL);
    436 		t->left = c_list(true);
    437 		t->right = dogroup();
    438 		nesting_pop(&old_nesting);
    439 		break;
    440 
    441 	case CASE:
    442 		t = newtp(TCASE);
    443 		musthave(LWORD, 0);
    444 		t->str = yylval.cp;
    445 		nesting_push(&old_nesting, c);
    446 		t->left = caselist();
    447 		nesting_pop(&old_nesting);
    448 		break;
    449 
    450 	case IF:
    451 		nesting_push(&old_nesting, c);
    452 		t = newtp(TIF);
    453 		t->left = c_list(true);
    454 		t->right = thenpart();
    455 		musthave(FI, KEYWORD|ALIAS);
    456 		nesting_pop(&old_nesting);
    457 		break;
    458 
    459 	case BANG:
    460 		syniocf &= ~(KEYWORD|ALIAS);
    461 		t = pipeline(0);
    462 		if (t == NULL)
    463 			syntaxerr(NULL);
    464 		t = block(TBANG, NOBLOCK, t, NOWORDS);
    465 		break;
    466 
    467 	case TIME:
    468 		syniocf &= ~(KEYWORD|ALIAS);
    469 		t = pipeline(0);
    470 		if (t) {
    471 			t->str = alloc(2, ATEMP);
    472 			/* TF_* flags */
    473 			t->str[0] = '\0';
    474 			t->str[1] = '\0';
    475 		}
    476 		t = block(TTIME, t, NOBLOCK, NOWORDS);
    477 		break;
    478 
    479 	case FUNCTION:
    480 		musthave(LWORD, 0);
    481 		t = function_body(yylval.cp, true);
    482 		break;
    483 	}
    484 
    485 	while ((iop = synio(syniocf)) != NULL) {
    486 		if (iopn >= NUFILE)
    487 			yyerror("too many %ss\n", "redirection");
    488 		iops[iopn++] = iop;
    489 	}
    490 
    491 	if (iopn == 0) {
    492 		afree(iops, ATEMP);
    493 		t->ioact = NULL;
    494 	} else {
    495 		iops[iopn++] = NULL;
    496 		iops = aresize2(iops, iopn, sizeof(struct ioword *), ATEMP);
    497 		t->ioact = iops;
    498 	}
    499 
    500 	if (t->type == TCOM || t->type == TDBRACKET) {
    501 		XPput(args, NULL);
    502 		t->args = (const char **)XPclose(args);
    503 		XPput(vars, NULL);
    504 		t->vars = (char **) XPclose(vars);
    505 	} else {
    506 		XPfree(args);
    507 		XPfree(vars);
    508 	}
    509 
    510 	return (t);
    511 }
    512 
    513 static struct op *
    514 dogroup(void)
    515 {
    516 	int c;
    517 	struct op *list;
    518 
    519 	c = token(CONTIN|KEYWORD|ALIAS);
    520 	/*
    521 	 * A {...} can be used instead of do...done for for/select loops
    522 	 * but not for while/until loops - we don't need to check if it
    523 	 * is a while loop because it would have been parsed as part of
    524 	 * the conditional command list...
    525 	 */
    526 	if (c == DO)
    527 		c = DONE;
    528 	else if (c == '{')
    529 		c = '}';
    530 	else
    531 		syntaxerr(NULL);
    532 	list = c_list(true);
    533 	musthave(c, KEYWORD|ALIAS);
    534 	return (list);
    535 }
    536 
    537 static struct op *
    538 thenpart(void)
    539 {
    540 	struct op *t;
    541 
    542 	musthave(THEN, KEYWORD|ALIAS);
    543 	t = newtp(0);
    544 	t->left = c_list(true);
    545 	if (t->left == NULL)
    546 		syntaxerr(NULL);
    547 	t->right = elsepart();
    548 	return (t);
    549 }
    550 
    551 static struct op *
    552 elsepart(void)
    553 {
    554 	struct op *t;
    555 
    556 	switch (token(KEYWORD|ALIAS|VARASN)) {
    557 	case ELSE:
    558 		if ((t = c_list(true)) == NULL)
    559 			syntaxerr(NULL);
    560 		return (t);
    561 
    562 	case ELIF:
    563 		t = newtp(TELIF);
    564 		t->left = c_list(true);
    565 		t->right = thenpart();
    566 		return (t);
    567 
    568 	default:
    569 		REJECT;
    570 	}
    571 	return (NULL);
    572 }
    573 
    574 static struct op *
    575 caselist(void)
    576 {
    577 	struct op *t, *tl;
    578 	int c;
    579 
    580 	c = token(CONTIN|KEYWORD|ALIAS);
    581 	/* A {...} can be used instead of in...esac for case statements */
    582 	if (c == IN)
    583 		c = ESAC;
    584 	else if (c == '{')
    585 		c = '}';
    586 	else
    587 		syntaxerr(NULL);
    588 	t = tl = NULL;
    589 	/* no ALIAS here */
    590 	while ((tpeek(CONTIN|KEYWORD|ESACONLY)) != c) {
    591 		struct op *tc = casepart(c);
    592 		if (tl == NULL)
    593 			t = tl = tc, tl->right = NULL;
    594 		else
    595 			tl->right = tc, tl = tc;
    596 	}
    597 	musthave(c, KEYWORD|ALIAS);
    598 	return (t);
    599 }
    600 
    601 static struct op *
    602 casepart(int endtok)
    603 {
    604 	struct op *t;
    605 	XPtrV ptns;
    606 
    607 	XPinit(ptns, 16);
    608 	t = newtp(TPAT);
    609 	/* no ALIAS here */
    610 	if (token(CONTIN | KEYWORD) != '(')
    611 		REJECT;
    612 	do {
    613 		musthave(LWORD, 0);
    614 		XPput(ptns, yylval.cp);
    615 	} while (token(0) == '|');
    616 	REJECT;
    617 	XPput(ptns, NULL);
    618 	t->vars = (char **) XPclose(ptns);
    619 	musthave(')', 0);
    620 
    621 	t->left = c_list(true);
    622 	/* Note: POSIX requires the ;; */
    623 	if ((tpeek(CONTIN|KEYWORD|ALIAS)) != endtok)
    624 		switch (symbol) {
    625 		default:
    626 			syntaxerr(NULL);
    627 		case BREAK:
    628 		case BRKEV:
    629 		case BRKFT:
    630 			t->u.charflag =
    631 			    (symbol == BRKEV) ? '|' :
    632 			    (symbol == BRKFT) ? '&' : ';';
    633 			ACCEPT;
    634 		}
    635 	return (t);
    636 }
    637 
    638 static struct op *
    639 function_body(char *name,
    640     /* function foo { ... } vs foo() { .. } */
    641     bool ksh_func)
    642 {
    643 	char *sname, *p;
    644 	struct op *t;
    645 	bool old_func_parse;
    646 
    647 	sname = wdstrip(name, 0);
    648 	/*-
    649 	 * Check for valid characters in name. POSIX and AT&T ksh93 say
    650 	 * only allow [a-zA-Z_0-9] but this allows more as old pdkshs
    651 	 * have allowed more; the following were never allowed:
    652 	 *	NUL TAB NL SP " $ & ' ( ) ; < = > \ ` |
    653 	 * C_QUOTE covers all but adds # * ? [ ]
    654 	 */
    655 	for (p = sname; *p; p++)
    656 		if (ctype(*p, C_QUOTE))
    657 			yyerror("%s: %s\n", sname, "invalid function name");
    658 
    659 	/*
    660 	 * Note that POSIX allows only compound statements after foo(),
    661 	 * sh and AT&T ksh allow any command, go with the later since it
    662 	 * shouldn't break anything. However, for function foo, AT&T ksh
    663 	 * only accepts an open-brace.
    664 	 */
    665 	if (ksh_func) {
    666 		if (tpeek(CONTIN|KEYWORD|ALIAS) == '(' /*)*/) {
    667 			/* function foo () { */
    668 			ACCEPT;
    669 			musthave(')', 0);
    670 			/* degrade to POSIX function */
    671 			ksh_func = false;
    672 		}
    673 		musthave('{' /*}*/, CONTIN|KEYWORD|ALIAS);
    674 		REJECT;
    675 	}
    676 
    677 	t = newtp(TFUNCT);
    678 	t->str = sname;
    679 	t->u.ksh_func = tobool(ksh_func);
    680 	t->lineno = source->line;
    681 
    682 	old_func_parse = e->flags & EF_FUNC_PARSE;
    683 	e->flags |= EF_FUNC_PARSE;
    684 	if ((t->left = get_command(CONTIN)) == NULL) {
    685 		char *tv;
    686 		/*
    687 		 * Probably something like foo() followed by EOF or ';'.
    688 		 * This is accepted by sh and ksh88.
    689 		 * To make "typeset -f foo" work reliably (so its output can
    690 		 * be used as input), we pretend there is a colon here.
    691 		 */
    692 		t->left = newtp(TCOM);
    693 		/* (2 * sizeof(char *)) is small enough */
    694 		t->left->args = alloc(2 * sizeof(char *), ATEMP);
    695 		t->left->args[0] = tv = alloc(3, ATEMP);
    696 		tv[0] = CHAR;
    697 		tv[1] = ':';
    698 		tv[2] = EOS;
    699 		t->left->args[1] = NULL;
    700 		t->left->vars = alloc(sizeof(char *), ATEMP);
    701 		t->left->vars[0] = NULL;
    702 		t->left->lineno = 1;
    703 	}
    704 	if (!old_func_parse)
    705 		e->flags &= ~EF_FUNC_PARSE;
    706 
    707 	return (t);
    708 }
    709 
    710 static char **
    711 wordlist(void)
    712 {
    713 	int c;
    714 	XPtrV args;
    715 
    716 	XPinit(args, 16);
    717 	/* POSIX does not do alias expansion here... */
    718 	if ((c = token(CONTIN|KEYWORD|ALIAS)) != IN) {
    719 		if (c != ';')
    720 			/* non-POSIX, but AT&T ksh accepts a ; here */
    721 			REJECT;
    722 		return (NULL);
    723 	}
    724 	while ((c = token(0)) == LWORD)
    725 		XPput(args, yylval.cp);
    726 	if (c != '\n' && c != ';')
    727 		syntaxerr(NULL);
    728 	if (XPsize(args) == 0) {
    729 		XPfree(args);
    730 		return (NULL);
    731 	} else {
    732 		XPput(args, NULL);
    733 		return ((char **)XPclose(args));
    734 	}
    735 }
    736 
    737 /*
    738  * supporting functions
    739  */
    740 
    741 static struct op *
    742 block(int type, struct op *t1, struct op *t2, char **wp)
    743 {
    744 	struct op *t;
    745 
    746 	t = newtp(type);
    747 	t->left = t1;
    748 	t->right = t2;
    749 	t->vars = wp;
    750 	return (t);
    751 }
    752 
    753 const struct tokeninfo {
    754 	const char *name;
    755 	short val;
    756 	short reserved;
    757 } tokentab[] = {
    758 	/* Reserved words */
    759 	{ "if",		IF,	true },
    760 	{ "then",	THEN,	true },
    761 	{ "else",	ELSE,	true },
    762 	{ "elif",	ELIF,	true },
    763 	{ "fi",		FI,	true },
    764 	{ "case",	CASE,	true },
    765 	{ "esac",	ESAC,	true },
    766 	{ "for",	FOR,	true },
    767 	{ Tselect,	SELECT,	true },
    768 	{ "while",	WHILE,	true },
    769 	{ "until",	UNTIL,	true },
    770 	{ "do",		DO,	true },
    771 	{ "done",	DONE,	true },
    772 	{ "in",		IN,	true },
    773 	{ Tfunction,	FUNCTION, true },
    774 	{ "time",	TIME,	true },
    775 	{ "{",		'{',	true },
    776 	{ "}",		'}',	true },
    777 	{ "!",		BANG,	true },
    778 	{ "[[",		DBRACKET, true },
    779 	/* Lexical tokens (0[EOF], LWORD and REDIR handled specially) */
    780 	{ "&&",		LOGAND,	false },
    781 	{ "||",		LOGOR,	false },
    782 	{ ";;",		BREAK,	false },
    783 	{ ";|",		BRKEV,	false },
    784 	{ ";&",		BRKFT,	false },
    785 	{ "((",		MDPAREN, false },
    786 	{ "|&",		COPROC,	false },
    787 	/* and some special cases... */
    788 	{ "newline",	'\n',	false },
    789 	{ NULL,		0,	false }
    790 };
    791 
    792 void
    793 initkeywords(void)
    794 {
    795 	struct tokeninfo const *tt;
    796 	struct tbl *p;
    797 
    798 	ktinit(APERM, &keywords,
    799 	    /* currently 28 keywords -> 80% of 64 (2^6) */
    800 	    6);
    801 	for (tt = tokentab; tt->name; tt++) {
    802 		if (tt->reserved) {
    803 			p = ktenter(&keywords, tt->name, hash(tt->name));
    804 			p->flag |= DEFINED|ISSET;
    805 			p->type = CKEYWD;
    806 			p->val.i = tt->val;
    807 		}
    808 	}
    809 }
    810 
    811 static void
    812 syntaxerr(const char *what)
    813 {
    814 	/* 2<<- is the longest redirection, I think */
    815 	char redir[6];
    816 	const char *s;
    817 	struct tokeninfo const *tt;
    818 	int c;
    819 
    820 	if (!what)
    821 		what = "unexpected";
    822 	REJECT;
    823 	c = token(0);
    824  Again:
    825 	switch (c) {
    826 	case 0:
    827 		if (nesting.start_token) {
    828 			c = nesting.start_token;
    829 			source->errline = nesting.start_line;
    830 			what = "unmatched";
    831 			goto Again;
    832 		}
    833 		/* don't quote the EOF */
    834 		yyerror("%s: %s %s\n", Tsynerr, "unexpected", "EOF");
    835 		/* NOTREACHED */
    836 
    837 	case LWORD:
    838 		s = snptreef(NULL, 32, "%S", yylval.cp);
    839 		break;
    840 
    841 	case REDIR:
    842 		s = snptreef(redir, sizeof(redir), "%R", yylval.iop);
    843 		break;
    844 
    845 	default:
    846 		for (tt = tokentab; tt->name; tt++)
    847 			if (tt->val == c)
    848 			    break;
    849 		if (tt->name)
    850 			s = tt->name;
    851 		else {
    852 			if (c > 0 && c < 256) {
    853 				redir[0] = c;
    854 				redir[1] = '\0';
    855 			} else
    856 				shf_snprintf(redir, sizeof(redir),
    857 					"?%d", c);
    858 			s = redir;
    859 		}
    860 	}
    861 	yyerror("%s: '%s' %s\n", Tsynerr, s, what);
    862 }
    863 
    864 static void
    865 nesting_push(struct nesting_state *save, int tok)
    866 {
    867 	*save = nesting;
    868 	nesting.start_token = tok;
    869 	nesting.start_line = source->line;
    870 }
    871 
    872 static void
    873 nesting_pop(struct nesting_state *saved)
    874 {
    875 	nesting = *saved;
    876 }
    877 
    878 static struct op *
    879 newtp(int type)
    880 {
    881 	struct op *t;
    882 
    883 	t = alloc(sizeof(struct op), ATEMP);
    884 	t->type = type;
    885 	t->u.evalflags = 0;
    886 	t->args = NULL;
    887 	t->vars = NULL;
    888 	t->ioact = NULL;
    889 	t->left = t->right = NULL;
    890 	t->str = NULL;
    891 	return (t);
    892 }
    893 
    894 struct op *
    895 compile(Source *s, bool skiputf8bom)
    896 {
    897 	nesting.start_token = 0;
    898 	nesting.start_line = 0;
    899 	herep = heres;
    900 	source = s;
    901 	if (skiputf8bom)
    902 		yyskiputf8bom();
    903 	yyparse();
    904 	return (outtree);
    905 }
    906 
    907 /*-
    908  * This kludge exists to take care of sh/AT&T ksh oddity in which
    909  * the arguments of alias/export/readonly/typeset have no field
    910  * splitting, file globbing, or (normal) tilde expansion done.
    911  * AT&T ksh seems to do something similar to this since
    912  *	$ touch a=a; typeset a=[ab]; echo "$a"
    913  *	a=[ab]
    914  *	$ x=typeset; $x a=[ab]; echo "$a"
    915  *	a=a
    916  *	$
    917  */
    918 static int
    919 assign_command(char *s)
    920 {
    921 	if (!*s)
    922 		return (0);
    923 	return ((strcmp(s, Talias) == 0) ||
    924 	    (strcmp(s, "export") == 0) ||
    925 	    (strcmp(s, "readonly") == 0) ||
    926 	    (strcmp(s, Ttypeset) == 0));
    927 }
    928 
    929 /* Check if we are in the middle of reading an alias */
    930 static int
    931 inalias(struct source *s)
    932 {
    933 	for (; s && s->type == SALIAS; s = s->next)
    934 		if (!(s->flags & SF_ALIASEND))
    935 			return (1);
    936 	return (0);
    937 }
    938 
    939 
    940 /*
    941  * Order important - indexed by Test_meta values
    942  * Note that ||, &&, ( and ) can't appear in as unquoted strings
    943  * in normal shell input, so these can be interpreted unambiguously
    944  * in the evaluation pass.
    945  */
    946 static const char dbtest_or[] = { CHAR, '|', CHAR, '|', EOS };
    947 static const char dbtest_and[] = { CHAR, '&', CHAR, '&', EOS };
    948 static const char dbtest_not[] = { CHAR, '!', EOS };
    949 static const char dbtest_oparen[] = { CHAR, '(', EOS };
    950 static const char dbtest_cparen[] = { CHAR, ')', EOS };
    951 const char *const dbtest_tokens[] = {
    952 	dbtest_or, dbtest_and, dbtest_not,
    953 	dbtest_oparen, dbtest_cparen
    954 };
    955 const char db_close[] = { CHAR, ']', CHAR, ']', EOS };
    956 const char db_lthan[] = { CHAR, '<', EOS };
    957 const char db_gthan[] = { CHAR, '>', EOS };
    958 
    959 /*
    960  * Test if the current token is a whatever. Accepts the current token if
    961  * it is. Returns 0 if it is not, non-zero if it is (in the case of
    962  * TM_UNOP and TM_BINOP, the returned value is a Test_op).
    963  */
    964 static Test_op
    965 dbtestp_isa(Test_env *te, Test_meta meta)
    966 {
    967 	int c = tpeek(ARRAYVAR | (meta == TM_BINOP ? 0 : CONTIN));
    968 	int uqword;
    969 	char *save = NULL;
    970 	Test_op ret = TO_NONOP;
    971 
    972 	/* unquoted word? */
    973 	uqword = c == LWORD && *ident;
    974 
    975 	if (meta == TM_OR)
    976 		ret = c == LOGOR ? TO_NONNULL : TO_NONOP;
    977 	else if (meta == TM_AND)
    978 		ret = c == LOGAND ? TO_NONNULL : TO_NONOP;
    979 	else if (meta == TM_NOT)
    980 		ret = (uqword && !strcmp(yylval.cp,
    981 		    dbtest_tokens[(int)TM_NOT])) ? TO_NONNULL : TO_NONOP;
    982 	else if (meta == TM_OPAREN)
    983 		ret = c == '(' /*)*/ ? TO_NONNULL : TO_NONOP;
    984 	else if (meta == TM_CPAREN)
    985 		ret = c == /*(*/ ')' ? TO_NONNULL : TO_NONOP;
    986 	else if (meta == TM_UNOP || meta == TM_BINOP) {
    987 		if (meta == TM_BINOP && c == REDIR &&
    988 		    (yylval.iop->flag == IOREAD || yylval.iop->flag == IOWRITE)) {
    989 			ret = TO_NONNULL;
    990 			save = wdcopy(yylval.iop->flag == IOREAD ?
    991 			    db_lthan : db_gthan, ATEMP);
    992 		} else if (uqword && (ret = test_isop(meta, ident)))
    993 			save = yylval.cp;
    994 	} else
    995 		/* meta == TM_END */
    996 		ret = (uqword && !strcmp(yylval.cp,
    997 		    db_close)) ? TO_NONNULL : TO_NONOP;
    998 	if (ret != TO_NONOP) {
    999 		ACCEPT;
   1000 		if (meta < NELEM(dbtest_tokens))
   1001 			save = wdcopy(dbtest_tokens[(int)meta], ATEMP);
   1002 		if (save)
   1003 			XPput(*te->pos.av, save);
   1004 	}
   1005 	return (ret);
   1006 }
   1007 
   1008 static const char *
   1009 dbtestp_getopnd(Test_env *te, Test_op op MKSH_A_UNUSED,
   1010     bool do_eval MKSH_A_UNUSED)
   1011 {
   1012 	int c = tpeek(ARRAYVAR);
   1013 
   1014 	if (c != LWORD)
   1015 		return (NULL);
   1016 
   1017 	ACCEPT;
   1018 	XPput(*te->pos.av, yylval.cp);
   1019 
   1020 	return (null);
   1021 }
   1022 
   1023 static int
   1024 dbtestp_eval(Test_env *te MKSH_A_UNUSED, Test_op op MKSH_A_UNUSED,
   1025     const char *opnd1 MKSH_A_UNUSED, const char *opnd2 MKSH_A_UNUSED,
   1026     bool do_eval MKSH_A_UNUSED)
   1027 {
   1028 	return (1);
   1029 }
   1030 
   1031 static void
   1032 dbtestp_error(Test_env *te, int offset, const char *msg)
   1033 {
   1034 	te->flags |= TEF_ERROR;
   1035 
   1036 	if (offset < 0) {
   1037 		REJECT;
   1038 		/* Kludgy to say the least... */
   1039 		symbol = LWORD;
   1040 		yylval.cp = *(XPptrv(*te->pos.av) + XPsize(*te->pos.av) +
   1041 		    offset);
   1042 	}
   1043 	syntaxerr(msg);
   1044 }
   1045 
   1046 #if HAVE_SELECT
   1047 
   1048 #ifndef EOVERFLOW
   1049 #ifdef ERANGE
   1050 #define EOVERFLOW	ERANGE
   1051 #else
   1052 #define EOVERFLOW	EINVAL
   1053 #endif
   1054 #endif
   1055 
   1056 bool
   1057 parse_usec(const char *s, struct timeval *tv)
   1058 {
   1059 	struct timeval tt;
   1060 	int i;
   1061 
   1062 	tv->tv_sec = 0;
   1063 	/* parse integral part */
   1064 	while (ksh_isdigit(*s)) {
   1065 		tt.tv_sec = tv->tv_sec * 10 + (*s++ - '0');
   1066 		if (tt.tv_sec / 10 != tv->tv_sec) {
   1067 			errno = EOVERFLOW;
   1068 			return (true);
   1069 		}
   1070 		tv->tv_sec = tt.tv_sec;
   1071 	}
   1072 
   1073 	tv->tv_usec = 0;
   1074 	if (!*s)
   1075 		/* no decimal fraction */
   1076 		return (false);
   1077 	else if (*s++ != '.') {
   1078 		/* junk after integral part */
   1079 		errno = EINVAL;
   1080 		return (true);
   1081 	}
   1082 
   1083 	/* parse decimal fraction */
   1084 	i = 100000;
   1085 	while (ksh_isdigit(*s)) {
   1086 		tv->tv_usec += i * (*s++ - '0');
   1087 		if (i == 1)
   1088 			break;
   1089 		i /= 10;
   1090 	}
   1091 	/* check for junk after fractional part */
   1092 	while (ksh_isdigit(*s))
   1093 		++s;
   1094 	if (*s) {
   1095 		errno = EINVAL;
   1096 		return (true);
   1097 	}
   1098 
   1099 	/* end of input string reached, no errors */
   1100 	return (false);
   1101 }
   1102 #endif
   1103 
   1104 /*
   1105  * Helper function called from within lex.c:yylex() to parse
   1106  * a COMSUB recursively using the main shell parser and lexer
   1107  */
   1108 char *
   1109 yyrecursive(void)
   1110 {
   1111 	struct op *t;
   1112 	char *cp;
   1113 	bool old_reject;
   1114 	int old_symbol;
   1115 	struct ioword **old_herep;
   1116 
   1117 	/* tell the lexer to accept a closing parenthesis as EOD */
   1118 	++subshell_nesting_level;
   1119 
   1120 	/* push reject state, parse recursively, pop reject state */
   1121 	old_reject = reject;
   1122 	old_symbol = symbol;
   1123 	ACCEPT;
   1124 	old_herep = herep;
   1125 	/* we use TPAREN as a helper container here */
   1126 	t = nested(TPAREN, '(', ')');
   1127 	herep = old_herep;
   1128 	reject = old_reject;
   1129 	symbol = old_symbol;
   1130 
   1131 	/* t->left because nested(TPAREN, ...) hides our goodies there */
   1132 	cp = snptreef(NULL, 0, "%T", t->left);
   1133 	tfree(t, ATEMP);
   1134 
   1135 	--subshell_nesting_level;
   1136 	return (cp);
   1137 }
   1138