1811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser/* $OpenBSD: syn.c,v 1.29 2013/06/03 18:40:05 jca Exp $ */ 25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 4c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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/syn.c,v 1.92 2013/06/03 22:28:17 tg Exp $"); 275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct nesting_state { 295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int start_token; /* token than began nesting (eg, FOR) */ 305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int start_line; /* line nesting began on */ 315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 33c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstruct yyrecursive_state { 34c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct yyrecursive_state *next; 35c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct ioword **old_herep; 36c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int old_symbol; 37c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int old_salias; 38c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int old_nesting_type; 39c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool old_reject; 40c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser}; 41c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void yyparse(void); 435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *pipeline(int); 445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *andor(void); 4503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic struct op *c_list(bool); 465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct ioword *synio(int); 475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *nested(int, int, int); 485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *get_command(int); 495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *dogroup(void); 505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *thenpart(void); 515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *elsepart(void); 525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *caselist(void); 535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *casepart(int); 545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *function_body(char *, bool); 555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char **wordlist(void); 56811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserstatic struct op *block(int, struct op *, struct op *); 575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *newtp(int); 585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void syntaxerr(const char *) MKSH_A_NORETURN; 595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void nesting_push(struct nesting_state *, int); 605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void nesting_pop(struct nesting_state *); 61c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic int assign_command(const char *); 625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int inalias(struct source *); 635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Test_op dbtestp_isa(Test_env *, Test_meta); 645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *dbtestp_getopnd(Test_env *, Test_op, bool); 655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int dbtestp_eval(Test_env *, Test_op, const char *, 665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *, bool); 675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void dbtestp_error(Test_env *, int, const char *) MKSH_A_NORETURN; 685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op *outtree; /* yyparse output */ 705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct nesting_state nesting; /* \n changed to ; */ 715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic bool reject; /* token(cf) gets symbol again */ 7303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int symbol; /* yylex value */ 74c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic int sALIAS = ALIAS; /* 0 in yyrecursive */ 755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define REJECT (reject = true) 7703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define ACCEPT (reject = false) 785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define token(cf) ((reject) ? (ACCEPT, symbol) : (symbol = yylex(cf))) 795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define tpeek(cf) ((reject) ? (symbol) : (REJECT, symbol = yylex(cf))) 8003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define musthave(c,cf) do { if (token(cf) != (c)) syntaxerr(NULL); } while (/* CONSTCOND */ 0) 815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 82c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char Tcbrace[] = "}"; 83c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char Tesac[] = "esac"; 84c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruyyparse(void) 875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru outtree = c_list(source->type == SSTRING); 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = tpeek(0); 945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == 0 && !outtree) 955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru outtree = newtp(TEOF); 965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c != '\n' && c != 0) 975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupipeline(int cf) 1025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t, *p, *tl = NULL; 1045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = get_command(cf); 1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t != NULL) { 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (token(0) == '|') { 1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = get_command(CONTIN)) == NULL) 1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tl == NULL) 111811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser t = tl = block(TPIPE, t, p); 1125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 113811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser tl = tl->right = block(TPIPE, tl->right, p); 1145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 1165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 1185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruandor(void) 1225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t, *p; 1245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 1255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = pipeline(0); 1275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t != NULL) { 1285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = token(0)) == LOGAND || c == LOGOR) { 1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = pipeline(CONTIN)) == NULL) 1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 131811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser t = block(c == LOGAND? TAND: TOR, t, p); 1325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 1345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 1365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 13903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrac_list(bool multi) 1405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t = NULL, *p, *tl = NULL; 14203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int c; 14303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool have_sep; 1445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 1465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = andor(); 14703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 14803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Token has always been read/rejected at this point, so 1495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * we don't worry about what flags to pass token() 1505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = token(0); 15203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra have_sep = true; 1535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\n' && (multi || inalias(source))) { 15403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!p) 15503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ignore blank lines */ 1565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 1575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!p) 1585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '&' || c == COPROC) 160811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser p = block(c == '&' ? TASYNC : TCOPROC, p, NULL); 1615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c != ';') 16203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra have_sep = false; 1635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!t) 1645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = p; 1655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (!tl) 166811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser t = tl = block(TLIST, t, p); 1675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 168811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser tl = tl->right = block(TLIST, tl->right, p); 1695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!have_sep) 1705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 1735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct ioword * 1775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusynio(int cf) 1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct ioword *iop; 18003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra static struct ioword *nextiop; 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool ishere; 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (nextiop != NULL) { 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop = nextiop; 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nextiop = NULL; 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (iop); 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tpeek(cf) != REDIR) 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop = yylval.iop; 19303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (iop->flag & IONDELIM) 19403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto gotnulldelim; 19503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ishere = (iop->flag & IOTYPE) == IOHERE; 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru musthave(LWORD, ishere ? HEREDELIM : 0); 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ishere) { 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->delim = yylval.cp; 19903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*ident != 0) 20003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* unquoted */ 20103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra gotnulldelim: 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IOEVAL; 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (herep > &heres[HERES - 1]) 20403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("too many %ss\n", "<<"); 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *herep++ = iop; 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->name = yylval.cp; 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->flag & IOBASH) { 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp; 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nextiop = alloc(sizeof(*iop), ATEMP); 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nextiop->name = cp = alloc(5, ATEMP); 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->unit > 9) { 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *cp++ = CHAR; 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *cp++ = '0' + (iop->unit / 10); 2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *cp++ = CHAR; 2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *cp++ = '0' + (iop->unit % 10); 2215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *cp = EOS; 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag &= ~IOBASH; 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nextiop->unit = 2; 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nextiop->flag = IODUP; 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nextiop->delim = NULL; 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nextiop->heredoc = NULL; 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (iop); 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querunested(int type, int smark, int emark) 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct nesting_state old_nesting; 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_push(&old_nesting, smark); 2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = c_list(true); 240c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser musthave(emark, KEYWORD|sALIAS); 2415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_pop(&old_nesting); 242811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser return (block(type, t, NULL)); 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 245c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char let_cmd[] = { 246811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser CHAR, 'l', CHAR, 'e', CHAR, 't', CHAR, ']', EOS 247c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser}; 248c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char setA_cmd0[] = { 249c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser CHAR, 's', CHAR, 'e', CHAR, 't', EOS 250c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser}; 251c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char setA_cmd1[] = { 252c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser CHAR, '-', CHAR, 'A', EOS 253c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser}; 254c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char setA_cmd2[] = { 255c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser CHAR, '-', CHAR, '-', EOS 256c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser}; 257c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 2595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruget_command(int cf) 2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 262c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int c, iopn = 0, syniocf, lno; 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct ioword *iop, **iops; 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPtrV args, vars; 265c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser char *tcp; 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct nesting_state old_nesting; 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 26803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* NUFILE is small enough to leave this addition unchecked */ 26903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra iops = alloc2((NUFILE + 1), sizeof(struct ioword *), ATEMP); 2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPinit(args, 16); 2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPinit(vars, 16); 2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 273c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser syniocf = KEYWORD|sALIAS; 274c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (c = token(cf|KEYWORD|sALIAS|VARASN)) { 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(iops, ATEMP); 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPfree(args); 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPfree(vars); 28003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* empty line */ 28103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (NULL); 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LWORD: 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case REDIR: 2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 286c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser syniocf &= ~(KEYWORD|sALIAS); 2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(TCOM); 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->lineno = source->line; 28903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cf = (t->u.evalflags ? ARRAYVAR : 0) | 291c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (XPsize(args) == 0 ? sALIAS|VARASN : CMDWORD); 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (tpeek(cf)) { 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case REDIR: 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((iop = synio(cf)) != NULL) { 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iopn >= NUFILE) 29603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("too many %ss\n", 29703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "redirection"); 2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iops[iopn++] = iop; 2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LWORD: 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 30403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 30503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * the iopn == 0 and XPsize(vars) == 0 are 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * dubious but AT&T ksh acts this way 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iopn == 0 && XPsize(vars) == 0 && 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPsize(args) == 0 && 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru assign_command(ident)) 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->u.evalflags = DOVACHECK; 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((XPsize(args) == 0 || Flag(FKEYWORD)) && 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru is_wdvarassign(yylval.cp)) 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(vars, yylval.cp); 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(args, yylval.cp); 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 319c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '(' /*)*/: 320c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (XPsize(args) == 0 && XPsize(vars) == 1 && 321c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser is_wdvarassign(yylval.cp)) { 322c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* wdarrassign: foo=(bar) */ 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 32403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 325c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* manipulate the vars string */ 326c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tcp = XPptrv(vars)[(vars.len = 0)]; 327c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 'varname=' -> 'varname' */ 328c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser tcp[wdscan(tcp, EOS) - tcp - 3] = EOS; 329c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 330c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* construct new args strings */ 331c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XPput(args, wdcopy(setA_cmd0, ATEMP)); 332c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XPput(args, wdcopy(setA_cmd1, ATEMP)); 333c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XPput(args, tcp); 334c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XPput(args, wdcopy(setA_cmd2, ATEMP)); 335c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 336c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* slurp in words till closing paren */ 337c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while (token(CONTIN) == LWORD) 338c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XPput(args, yylval.cp); 339c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (symbol != /*(*/ ')') 340c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser syntaxerr(NULL); 341c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else { 342c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 343c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Check for "> foo (echo hi)" 344c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * which AT&T ksh allows (not 345c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * POSIX, but not disallowed) 346c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 347c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afree(t, ATEMP); 348c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (XPsize(args) == 0 && 349c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XPsize(vars) == 0) { 350c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ACCEPT; 351c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto Subshell; 352c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 353c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 354c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* must be a function */ 355c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (iopn != 0 || XPsize(args) != 1 || 356c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XPsize(vars) != 0) 357c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser syntaxerr(NULL); 358c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ACCEPT; 359c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser musthave(/*(*/')', 0); 360c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser t = function_body(XPptrv(args)[0], false); 361c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 36203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto Leave; 3635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Leave; 3665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Leave: 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 371c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '(': /*)*/ { 372c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int subshell_nesting_type_saved; 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Subshell: 374c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subshell_nesting_type_saved = subshell_nesting_type; 375c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subshell_nesting_type = ')'; 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = nested(TPAREN, '(', ')'); 377c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subshell_nesting_type = subshell_nesting_type_saved; 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 379c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '{': /*}*/ 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = nested(TBRACE, '{', '}'); 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 385c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case MDPAREN: 38603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* leave KEYWORD in syniocf (allow if (( 1 )) then ...) */ 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lno = source->line; 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (token(LETEXPR)) { 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LWORD: 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 39203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '(': /*)*/ 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subshell; 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(TCOM); 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->lineno = lno; 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(args, wdcopy(let_cmd, ATEMP)); 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(args, yylval.cp); 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case DBRACKET: /* [[ .. ]] */ 40403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* leave KEYWORD in syniocf (allow if [[ -n 1 ]] then ...) */ 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(TDBRACKET); 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_env te; 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.flags = TEF_DBRACKET; 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.pos.av = &args; 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.isa = dbtestp_isa; 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.getopnd = dbtestp_getopnd; 4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.eval = dbtestp_eval; 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te.error = dbtestp_error; 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru test_parse(&te); 4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case FOR: 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SELECT: 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp((c == FOR) ? TFOR : TSELECT); 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru musthave(LWORD, ARRAYVAR); 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!is_wdvarname(yylval.cp, true)) 42603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("%s: %s\n", c == FOR ? "for" : Tselect, 42703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "bad identifier"); 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(t->str, ident, ATEMP); 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_push(&old_nesting, c); 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->vars = wordlist(); 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = dogroup(); 4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_pop(&old_nesting); 4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case WHILE: 4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case UNTIL: 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_push(&old_nesting, c); 4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp((c == WHILE) ? TWHILE : TUNTIL); 4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = c_list(true); 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->right = dogroup(); 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_pop(&old_nesting); 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case CASE: 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(TCASE); 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru musthave(LWORD, 0); 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str = yylval.cp; 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_push(&old_nesting, c); 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = caselist(); 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_pop(&old_nesting); 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case IF: 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_push(&old_nesting, c); 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(TIF); 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = c_list(true); 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->right = thenpart(); 458c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser musthave(FI, KEYWORD|sALIAS); 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting_pop(&old_nesting); 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case BANG: 463c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser syniocf &= ~(KEYWORD|sALIAS); 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = pipeline(0); 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t == NULL) 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 467811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser t = block(TBANG, NULL, t); 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case TIME: 471c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser syniocf &= ~(KEYWORD|sALIAS); 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = pipeline(0); 473c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (t && t->type == TCOM) { 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str = alloc(2, ATEMP); 47503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* TF_* flags */ 47603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra t->str[0] = '\0'; 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str[1] = '\0'; 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 479811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser t = block(TTIME, t, NULL); 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case FUNCTION: 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru musthave(LWORD, 0); 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = function_body(yylval.cp, true); 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((iop = synio(syniocf)) != NULL) { 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iopn >= NUFILE) 49003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("too many %ss\n", "redirection"); 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iops[iopn++] = iop; 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iopn == 0) { 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(iops, ATEMP); 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->ioact = NULL; 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iops[iopn++] = NULL; 49903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra iops = aresize2(iops, iopn, sizeof(struct ioword *), ATEMP); 5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->ioact = iops; 5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->type == TCOM || t->type == TDBRACKET) { 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(args, NULL); 5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->args = (const char **)XPclose(args); 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(vars, NULL); 507811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser t->vars = (char **)XPclose(vars); 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPfree(args); 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPfree(vars); 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querudogroup(void) 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *list; 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 522c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c = token(CONTIN|KEYWORD|sALIAS); 52303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 52403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * A {...} can be used instead of do...done for for/select loops 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * but not for while/until loops - we don't need to check if it 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is a while loop because it would have been parsed as part of 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the conditional command list... 5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == DO) 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = DONE; 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '{') 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = '}'; 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru list = c_list(true); 536c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser musthave(c, KEYWORD|sALIAS); 5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (list); 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruthenpart(void) 5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 545c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser musthave(THEN, KEYWORD|sALIAS); 5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(0); 5475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = c_list(true); 5485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->left == NULL) 5495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->right = elsepart(); 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruelsepart(void) 5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 559c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (token(KEYWORD|sALIAS|VARASN)) { 5605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case ELSE: 5615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((t = c_list(true)) == NULL) 5625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 5645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case ELIF: 5665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(TELIF); 5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = c_list(true); 5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->right = thenpart(); 5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucaselist(void) 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t, *tl; 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 583c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c = token(CONTIN|KEYWORD|sALIAS); 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* A {...} can be used instead of in...esac for case statements */ 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == IN) 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = ESAC; 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '{') 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = '}'; 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = tl = NULL; 59203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no ALIAS here */ 59303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((tpeek(CONTIN|KEYWORD|ESACONLY)) != c) { 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *tc = casepart(c); 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tl == NULL) 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = tl = tc, tl->right = NULL; 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tl->right = tc, tl = tc; 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 600c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser musthave(c, KEYWORD|sALIAS); 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucasepart(int endtok) 6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPtrV ptns; 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPinit(ptns, 16); 6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(TPAT); 6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* no ALIAS here */ 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (token(CONTIN | KEYWORD) != '(') 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 616c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (token(0)) { 617c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case LWORD: 618c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 619c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '}': 620c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case ESAC: 621c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (symbol != endtok) { 622c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser strdupx(yylval.cp, 623c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser symbol == '}' ? Tcbrace : Tesac, ATEMP); 624c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 625c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 626c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 627c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 628c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser syntaxerr(NULL); 629c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(ptns, yylval.cp); 6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (token(0) == '|'); 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(ptns, NULL); 634811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser t->vars = (char **)XPclose(ptns); 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru musthave(')', 0); 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = c_list(true); 638c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 639c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* initialise to default for ;; or omitted */ 640c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser t->u.charflag = ';'; 641c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* SUSv4 requires the ;; except in the last casepart */ 642c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((tpeek(CONTIN|KEYWORD|sALIAS)) != endtok) 64303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (symbol) { 64403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra default: 64503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra syntaxerr(NULL); 64603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case BRKEV: 647c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser t->u.charflag = '|'; 648c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (0) 649c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 65003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case BRKFT: 651c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser t->u.charflag = '&'; 652c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 653c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case BREAK: 654c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* initialised above, but we need to eat the token */ 65503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ACCEPT; 65603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querufunction_body(char *name, 66203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* function foo { ... } vs foo() { .. } */ 66303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool ksh_func) 6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *sname, *p; 6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 66803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sname = wdstrip(name, 0); 66903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*- 67003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Check for valid characters in name. POSIX and AT&T ksh93 say 67103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * only allow [a-zA-Z_0-9] but this allows more as old pdkshs 67203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * have allowed more; the following were never allowed: 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * NUL TAB NL SP " $ & ' ( ) ; < = > \ ` | 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * C_QUOTE covers all but adds # * ? [ ] 6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = sname; *p; p++) 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ctype(*p, C_QUOTE)) 67803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("%s: %s\n", sname, "invalid function name"); 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 68003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 68103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Note that POSIX allows only compound statements after foo(), 68203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * sh and AT&T ksh allow any command, go with the later since it 68303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * shouldn't break anything. However, for function foo, AT&T ksh 68403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * only accepts an open-brace. 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_func) { 687c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (tpeek(CONTIN|KEYWORD|sALIAS) == '(' /*)*/) { 688c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* function foo () { //}*/ 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru musthave(')', 0); 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* degrade to POSIX function */ 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_func = false; 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 694c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser musthave('{' /*}*/, CONTIN|KEYWORD|sALIAS); 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(TFUNCT); 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str = sname; 70003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra t->u.ksh_func = tobool(ksh_func); 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->lineno = source->line; 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((t->left = get_command(CONTIN)) == NULL) { 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *tv; 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 70603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Probably something like foo() followed by EOF or ';'. 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This is accepted by sh and ksh88. 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * To make "typeset -f foo" work reliably (so its output can 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * be used as input), we pretend there is a colon here. 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = newtp(TCOM); 71203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* (2 * sizeof(char *)) is small enough */ 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left->args = alloc(2 * sizeof(char *), ATEMP); 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left->args[0] = tv = alloc(3, ATEMP); 7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv[0] = CHAR; 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv[1] = ':'; 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tv[2] = EOS; 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left->args[1] = NULL; 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left->vars = alloc(sizeof(char *), ATEMP); 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left->vars[0] = NULL; 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left->lineno = 1; 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char ** 7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwordlist(void) 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPtrV args; 7325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPinit(args, 16); 7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* POSIX does not do alias expansion here... */ 735c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((c = token(CONTIN|KEYWORD|sALIAS)) != IN) { 73603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c != ';') 73703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* non-POSIX, but AT&T ksh accepts a ; here */ 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = token(0)) == LWORD) 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(args, yylval.cp); 7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != '\n' && c != ';') 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(NULL); 745811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser XPput(args, NULL); 746811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser return ((char **)XPclose(args)); 7475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 7505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * supporting functions 7515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 754811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserblock(int type, struct op *t1, struct op *t2) 7555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 7565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 7575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = newtp(type); 7595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = t1; 7605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->right = t2; 7615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 7625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 764c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const struct tokeninfo { 7655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *name; 7665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru short val; 7675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru short reserved; 7685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} tokentab[] = { 7695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Reserved words */ 7705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "if", IF, true }, 7715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "then", THEN, true }, 7725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "else", ELSE, true }, 7735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "elif", ELIF, true }, 7745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "fi", FI, true }, 7755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "case", CASE, true }, 776c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser { Tesac, ESAC, true }, 7775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "for", FOR, true }, 77803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra { Tselect, SELECT, true }, 7795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "while", WHILE, true }, 7805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "until", UNTIL, true }, 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "do", DO, true }, 7825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "done", DONE, true }, 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "in", IN, true }, 78403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra { Tfunction, FUNCTION, true }, 7855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "time", TIME, true }, 7865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "{", '{', true }, 787c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser { Tcbrace, '}', true }, 7885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "!", BANG, true }, 7895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "[[", DBRACKET, true }, 7905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Lexical tokens (0[EOF], LWORD and REDIR handled specially) */ 7915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "&&", LOGAND, false }, 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "||", LOGOR, false }, 7935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { ";;", BREAK, false }, 79403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra { ";|", BRKEV, false }, 79503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra { ";&", BRKFT, false }, 7965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "((", MDPAREN, false }, 7975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "|&", COPROC, false }, 7985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* and some special cases... */ 7995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { "newline", '\n', false }, 8005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { NULL, 0, false } 8015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 8025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 8045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinitkeywords(void) 8055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 8065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tokeninfo const *tt; 8075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *p; 8085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 80903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &keywords, 810c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* currently 28 keywords: 75% of 64 = 2^6 */ 81103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 6); 8125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (tt = tokentab; tt->name; tt++) { 8135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tt->reserved) { 8145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = ktenter(&keywords, tt->name, hash(tt->name)); 8155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flag |= DEFINED|ISSET; 8165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->type = CKEYWD; 8175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->val.i = tt->val; 8185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 8235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusyntaxerr(const char *what) 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 82503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 2<<- is the longest redirection, I think */ 82603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char redir[6]; 8275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s; 8285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tokeninfo const *tt; 8295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 8305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!what) 8325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru what = "unexpected"; 8335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 8345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = token(0); 8355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Again: 8365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 8375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 0: 8385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (nesting.start_token) { 8395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = nesting.start_token; 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->errline = nesting.start_line; 8415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru what = "unmatched"; 8425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Again; 8435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* don't quote the EOF */ 84503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("%s: %s %s\n", Tsynerr, "unexpected", "EOF"); 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NOTREACHED */ 8475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case LWORD: 8495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = snptreef(NULL, 32, "%S", yylval.cp); 8505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case REDIR: 8535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = snptreef(redir, sizeof(redir), "%R", yylval.iop); 8545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 8575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (tt = tokentab; tt->name; tt++) 8585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tt->val == c) 8595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tt->name) 8615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = tt->name; 8625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 8635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c > 0 && c < 256) { 8645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru redir[0] = c; 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru redir[1] = '\0'; 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_snprintf(redir, sizeof(redir), 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "?%d", c); 8695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = redir; 8705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 87203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("%s: '%s' %s\n", Tsynerr, s, what); 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 8765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querunesting_push(struct nesting_state *save, int tok) 8775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 8785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *save = nesting; 8795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting.start_token = tok; 8805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting.start_line = source->line; 8815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querunesting_pop(struct nesting_state *saved) 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting = *saved; 8875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct op * 8905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querunewtp(int type) 8915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 8925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct op *t; 8935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t = alloc(sizeof(struct op), ATEMP); 8955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->type = type; 8965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->u.evalflags = 0; 8975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->args = NULL; 8985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->vars = NULL; 8995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->ioact = NULL; 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->left = t->right = NULL; 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->str = NULL; 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (t); 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct op * 90603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condracompile(Source *s, bool skiputf8bom) 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting.start_token = 0; 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nesting.start_line = 0; 9105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru herep = heres; 9115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 91203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (skiputf8bom) 91303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyskiputf8bom(); 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyparse(); 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (outtree); 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 91803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*- 91903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * This kludge exists to take care of sh/AT&T ksh oddity in which 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the arguments of alias/export/readonly/typeset have no field 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * splitting, file globbing, or (normal) tilde expansion done. 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * AT&T ksh seems to do something similar to this since 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * $ touch a=a; typeset a=[ab]; echo "$a" 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a=[ab] 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * $ x=typeset; $x a=[ab]; echo "$a" 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a=a 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * $ 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 930c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserassign_command(const char *s) 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*s) 9335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 93403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return ((strcmp(s, Talias) == 0) || 935c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (strcmp(s, Texport) == 0) || 936c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (strcmp(s, Treadonly) == 0) || 93703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (strcmp(s, Ttypeset) == 0)); 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Check if we are in the middle of reading an alias */ 9415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 9425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinalias(struct source *s) 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; s && s->type == SALIAS; s = s->next) 9455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(s->flags & SF_ALIASEND)) 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 9485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 95103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 95203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Order important - indexed by Test_meta values 9535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Note that ||, &&, ( and ) can't appear in as unquoted strings 9545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * in normal shell input, so these can be interpreted unambiguously 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * in the evaluation pass. 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char dbtest_or[] = { CHAR, '|', CHAR, '|', EOS }; 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char dbtest_and[] = { CHAR, '&', CHAR, '&', EOS }; 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char dbtest_not[] = { CHAR, '!', EOS }; 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char dbtest_oparen[] = { CHAR, '(', EOS }; 9615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char dbtest_cparen[] = { CHAR, ')', EOS }; 962c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserconst char * const dbtest_tokens[] = { 9635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dbtest_or, dbtest_and, dbtest_not, 9645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dbtest_oparen, dbtest_cparen 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 966c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char db_close[] = { CHAR, ']', CHAR, ']', EOS }; 967c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char db_lthan[] = { CHAR, '<', EOS }; 968c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic const char db_gthan[] = { CHAR, '>', EOS }; 9695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Test if the current token is a whatever. Accepts the current token if 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * it is. Returns 0 if it is not, non-zero if it is (in the case of 9735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * TM_UNOP and TM_BINOP, the returned value is a Test_op). 9745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Test_op 9765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querudbtestp_isa(Test_env *te, Test_meta meta) 9775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c = tpeek(ARRAYVAR | (meta == TM_BINOP ? 0 : CONTIN)); 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int uqword; 9805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *save = NULL; 9815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Test_op ret = TO_NONOP; 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unquoted word? */ 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uqword = c == LWORD && *ident; 9855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (meta == TM_OR) 9875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = c == LOGOR ? TO_NONNULL : TO_NONOP; 9885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (meta == TM_AND) 9895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = c == LOGAND ? TO_NONNULL : TO_NONOP; 9905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (meta == TM_NOT) 9915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = (uqword && !strcmp(yylval.cp, 9925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dbtest_tokens[(int)TM_NOT])) ? TO_NONNULL : TO_NONOP; 9935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (meta == TM_OPAREN) 9945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = c == '(' /*)*/ ? TO_NONNULL : TO_NONOP; 9955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (meta == TM_CPAREN) 9965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = c == /*(*/ ')' ? TO_NONNULL : TO_NONOP; 9975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (meta == TM_UNOP || meta == TM_BINOP) { 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (meta == TM_BINOP && c == REDIR && 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (yylval.iop->flag == IOREAD || yylval.iop->flag == IOWRITE)) { 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = TO_NONNULL; 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru save = wdcopy(yylval.iop->flag == IOREAD ? 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru db_lthan : db_gthan, ATEMP); 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (uqword && (ret = test_isop(meta, ident))) 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru save = yylval.cp; 100503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 100603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* meta == TM_END */ 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = (uqword && !strcmp(yylval.cp, 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru db_close)) ? TO_NONNULL : TO_NONOP; 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ret != TO_NONOP) { 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 1011c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((unsigned int)meta < NELEM(dbtest_tokens)) 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru save = wdcopy(dbtest_tokens[(int)meta], ATEMP); 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (save) 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(*te->pos.av, save); 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (ret); 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querudbtestp_getopnd(Test_env *te, Test_op op MKSH_A_UNUSED, 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool do_eval MKSH_A_UNUSED) 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c = tpeek(ARRAYVAR); 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != LWORD) 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ACCEPT; 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(*te->pos.av, yylval.cp); 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (null); 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querudbtestp_eval(Test_env *te MKSH_A_UNUSED, Test_op op MKSH_A_UNUSED, 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *opnd1 MKSH_A_UNUSED, const char *opnd2 MKSH_A_UNUSED, 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool do_eval MKSH_A_UNUSED) 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querudbtestp_error(Test_env *te, int offset, const char *msg) 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru te->flags |= TEF_ERROR; 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (offset < 0) { 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru REJECT; 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Kludgy to say the least... */ 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru symbol = LWORD; 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yylval.cp = *(XPptrv(*te->pos.av) + XPsize(*te->pos.av) + 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru offset); 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru syntaxerr(msg); 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 105603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 105703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if HAVE_SELECT 105803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 105903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef EOVERFLOW 106003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifdef ERANGE 106103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define EOVERFLOW ERANGE 106203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 106303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define EOVERFLOW EINVAL 106403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 106503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 106603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 106703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrabool 106803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condraparse_usec(const char *s, struct timeval *tv) 106903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 107003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct timeval tt; 107103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int i; 107203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 107303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tv->tv_sec = 0; 107403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* parse integral part */ 107503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (ksh_isdigit(*s)) { 107603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tt.tv_sec = tv->tv_sec * 10 + (*s++ - '0'); 107703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tt.tv_sec / 10 != tv->tv_sec) { 107803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errno = EOVERFLOW; 107903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (true); 108003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 108103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tv->tv_sec = tt.tv_sec; 108203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 108303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 108403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tv->tv_usec = 0; 108503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!*s) 108603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* no decimal fraction */ 108703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (false); 108803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (*s++ != '.') { 108903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* junk after integral part */ 109003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errno = EINVAL; 109103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (true); 109203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 109303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 109403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* parse decimal fraction */ 109503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = 100000; 109603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (ksh_isdigit(*s)) { 109703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tv->tv_usec += i * (*s++ - '0'); 109803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (i == 1) 109903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 110003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i /= 10; 110103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 110203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check for junk after fractional part */ 110303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (ksh_isdigit(*s)) 110403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++s; 110503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*s) { 110603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errno = EINVAL; 110703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (true); 110803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 110903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 111003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of input string reached, no errors */ 111103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (false); 111203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 111303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 111403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 111503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 111603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Helper function called from within lex.c:yylex() to parse 111703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * a COMSUB recursively using the main shell parser and lexer 111803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 111903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrachar * 1120c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaseryyrecursive(int subtype MKSH_A_UNUSED) 112103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 112203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct op *t; 112303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp; 1124c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct yyrecursive_state *ys; 1125c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int stok, etok; 1126c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1127811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (subtype != COMSUB) { 1128c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser stok = '{'; 1129c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser etok = '}'; 1130c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else { 1131c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser stok = '('; 1132c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser etok = ')'; 1133c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1134c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1135c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ys = alloc(sizeof(struct yyrecursive_state), ATEMP); 113603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 113703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* tell the lexer to accept a closing parenthesis as EOD */ 1138c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ys->old_nesting_type = subshell_nesting_type; 1139c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subshell_nesting_type = etok; 114003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 114103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* push reject state, parse recursively, pop reject state */ 1142c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ys->old_reject = reject; 1143c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ys->old_symbol = symbol; 114403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ACCEPT; 1145c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ys->old_herep = herep; 1146c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ys->old_salias = sALIAS; 1147c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sALIAS = 0; 1148c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ys->next = e->yyrecursive_statep; 1149c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser e->yyrecursive_statep = ys; 115003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* we use TPAREN as a helper container here */ 1151c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser t = nested(TPAREN, stok, etok); 1152c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser yyrecursive_pop(false); 115303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 115403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* t->left because nested(TPAREN, ...) hides our goodies there */ 115503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cp = snptreef(NULL, 0, "%T", t->left); 115603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tfree(t, ATEMP); 115703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 115803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (cp); 115903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 1160c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1161c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaservoid 1162c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaseryyrecursive_pop(bool popall) 1163c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 1164c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct yyrecursive_state *ys; 1165c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1166c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser popnext: 1167c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!(ys = e->yyrecursive_statep)) 1168c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 1169c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser e->yyrecursive_statep = ys->next; 1170c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1171c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sALIAS = ys->old_salias; 1172c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser herep = ys->old_herep; 1173c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser reject = ys->old_reject; 1174c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser symbol = ys->old_symbol; 1175c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1176c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subshell_nesting_type = ys->old_nesting_type; 1177c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1178c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afree(ys, ATEMP); 1179c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (popall) 1180c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto popnext; 1181c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 1182