lex.c revision 811a575c0f6a5ef00a921d14c1830ef5ae1bd796
1811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser/* $OpenBSD: lex.c,v 1.47 2013/03/03 19:11:34 guenther Exp $ */ 25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 4c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 5c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten 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/lex.c,v 1.188 2013/08/10 13:44:31 tg Exp $"); 275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * states while lexing word 305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SBASE 0 /* outside any lexical constructs */ 325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SWORD 1 /* implicit quoting for substitute() */ 335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SLETPAREN 2 /* inside (( )), implicit quoting */ 345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SSQUOTE 3 /* inside '' */ 355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SDQUOTE 4 /* inside "" */ 365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SEQUOTE 5 /* inside $'' */ 375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SBRACE 6 /* inside ${} */ 385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SQBRACE 7 /* inside "${}" */ 3903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define SBQUOTE 8 /* inside `` */ 4003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define SASPAREN 9 /* inside $(( )) */ 41c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define SHEREDELIM 10 /* parsing <<,<<-,<<< delimiter */ 42c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define SHEREDQUOTE 11 /* parsing " in <<,<<-,<<< delimiter */ 4303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define SPATTERN 12 /* parsing *(...|...) pattern (*+?@!) */ 4403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define SADELIM 13 /* like SBASE, looking for delimiter */ 45c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define STBRACEKORN 14 /* parsing ${...[#%]...} !FSH */ 46c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#define STBRACEBOURNE 15 /* parsing ${...[#%]...} FSH */ 4703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define SINVALID 255 /* invalid state */ 4803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 4903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastruct sretrace_info { 5003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct sretrace_info *next; 5103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XString xs; 5203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *xp; 5303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra}; 545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 5603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Structure to keep track of the lexing state and the various pieces of info 5703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * needed for each particular state. 5803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 5903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condratypedef struct lex_state { 6003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra union { 6103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* point to the next state block */ 6203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct lex_state *base; 6303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* marks start of state output in output string */ 6403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int start; 6503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* SBQUOTE: true if in double quotes: "`...`" */ 6603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* SEQUOTE: got NUL, ignore rest of string */ 6703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool abool; 6803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* SADELIM information */ 6903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct { 7003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* character to search for */ 715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char delimiter; 7203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* max. number of delimiters */ 735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char num; 7403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } adelim; 7503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } u; 7603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* count open parentheses */ 7703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra short nparen; 7803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* type of this state */ 7903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra uint8_t type; 8003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} Lex_state; 8103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define ls_base u.base 8203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define ls_start u.start 8303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define ls_bool u.abool 8403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define ls_adelim u.adelim 855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutypedef struct { 875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *base; 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *end; 895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} State_info; 905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void readhere(struct ioword *); 9203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void ungetsc(int); 93c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic void ungetsc_i(int); 9403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int getsc_uu(void); 955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void getsc_line(Source *); 965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int getsc_bn(void); 975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int s_get(void); 985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void s_put(int); 995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char *get_brace_var(XString *, char *); 10003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic bool arraysub(char **); 1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void gethere(bool); 102c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic Lex_state *push_state_i(State_info *, Lex_state *); 103c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstatic Lex_state *pop_state_i(State_info *, Lex_state *); 1045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int backslash_skip; 1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int ignore_backslash_newline; 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* optimised getsc_bn() */ 10903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define o_getsc() (*source->str != '\0' && *source->str != '\\' && \ 11003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra !backslash_skip ? *source->str++ : getsc_bn()) 11103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* optimised getsc_uu() */ 11203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define o_getsc_u() ((*source->str != '\0') ? *source->str++ : getsc_uu()) 11303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 11403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* retrace helper */ 11503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define o_getsc_r(carg) { \ 11603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int cev = (carg); \ 11703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct sretrace_info *rp = retrace_info; \ 11803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra \ 11903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (rp) { \ 12003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(rp->xs, rp->xp); \ 12103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *rp->xp++ = cev; \ 12203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rp = rp->next; \ 12303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } \ 12403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra \ 12503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (cev); \ 12603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 1275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 128c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if defined(MKSH_SMALL) && !defined(MKSH_SMALL_BUT_FAST) 1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int getsc(void); 1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 1325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc(void) 1335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra o_getsc_r(o_getsc()); 1355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 13703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic int getsc_r(int); 1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 14003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condragetsc_r(int c) 1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra o_getsc_r(c); 1435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 14503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define getsc() getsc_r(o_getsc()) 1465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define STATE_BSIZE 8 1495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PUSH_STATE(s) do { \ 1515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (++statep == state_info.end) \ 152c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser statep = push_state_i(&state_info, statep); \ 15303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra state = statep->type = (s); \ 15403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} while (/* CONSTCOND */ 0) 1555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define POP_STATE() do { \ 1575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (--statep == state_info.base) \ 158c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser statep = pop_state_i(&state_info, statep); \ 15903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra state = statep->type; \ 16003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} while (/* CONSTCOND */ 0) 16103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 16203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define PUSH_SRETRACE() do { \ 16303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct sretrace_info *ri; \ 16403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra \ 16503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_start = Xsavepos(ws, wp); \ 16603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ri = alloc(sizeof(struct sretrace_info), ATEMP); \ 16703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xinit(ri->xs, ri->xp, 64, ATEMP); \ 16803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ri->next = retrace_info; \ 16903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra retrace_info = ri; \ 17003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} while (/* CONSTCOND */ 0) 17103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 17203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define POP_SRETRACE() do { \ 17303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp = Xrestpos(ws, wp, statep->ls_start); \ 17403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *retrace_info->xp = '\0'; \ 17503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sp = Xstring(retrace_info->xs, retrace_info->xp); \ 17603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dp = (void *)retrace_info; \ 17703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra retrace_info = retrace_info->next; \ 17803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(dp, ATEMP); \ 17903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} while (/* CONSTCOND */ 0) 1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/** 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Lexical analyser 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * tokens are not regular expressions, they are LL(1). 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for example, "${var:-${PWD}}", and "$(size $(whence ksh))". 18603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * hence the state stack. Note "$(...)" are now parsed recursively. 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruyylex(int cf) 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state states[STATE_BSIZE], *statep, *s2, *base; 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru State_info state_info; 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c, c2, state; 19503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t cz; 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString ws; /* expandable output word */ 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *wp; /* output word pointer */ 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *sp, *dp; 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Again: 20103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra states[0].type = SINVALID; 20203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra states[0].ls_base = NULL; 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep = &states[1]; 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state_info.base = states; 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state_info.end = &state_info.base[STATE_BSIZE]; 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(ws, wp, 64, ATEMP); 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 0; 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline = 0; 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (cf & ONEWORD) 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SWORD; 21403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (cf & LETEXPR) { 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* enclose arguments in (double) quotes */ 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SLETPAREN; 21803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 0; 21903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 22003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* normal lexing */ 2215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = (cf & HEREDELIM) ? SHEREDELIM : SBASE; 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) == ' ' || c == '\t') 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '#') { 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) != '\0' && c != '\n') 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 2295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (source->flags & SF_ALIAS) { 23303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* trailing ' ' in alias definition */ 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags &= ~SF_ALIAS; 2355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cf |= ALIAS; 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 23803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Initial state: one of SWORD SLETPAREN SHEREDELIM SBASE */ 23903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->type = state; 2405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check for here string */ 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SHEREDELIM) { 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '<') { 245c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser state = SHEREDELIM; 2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) == ' ' || c == '\t') 2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = '<'; 2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto accept_nonword; 2515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* collect non-special or quoted characters to form word */ 2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (!((c = getsc()) == 0 || 257c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ((state == SBASE || state == SHEREDELIM) && ctype(c, C_LEX1)))) { 258c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (state == SBASE && 259c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subshell_nesting_type == /*{*/ '}' && 260c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c == /*{*/ '}') 261c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* possibly end ${ :;} */ 262c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru accept_nonword: 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (state) { 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SADELIM: 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') 26803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen++; 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ')') 27003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen--; 271c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else if (statep->nparen == 0 && (c == /*{*/ '}' || 272c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c == (int)statep->ls_adelim.delimiter)) { 2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 27503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == /*{*/ '}' || --statep->ls_adelim.num == 0) 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == /*{*/ '}') 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SBASE: 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[' && (cf & (VARASN|ARRAYVAR))) { 28403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* temporary */ 28503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp = EOS; 2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (is_wdvarname(Xstring(ws, wp), false)) { 2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *tmp; 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arraysub(&tmp)) { 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 2915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = tmp; *p; ) { 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = *p++; 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, ATEMP); 2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SREREAD, 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->areap); 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.freeme = tmp; 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Sbase1: /* includes *(...|...) pattern (*+?@!) */ 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '*' || c == '@' || c == '+' || c == '?' || 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '!') { 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = getsc(); 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c2 == '(' /*)*/ ) { 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OPAT; 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SPATTERN); 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Sbase2: /* doesn't include *(...|...) pattern (*+?@!) */ 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getsc_qchar: 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = getsc())) { 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\'': 339811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser open_ssquote_unless_heredoc: 340811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((cf & HEREDOC)) 341811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser goto store_char; 3425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 3435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 3445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SSQUOTE); 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru open_sdquote: 3485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 3495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SDQUOTE); 3505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 351c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '$': 352c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 353c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * processing of dollar sign belongs into 354c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Subst, except for those which can open 355c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * a string: $'…' and $"…" 356c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 357c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subst_dollar_ex: 358c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c = getsc(); 359c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (c) { 360c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '"': 361c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto open_sdquote; 362c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '\'': 363c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto open_sequote; 364c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 365c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto SubstS; 366c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subst; 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Subst: 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & HEREDOC)) 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto heredocquote; 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': case '`': 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru store_qchar: 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru heredocquote: 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\\'; 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 402c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser SubstS: 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') /*)*/ { 4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') /*)*/ { 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = EXPRSUB; 40703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra PUSH_STATE(SASPAREN); 40803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 2; 40903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra PUSH_SRETRACE(); 41003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *retrace_info->xp++ = '('; 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 41303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra subst_command: 414c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c = COMSUB; 415c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subst_command2: 416c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sp = yyrecursive(c); 41703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cz = strlen(sp) + 1; 41803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XcheckN(ws, wp, cz); 419c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *wp++ = c; 42003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra memcpy(wp, sp, cz); 42103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp += cz; 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '{') /*}*/ { 424811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((c = getsc()) == '|') { 425811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* 426811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser * non-subenvironment 427811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser * value substitution 428811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser */ 429811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser c = VALSUB; 430811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser goto subst_command2; 431811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser } else if (ctype(c, C_IFSWS)) { 432c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 433c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * non-subenvironment 434c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * "command" substitution 435c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 436c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c = FUNSUB; 437c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto subst_command2; 438c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 439c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc(c); 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '{'; /*}*/ 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp = get_brace_var(&ws, wp); 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* allow :# and :% (ksh88 compat) */ 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == ':') { 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == ':') { 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '0'; 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ':'; 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 45603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.delimiter = ':'; 45703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.num = 1; 45803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 0; 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ksh_isdigit(c) || 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '('/*)*/ || c == ' ' || 46203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX what else? */ 46303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c == '$') { 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* substring subst. */ 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != ' ') { 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ' '; 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 47203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.delimiter = ':'; 47303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.num = 2; 47403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 0; 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '/') { 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = getsc()) == '/') { 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 48703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.delimiter = '/'; 48803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.num = 1; 48903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 0; 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 49203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 49303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * If this is a trim operation, 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * treat (,|,) specially in STBRACE. 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ctype(c, C_SUBOP2)) { 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 49803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FSH)) 49903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra PUSH_STATE(STBRACEBOURNE); 50003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 50103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra PUSH_STATE(STBRACEKORN); 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 504811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (state == SDQUOTE || 505811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser state == SQBRACE) 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SQBRACE); 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ksh_isalphx(c)) { 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (ksh_isalnux(c)); 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ctype(c, C_VAR1 | C_DIGIT)) { 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '$'; 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '`': 5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru subst_gravis: 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBQUOTE); 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = COMSUB; 54003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 54103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Need to know if we are inside double quotes 5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * since sh/AT&T-ksh translate the \" to " in 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * "`...\"...`". 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This is not done in POSIX mode (section 5455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 3.2.3, Double Quotes: "The backquote shall 5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * retain its special meaning introducing the 5475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * other form of command substitution (see 5485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 3.6.3). The portion of the quoted string 5495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * from the initial backquote and the 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * characters up to the next backquote that 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is not preceded by a backslash (having 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * escape characters removed) defines that 5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command whose output replaces `...` when 5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the word is expanded." 5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Section 3.6.3, Command Substitution: 5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * "Within the backquoted style of command 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * substitution, backslash shall retain its 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * literal meaning, except when followed by 5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * $ ` \."). 5605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 56103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_bool = false; 5625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s2 = statep; 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = state_info.base; 56403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 5655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; s2 != base; s2--) { 56603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (s2->type == SDQUOTE) { 56703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_bool = true; 5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s2 != base) 5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 57303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!(s2 = s2->ls_base)) 5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = s2-- - STATE_BSIZE; 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case QCHAR: 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cf & LQCHAR) { 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = getsc(); 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru store_char: 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SEQUOTE: 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') { 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\\') { 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = unbksl(true, s_get, s_put)) == -1) 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = s_get(); 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c2 == 0) 60103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_bool = true; 60203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!statep->ls_bool) { 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char ts[4]; 6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned int)c2 < 0x100) { 6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c2; 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 60903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cz = utf_wctomb(ts, c2 - 0x100); 61003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ts[cz] = 0; 61103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra for (cz = 0; ts[cz]; ++cz) { 6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 61303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = ts[cz]; 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 61703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (!statep->ls_bool) { 6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSQUOTE: 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') { 6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 626811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((cf & HEREDOC) || state == SQBRACE) 627811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser goto store_char; 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SDQUOTE: 6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '"') { 6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 6395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subst; 6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 64403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* $(( ... )) */ 64503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SASPAREN: 6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') 64703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen++; 6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ')') { 64903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen--; 65003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (statep->nparen == 1) { 65103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of EXPRSUB */ 65203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra POP_SRETRACE(); 65303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra POP_STATE(); 65403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 65503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c2 = getsc()) == /*(*/ ')') { 65603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cz = strlen(sp) - 2; 65703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XcheckN(ws, wp, cz); 65803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra memcpy(wp, sp + 1, cz); 65903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp += cz; 66003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(sp, ATEMP); 66103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = '\0'; 6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 66403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Source *s; 6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 66703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 66803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * mismatched parenthesis - 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * assume we were really 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parsing a $(...) expression 6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 67203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --wp; 67303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s = pushs(SREREAD, 67403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra source->areap); 67503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s->start = s->str = 67603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s->u.freeme = sp; 67703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s->next = source; 67803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra source = s; 67903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto subst_command; 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 68303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* reuse existing state machine */ 68403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto Sbase2; 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SQBRACE: 6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * perform POSIX "quote removal" if the back- 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * slash is "special", i.e. same cases as the 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * {case '\\':} in Subst: plus closing brace; 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * in mksh code "quote removal" on '\c' means 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * write QCHAR+c, otherwise CHAR+\+CHAR+c are 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * emitted (in heredocquote:) 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = getsc()) == '"' || c == '\\' || 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '$' || c == '`' || c == /*{*/'}') 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto store_qchar; 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto heredocquote; 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto common_SQBRACE; 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SBRACE: 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') 705811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser goto open_ssquote_unless_heredoc; 7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '\\') 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto getsc_qchar; 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru common_SQBRACE: 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '"') 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto open_sdquote; 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '$') 712c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto subst_dollar_ex; 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '`') 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto subst_gravis; 7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c != /*{*/ '}') 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto store_char; 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = /*{*/ '}'; 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 72203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Same as SBASE, except (,|,) treated specially */ 72303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case STBRACEKORN: 72403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == '|') 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = SPAT; 72603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (c == '(') { 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OPAT; 72803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* simile for @ */ 72903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = ' '; 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SPATTERN); 73103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else /* FALLTHROUGH */ 73203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case STBRACEBOURNE: 73303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == /*{*/ '}') { 73403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra POP_STATE(); 73503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = CSUBST; 73603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = /*{*/ '}'; 7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Sbase1; 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SBQUOTE: 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '`') { 7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 0; 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\\') { 7465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c = getsc()) { 74703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 0: 74803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* trailing \ is lost */ 74903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 7505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 7515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': case '`': 7525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 7535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 75503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (statep->ls_bool) { 7565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 7575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 7605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 76103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = '\\'; 76203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = c; 7635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 7665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 7675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 76903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ONEWORD */ 77003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SWORD: 7715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subst; 7725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 77303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LETEXPR: (( ... )) */ 77403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SLETPAREN: 77503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == /*(*/ ')') { 77603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (statep->nparen > 0) 77703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra --statep->nparen; 7785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if ((c2 = getsc()) == /*(*/ ')') { 7795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = 0; 7805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Done; 7825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 7845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 78603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 78703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * mismatched parenthesis - 7885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * assume we were really 78903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * parsing a (...) expression 7905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp = EOS; 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sp = Xstring(ws, wp); 79303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dp = wdstrip(sp, WDS_KEEPQ); 7945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SREREAD, source->areap); 7955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = s->u.freeme = dp; 7965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 7975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 7985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ('('/*)*/); 7995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '(') 80103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 80203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * parentheses inside quotes and 80303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * backslashes are lost, but AT&T ksh 80403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * doesn't count them either 8055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 80603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++statep->nparen; 8075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Sbase2; 8085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 809c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* <<, <<-, <<< delimiter */ 81003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SHEREDELIM: 81103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 81203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * here delimiters need a special case since 8135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * $ and `...` are not to be treated specially 8145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 815c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (c) { 816c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '\\': 817c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if ((c = getsc())) { 8185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 8195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 8205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 822c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 823c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '\'': 824811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser goto open_ssquote_unless_heredoc; 825c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '$': 8265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) == '\'') { 827c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser open_sequote: 828c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *wp++ = OQUOTE; 829c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ignore_backslash_newline++; 8305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SEQUOTE); 83103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_bool = false; 832c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 833c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else if (c2 == '"') { 834c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 835c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '"': 836c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser state = statep->type = SHEREDQUOTE; 837c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser PUSH_SRETRACE(); 838c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 839c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 841c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 842c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 8435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 848c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* " in <<, <<-, <<< delimiter */ 84903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SHEREDQUOTE: 850c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (c != '"') 851c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto Subst; 852c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser POP_SRETRACE(); 853c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser dp = strnul(sp) - 1; 854c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* remove the trailing double quote */ 855c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *dp = '\0'; 856c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* store the quoted string */ 857c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *wp++ = OQUOTE; 858c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XcheckN(ws, wp, (dp - sp)); 859c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser dp = sp; 860c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((c = *dp++)) { 8615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 862c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch ((c = *dp++)) { 86303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '\\': 86403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '"': 86503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '$': 86603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '`': 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 86903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = CHAR; 87003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = '\\'; 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 877c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afree(sp, ATEMP); 878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *wp++ = CQUOTE; 879c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser state = statep->type = SHEREDELIM; 8805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 88203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* in *(...|...) pattern (*+?@!) */ 88303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SPATTERN: 88403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == /*(*/ ')') { 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CPAT; 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 8875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '|') { 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = SPAT; 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '(') { 8905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OPAT; 89103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* simile for @ */ 89203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = ' '; 8935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SPATTERN); 8945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 8955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Sbase1; 8965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Done: 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (statep != &states[1]) 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX figure out what is missing */ 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyerror("no closing quote\n"); 9045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This done to avoid tests for SHEREDELIM wherever SBASE tested */ 906c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (state == SHEREDELIM) 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SBASE; 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = Xstring(ws, wp); 910811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (state == SBASE && ( 911811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#ifndef MKSH_LEGACY_MODE 912811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser (c == '&' && !Flag(FSH) && !Flag(FPOSIX)) || 913811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 914811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser c == '<' || c == '>')) { 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct ioword *iop = alloc(sizeof(struct ioword), ATEMP); 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Xlength(ws, wp) == 0) 9185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->unit = c == '<' ? 0 : 1; 9195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else for (iop->unit = 0, c2 = 0; c2 < Xlength(ws, wp); c2 += 2) { 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (dp[c2] != CHAR) 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isdigit(dp[c2 + 1])) 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->unit = (iop->unit * 10) + dp[c2 + 1] - '0'; 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->unit >= FDBASE) 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '&') { 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) != '>') { 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 9335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = c2; 9365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag = IOBASH; 9375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag = 0; 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = getsc(); 9415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* <<, >>, <> are ok, >< is not */ 9425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == c2 || (c == '<' && c2 == '>')) { 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= c == c2 ? 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '>' ? IOCAT : IOHERE) : IORDWR; 9455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->flag == IOHERE) { 94603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c2 = getsc()) == '-') { 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IOSKIP; 94803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c2 = getsc(); 94903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (c2 == '<') 95003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra iop->flag |= IOHERESTR; 95103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(c2); 95203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c2 == '\n') 95303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra iop->flag |= IONDELIM; 9545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c2 == '&') 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IODUP | (c == '<' ? IORDUP : 0); 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= c == '>' ? IOWRITE : IOREAD; 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '>' && c2 == '|') 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IOCLOB; 9615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 9635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->name = NULL; 9665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->delim = NULL; 9675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->heredoc = NULL; 96803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free word */ 96903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xfree(ws, wp); 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yylval.iop = iop; 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (REDIR); 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru no_iop: 97303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(iop, ATEMP); 9745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp == dp && state == SBASE) { 97703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free word */ 97803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xfree(ws, wp); 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* no word, process LEX1 character */ 9805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == '|') || (c == '&') || (c == ';') || (c == '('/*)*/)) { 9815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) == c) 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = (c == ';') ? BREAK : 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '|') ? LOGOR : 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '&') ? LOGAND : 9855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* c == '(' ) */ MDPAREN; 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '|' && c2 == '&') 9875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = COPROC; 98803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (c == ';' && c2 == '|') 98903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = BRKEV; 99003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (c == ';' && c2 == '&') 99103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = BRKFT; 9925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 99403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_SMALL 99503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == BREAK) { 99603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c2 = getsc()) == '&') 99703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = BRKEV; 99803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 99903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(c2); 100003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 100103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\n') { 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gethere(false); 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cf & CONTIN) 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Again; 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\0') 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* need here strings at EOF */ 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gethere(true); 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 101203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* terminate word */ 101303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = EOS; 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yylval.cp = Xclose(ws, wp); 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SWORD || state == SLETPAREN 101603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* XXX ONEWORD? */) 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unget terminator */ 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * note: the alias-vs-function code below depends on several 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * interna: starting from here, source->str is not modified; 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the way getsc() and ungetsc() operate; etc. 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* copy word to unprefixed string ident */ 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sp = yylval.cp; 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = ident; 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & HEREDELIM) && (sp[1] == '<')) 1032c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((dp - ident) < IDENT) { 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = *sp++) == CHAR) 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *dp++ = *sp++; 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if ((c != OQUOTE) && (c != CQUOTE)) 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 1039c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((dp - ident) < IDENT && (c = *sp++) == CHAR) 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *dp++ = *sp++; 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Make sure the ident array stays '\0' padded */ 1042c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser memset(dp, 0, (ident + IDENT) - dp + 1); 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != EOS) 104403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* word is not unquoted */ 104503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *ident = '\0'; 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 104703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*ident != '\0' && (cf & (KEYWORD | ALIAS))) { 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *p; 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h = hash(ident); 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) && 105203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (!(cf & ESACONLY) || p->val.i == ESAC || 105303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra p->val.i == /*{*/ '}')) { 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(yylval.cp, ATEMP); 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p->val.i); 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & ALIAS) && (p = ktsearch(&aliases, ident, h)) && 10585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (p->flag & ISSET)) { 10595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this still points to the same character as the 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ungetsc'd terminator from above 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp = source->str; 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prefer POSIX but not Korn functions over aliases */ 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp == ' ' || *cp == '\t') 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is like getsc() without skipping 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * over Source boundaries (including not 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parsing ungetsc'd characters that got 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pushed into an SREREAD) which is what 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * we want here anyway: find out whether 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the alias name is followed by a POSIX 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * function definition (only the opening 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parenthesis is checked though) 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++cp; 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prefer functions over aliases */ 107903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (cp[0] != '(' || cp[1] != ')') { 10805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s = source; 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (s && (s->flags & SF_HASALIAS)) 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->u.tblp == p) 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 10855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 10865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = s->next; 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* push alias expansion */ 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SALIAS, source->areap); 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = p->val.s; 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.tblp = p; 10915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_HASALIAS; 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->type == SEOF) { 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prevent infinite recursion at EOS */ 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->u.tblp = p; 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= SF_HASALIAS; 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(yylval.cp, ATEMP); 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Again; 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugethere(bool iseof) 11105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct ioword **p; 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = heres; p < herep; p++) 111403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (iseof && !((*p)->flag & IOHERESTR)) 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* only here strings at EOF */ 11165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru readhere(*p); 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru herep = heres; 11205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 11235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * read "<<word" text into temp file 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querureadhere(struct ioword *iop) 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 113003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *eof, *eofp; 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString xs; 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int xpos; 11345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 113503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (iop->flag & IOHERESTR) { 11365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* process the here string */ 113703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra iop->heredoc = xp = evalstr(iop->delim, DOBLANK); 113803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xpos = strlen(xp) - 1; 113903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra memmove(xp, xp + 1, xpos); 114003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp[xpos] = '\n'; 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 114403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra eof = iop->flag & IONDELIM ? "<<" : evalstr(iop->delim, 0); 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(iop->flag & IOEVAL)) 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 11485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(xs, xp, 256, ATEMP); 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 115103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_read_line: 115203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* beginning of line */ 115303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra eofp = eof; 115403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xpos = Xsavepos(xs, xp); 115503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (iop->flag & IOSKIP) { 115603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip over leading tabs */ 115703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((c = getsc()) == '\t') 115803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* nothing */; 115903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_parse_char; 116003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 116103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_read_char: 116203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = getsc(); 116303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_parse_char: 116403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* compare with here document marker */ 116503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!*eofp) { 116603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of here document marker, what to do? */ 116703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (c) { 116803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case /*(*/ ')': 1169c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!subshell_nesting_type) 117003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*- 117103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * not allowed outside $(...) or (...) 117203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * => mismatch 117303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 11745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 117503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* allow $(...) or (...) to close here */ 117603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(/*(*/ ')'); 117703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* FALLTHROUGH */ 117803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 0: 117903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 118003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Allow EOF here to commands without trailing 118103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * newlines (mksh -c '...') will work as well. 118203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 118303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '\n': 118403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Newline terminates here document marker */ 118503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_found_terminator; 11865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 118703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (c == *eofp++) 118803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* store; then read and compare next character */ 118903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_store_and_loop; 119003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* nope, mismatch; read until end of line */ 119103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (c != '\n') { 119203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!c) 119303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* oops, reached EOF */ 119403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("%s '%s' unclosed\n", "here document", eof); 119503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* store character */ 11965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(xs, xp); 11975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, c); 119803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* read next character */ 119903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = getsc(); 12005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 120103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* we read a newline as last character */ 120203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_store_and_loop: 120303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* store character */ 120403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 120503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, c); 120603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == '\n') 120703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_read_line; 120803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_read_char; 120903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 121003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_found_terminator: 121103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* jump back to saved beginning of line */ 121203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xrestpos(xs, xp, xpos); 121303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* terminate, close and store */ 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\0'); 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->heredoc = Xclose(xs, xp); 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(iop->flag & IOEVAL)) 12185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 12195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruyyerror(const char *fmt, ...) 12235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* pop aliases and re-reads */ 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (source->type == SALIAS || source->type == SREREAD) 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = source->next; 122903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* zap pending input */ 123003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra source->str = null; 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru error_prefix(true); 12335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 12345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_vfprintf(shl_out, fmt, va); 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 12365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorfz(); 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * input for yylex with alias expansion 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste QueruSource * 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupushs(int type, Area *areap) 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = alloc(sizeof(Source), areap); 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memset(s, 0, sizeof(Source)); 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = type; 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = null; 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->areap = areap; 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (type == SFILE || type == SSTDIN) 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XinitN(s->xs, 256, s->areap); 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 125903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condragetsc_uu(void) 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s = source; 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = *s->str++) == 0) { 126503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* return 0 for EOF by default */ 126603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s->str = NULL; 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (s->type) { 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SEOF: 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = null; 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 12715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSTDIN: 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SFILE: 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getsc_line(s); 12755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWSTR: 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSTRING: 1281c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case SSTRINGCMDLINE: 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWORDS: 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = *s->u.strv++; 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SWORDSEP; 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWORDSEP: 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s->u.strv == NULL) { 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = "\n"; 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SEOF; 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = " "; 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SWORDS; 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SALIAS: 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->flags & SF_ALIASEND) { 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* pass on an unused SF_ALIAS flag */ 13025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s->next; 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= s->flags & SF_ALIAS; 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = source; 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*s->u.tblp->val.s && 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c = strnul(s->u.tblp->val.s)[-1], ksh_isspace(c))) { 130703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* pop source stack */ 130803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra source = s = s->next; 130903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 131003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Note that this alias ended with a 131103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * space, enabling alias expansion on 131203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * the following word. 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_ALIAS; 13155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 131603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 131703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * At this point, we need to keep the current 13185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * alias in the source list so recursive 131903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * aliases can be detected and we also need to 132003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * return the next character. Do this by 132103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * temporarily popping the alias to get the 132203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * next character and then put it back in the 132303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * source list with the SF_ALIASEND flag set. 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 132503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* pop source stack */ 132603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra source = s->next; 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= s->flags & SF_ALIAS; 132803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = getsc_uu(); 13295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_ALIASEND; 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->ugbuf[0] = c; s->ugbuf[1] = '\0'; 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = s->ugbuf; 13335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 13365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = source; 133703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* avoid reading EOF twice */ 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = NULL; 13395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SREREAD: 134503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (s->start != s->ugbuf) 134603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* yuck */ 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(s->u.freeme, ATEMP); 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s = s->next; 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->str == NULL) { 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SEOF; 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = null; 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ('\0'); 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->flags & SF_ECHO) { 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(s->str, shl_out); 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 13655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc_line(Source *s) 13665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp = Xstring(s->xs, xp), *cp; 13685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool interactive = Flag(FTALKING) && s->type == SSTDIN; 1369c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool have_tty = tobool(interactive && (s->flags & SF_TTY)); 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Done here to ensure nothing odd happens when a timeout occurs */ 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(s->xs, xp, LINE); 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *xp = '\0'; 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = xp; 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ksh_tmout) { 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_READING; 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alarm(ksh_tmout); 13795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 13815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru change_winsz(); 1382c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 13835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ( 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !MKSH_S_NOVI 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FVI) || 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 13875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FEMACS) || Flag(FGMACS))) { 13885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nread; 13895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1390811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser nread = x_read(xp); 139103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (nread < 0) 139203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* read error */ 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nread = 0; 13945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp[nread] = '\0'; 13955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += nread; 1396c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else 1397c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1398c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser { 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pprompt(prompt, 0); 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->line++; 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 140403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p = shf_getse(xp, Xnleft(s->xs, xp), s->u.shf); 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!p && shf_error(s->u.shf) && 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_errno(s->u.shf) == EINTR) { 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_clearerr(s->u.shf); 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (trap) 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru runtraps(0); 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 14135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!p || (xp = p, xp[-1] == '\n')) 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* double buffer size */ 141703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* move past NUL so doubling works... */ 141803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp++; 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(s->xs, xp, Xlength(s->xs, xp)); 142003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ...and move back again */ 142103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp--; 14225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 142303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 142403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * flush any unwanted input so other programs/builtins 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * can read it. Not very optimal, but less error prone 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * than flushing else where, dealing with redirections, 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * etc. 142803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * TODO: reduce size of shf buffer (~128?) if SSTDIN 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->type == SSTDIN) 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(s->u.shf); 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 143303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 143403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * XXX: temporary kludge to restore source after a 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * trap may have been executed. 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ksh_tmout) { 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_EXECUTING; 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alarm(0); 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = Xstring(s->xs, xp); 14435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = cp; 14445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp)); 14455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Note: if input is all nulls, this is not eof */ 14465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Xlength(s->xs, xp) == 0) { 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* EOF */ 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->type == SFILE) 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fdclose(s->u.shf); 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = NULL; 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (interactive && *s->str && 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (cur_prompt != PS1 || !ctype(*s->str, C_IFS | C_IFSWS))) { 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsave(&s->line, s->str, true, true); 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (interactive && cur_prompt == PS1) { 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = Xstring(s->xs, xp); 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp && ctype(*cp, C_IFSWS)) 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++cp; 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*cp) 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsync(); 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set_prompt(PS2, NULL); 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruset_prompt(int to, Source *s) 14695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cur_prompt = to; 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (to) { 147303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* command */ 147403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case PS1: 147503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 147603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Substitute ! and !! here, before substitutions are done 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * so ! in expanded variables are not expanded. 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * NOTE: this is not what AT&T ksh does (it does it after 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * substitutions, POSIX doesn't say which is to be done. 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 14825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct shf *shf; 14835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char * volatile ps1; 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Area *saved_atemp; 14855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ps1 = str_val(global("PS1")); 14875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf = shf_sopen(NULL, strlen(ps1) * 2, 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SHF_WR | SHF_DYNAMIC, NULL); 14895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*ps1) 14905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ps1 != '!' || *++ps1 == '!') 14915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putchar(*ps1++, shf); 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%d", 14945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s ? s->line + 1 : 0); 14955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ps1 = shf_sclose(shf); 14965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru saved_atemp = ATEMP; 14975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru newenv(E_ERRH); 1498c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (kshsetjmp(e->jbuf)) { 14995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prompt = safe_prompt; 150003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 150103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Don't print an error - assume it has already 15025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * been printed. Reason is we may have forked 15035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to run a command and the child may be 15045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * unwinding its stack through this code as it 15055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * exits. 15065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 15085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp = substitute(ps1, 0); 15095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(prompt, cp, saved_atemp); 15105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(NULL); 15125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 151403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* command continuation */ 151503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case PS2: 15165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prompt = str_val(global("PS2")); 15175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1521811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserint 1522811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserpprompt(const char *cp, int ntruncate) 15235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1524c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser int columns = 0, lines = 0; 1525c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool indelimit = false; 15265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char delimiter = 0; 15275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 152803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 152903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Undocumented AT&T ksh feature: 153003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * If the second char in the prompt string is \r then the first 153103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * char is taken to be a non-printing delimiter and any chars 153203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * between two instances of the delimiter are not considered to 153303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * be part of the prompt length 15345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp && cp[1] == '\r') { 15365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru delimiter = *cp; 15375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp += 2; 15385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *cp; cp++) { 15405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (indelimit && *cp != delimiter) 15415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 15425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*cp == '\n' || *cp == '\r') { 15435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lines += columns / x_cols + ((*cp == '\n') ? 1 : 0); 15445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns = 0; 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == '\t') { 15465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns = (columns | 7) + 1; 15475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == '\b') { 15485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (columns > 0) 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns--; 15505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == delimiter) 15515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru indelimit = !indelimit; 15525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (UTFMODE && ((unsigned char)*cp > 0x7F)) { 15535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp2; 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns += utf_widthadj(cp, &cp2); 1555811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (indelimit || 1556811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser (ntruncate < (x_cols * lines + columns))) 15575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_write(cp, cp2 - cp, shl_out); 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = cp2 - /* loop increment */ 1; 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns++; 1562811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((*cp != delimiter) && 15635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (indelimit || (ntruncate < (x_cols * lines + columns)))) 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc(*cp, shl_out); 15655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1566811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser shf_flush(shl_out); 15675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (x_cols * lines + columns); 15685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 157003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 157103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Read the variable part of a ${...} expression (i.e. up to but not 157203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * including the :[-+?=#%] or close-brace). 15735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char * 15755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruget_brace_var(XString *wsp, char *wp) 15765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 157703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char c; 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru enum parse_state { 15795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PS_INITIAL, PS_SAW_HASH, PS_IDENT, 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PS_NUMBER, PS_VAR1 158103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } state = PS_INITIAL; 15825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 158303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 15845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 15855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* State machine to figure out where the variable part ends. */ 15865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (state) { 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_INITIAL: 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '#' || c == '!' || c == '%') { 15895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_SAW_HASH; 15905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 15935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_SAW_HASH: 15945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isalphx(c)) 15955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_IDENT; 15965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (ksh_isdigit(c)) 15975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_NUMBER; 159803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (c == '#') { 159903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (state == PS_SAW_HASH) { 160003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char c2; 160103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 160203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c2 = getsc(); 160303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(c2); 1604c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (c2 != /*{*/ '}') { 160503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(c); 160603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto out; 160703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 160803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 160903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra state = PS_VAR1; 161003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (ctype(c, C_VAR1)) 16115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_VAR1; 16125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 16135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_IDENT: 16165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isalnux(c)) { 16175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') { 16185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *tmp, *p; 16195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!arraysub(&tmp)) 16215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyerror("missing ]\n"); 16225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = tmp; *p; ) { 16245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(*wsp, wp); 16255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = *p++; 16265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, ATEMP); 162803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* the ] */ 162903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = getsc(); 16305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_NUMBER: 16355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isdigit(c)) 16365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_VAR1: 16395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(*wsp, wp); 16425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru out: 164503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of variable part */ 164603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = '\0'; 16475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 16485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (wp); 16495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 16525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Save an array subscript - returns true if matching bracket found, false 16535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if eof or newline was found. 16545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (Returned string double null terminated) 16555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 165603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic bool 16575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarraysub(char **strp) 16585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 16595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString ws; 166003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *wp, c; 166103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* we are just past the initial [ */ 1662c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unsigned int depth = 1; 16635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(ws, wp, 32, ATEMP); 16655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 16675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 16685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 16695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') 16715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth++; 16725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ']') 16735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth--; 16745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (depth > 0 && c && c != '\n'); 16755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 16775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *strp = Xclose(ws, wp); 16785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 167903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (tobool(depth == 0)); 16805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Unget a char: handles case when we are already at the start of the buffer */ 168303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void 16845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruungetsc(int c) 16855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 168603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct sretrace_info *rp = retrace_info; 168703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 16885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (backslash_skip) 16895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip--; 169003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Don't unget EOF... */ 16915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->str == null && c == '\0') 169203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 169303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (rp) { 169403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Xlength(rp->xs, rp->xp)) 169503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rp->xp--; 169603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rp = rp->next; 169703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 1698c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c); 169903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 170003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void 1701c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserungetsc_i(int c) 170203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 17035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->str > source->start) 17045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->str--; 17055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 17065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 17075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SREREAD, source->areap); 17095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->ugbuf[0] = c; s->ugbuf[1] = '\0'; 17105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = s->ugbuf; 17115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 17125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 17135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called to get a char that isn't a \newline sequence. */ 17185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 17195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc_bn(void) 17205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c, c2; 17225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ignore_backslash_newline) 172403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (o_getsc_u()); 17255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (backslash_skip == 1) { 17275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 2; 172803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (o_getsc_u()); 17295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 0; 17325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 173303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 173403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = o_getsc_u(); 17355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 173603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c2 = o_getsc_u()) == '\n') 17375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignore the \newline; get the next char... */ 17385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 1739c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c2); 17405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 1; 17415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 17435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 174603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid 174703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrayyskiputf8bom(void) 174803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 174903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int c; 175003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 175103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((unsigned char)(c = o_getsc_u()) != 0xEF) { 1752c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c); 175303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 175403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 175503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((unsigned char)(c = o_getsc_u()) != 0xBB) { 1756c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c); 1757c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(0xEF); 175803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 175903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 176003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((unsigned char)(c = o_getsc_u()) != 0xBF) { 1761c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c); 1762c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(0xBB); 1763c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(0xEF); 176403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 176503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 176603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra UTFMODE |= 8; 176703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 176803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 17695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Lex_state * 1770c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserpush_state_i(State_info *si, Lex_state *old_end) 17715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 177203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Lex_state *news = alloc2(STATE_BSIZE, sizeof(Lex_state), ATEMP); 17735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 177403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra news[0].ls_base = old_end; 17755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru si->base = &news[0]; 17765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru si->end = &news[STATE_BSIZE]; 17775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (&news[1]); 17785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Lex_state * 1781c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserpop_state_i(State_info *si, Lex_state *old_end) 17825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *old_base = si->base; 17845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 178503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra si->base = old_end->ls_base - STATE_BSIZE; 178603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra si->end = old_end->ls_base; 17875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(old_base, ATEMP); 17895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (si->base + STATE_BSIZE - 1); 17915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 17945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_get(void) 17955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (getsc()); 17975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 18005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_put(int c) 18015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 18025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 18035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1804