1427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes/* $OpenBSD: lex.c,v 1.49 2013/12/17 16:37:06 deraadt Exp $ */ 25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 4c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 5427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes * 2011, 2012, 2013, 2014 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 26427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.193 2014/06/29 11:28:28 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 162427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes#define PUSH_SRETRACE(s) do { \ 16303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct sretrace_info *ri; \ 16403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra \ 165427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes PUSH_STATE(s); \ 16603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_start = Xsavepos(ws, wp); \ 16703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ri = alloc(sizeof(struct sretrace_info), ATEMP); \ 16803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xinit(ri->xs, ri->xp, 64, ATEMP); \ 16903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ri->next = retrace_info; \ 17003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra retrace_info = ri; \ 17103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} while (/* CONSTCOND */ 0) 17203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 17303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define POP_SRETRACE() do { \ 17403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp = Xrestpos(ws, wp, statep->ls_start); \ 17503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *retrace_info->xp = '\0'; \ 17603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra sp = Xstring(retrace_info->xs, retrace_info->xp); \ 17703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra dp = (void *)retrace_info; \ 17803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra retrace_info = retrace_info->next; \ 17903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(dp, ATEMP); \ 180427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes POP_STATE(); \ 18103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} while (/* CONSTCOND */ 0) 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/** 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Lexical analyser 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * tokens are not regular expressions, they are LL(1). 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for example, "${var:-${PWD}}", and "$(size $(whence ksh))". 18803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * hence the state stack. Note "$(...)" are now parsed recursively. 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruyylex(int cf) 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state states[STATE_BSIZE], *statep, *s2, *base; 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru State_info state_info; 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c, c2, state; 19703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t cz; 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString ws; /* expandable output word */ 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *wp; /* output word pointer */ 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *sp, *dp; 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Again: 20303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra states[0].type = SINVALID; 20403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra states[0].ls_base = NULL; 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep = &states[1]; 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state_info.base = states; 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state_info.end = &state_info.base[STATE_BSIZE]; 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(ws, wp, 64, ATEMP); 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 0; 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline = 0; 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 21403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (cf & ONEWORD) 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SWORD; 21603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (cf & LETEXPR) { 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* enclose arguments in (double) quotes */ 2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SLETPAREN; 22003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 0; 22103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 22203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* normal lexing */ 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = (cf & HEREDELIM) ? SHEREDELIM : SBASE; 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) == ' ' || c == '\t') 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '#') { 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) != '\0' && c != '\n') 2295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 23403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (source->flags & SF_ALIAS) { 23503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* trailing ' ' in alias definition */ 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags &= ~SF_ALIAS; 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cf |= ALIAS; 2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 24003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Initial state: one of SWORD SLETPAREN SHEREDELIM SBASE */ 24103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->type = state; 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check for here string */ 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SHEREDELIM) { 2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '<') { 247c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser state = SHEREDELIM; 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) == ' ' || c == '\t') 2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = '<'; 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto accept_nonword; 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* collect non-special or quoted characters to form word */ 2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (!((c = getsc()) == 0 || 259c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ((state == SBASE || state == SHEREDELIM) && ctype(c, C_LEX1)))) { 260c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (state == SBASE && 261c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subshell_nesting_type == /*{*/ '}' && 262c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c == /*{*/ '}') 263c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* possibly end ${ :;} */ 264c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru accept_nonword: 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (state) { 2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SADELIM: 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') 27003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen++; 2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ')') 27203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen--; 273c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser else if (statep->nparen == 0 && (c == /*{*/ '}' || 274c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c == (int)statep->ls_adelim.delimiter)) { 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 27703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == /*{*/ '}' || --statep->ls_adelim.num == 0) 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == /*{*/ '}') 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SBASE: 2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[' && (cf & (VARASN|ARRAYVAR))) { 28603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* temporary */ 28703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp = EOS; 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (is_wdvarname(Xstring(ws, wp), false)) { 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *tmp; 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arraysub(&tmp)) { 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = tmp; *p; ) { 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 2975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = *p++; 2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, ATEMP); 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SREREAD, 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->areap); 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.freeme = tmp; 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Sbase1: /* includes *(...|...) pattern (*+?@!) */ 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '*' || c == '@' || c == '+' || c == '?' || 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '!') { 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = getsc(); 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c2 == '(' /*)*/ ) { 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OPAT; 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SPATTERN); 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Sbase2: /* doesn't include *(...|...) pattern (*+?@!) */ 3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getsc_qchar: 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = getsc())) { 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\'': 341811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser open_ssquote_unless_heredoc: 342811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((cf & HEREDOC)) 343811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser goto store_char; 3445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SSQUOTE); 3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 3495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru open_sdquote: 3505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 3515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SDQUOTE); 3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 353c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '$': 354c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 355c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * processing of dollar sign belongs into 356c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Subst, except for those which can open 357c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * a string: $'…' and $"…" 358c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 359c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subst_dollar_ex: 360c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c = getsc(); 361c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (c) { 362c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '"': 363c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto open_sdquote; 364c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case '\'': 365c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto open_sequote; 366c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 367c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto SubstS; 368c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subst; 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Subst: 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & HEREDOC)) 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto heredocquote; 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': case '`': 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru store_qchar: 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru heredocquote: 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\\'; 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 404c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser SubstS: 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') /*)*/ { 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') /*)*/ { 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = EXPRSUB; 409427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes PUSH_SRETRACE(SASPAREN); 41003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 2; 41103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *retrace_info->xp++ = '('; 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 41403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra subst_command: 415c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c = COMSUB; 416c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser subst_command2: 417c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sp = yyrecursive(c); 41803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cz = strlen(sp) + 1; 41903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra XcheckN(ws, wp, cz); 420c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *wp++ = c; 42103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra memcpy(wp, sp, cz); 42203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra wp += cz; 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '{') /*}*/ { 425811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((c = getsc()) == '|') { 426811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* 427811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser * non-subenvironment 428811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser * value substitution 429811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser */ 430811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser c = VALSUB; 431811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser goto subst_command2; 432811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser } else if (ctype(c, C_IFSWS)) { 433c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 434c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * non-subenvironment 435c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * "command" substitution 436c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 437c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser c = FUNSUB; 438c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto subst_command2; 439c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 440c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc(c); 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '{'; /*}*/ 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp = get_brace_var(&ws, wp); 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* allow :# and :% (ksh88 compat) */ 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == ':') { 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == ':') { 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '0'; 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ':'; 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 45703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.delimiter = ':'; 45803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.num = 1; 45903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 0; 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ksh_isdigit(c) || 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '('/*)*/ || c == ' ' || 46303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*XXX what else? */ 46403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c == '$') { 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* substring subst. */ 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != ' ') { 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ' '; 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 47303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.delimiter = ':'; 47403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.num = 2; 47503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 0; 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '/') { 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = getsc()) == '/') { 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 48803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.delimiter = '/'; 48903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_adelim.num = 1; 49003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen = 0; 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 49303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 49403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * If this is a trim operation, 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * treat (,|,) specially in STBRACE. 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ctype(c, C_SUBOP2)) { 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 49903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Flag(FSH)) 50003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra PUSH_STATE(STBRACEBOURNE); 50103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 50203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra PUSH_STATE(STBRACEKORN); 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 505811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (state == SDQUOTE || 506811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser state == SQBRACE) 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SQBRACE); 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ksh_isalphx(c)) { 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (ksh_isalnux(c)); 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ctype(c, C_VAR1 | C_DIGIT)) { 5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '$'; 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '`': 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru subst_gravis: 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBQUOTE); 5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = COMSUB; 54103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 54203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Need to know if we are inside double quotes 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * since sh/AT&T-ksh translate the \" to " in 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * "`...\"...`". 5455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This is not done in POSIX mode (section 5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 3.2.3, Double Quotes: "The backquote shall 5475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * retain its special meaning introducing the 5485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * other form of command substitution (see 5495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 3.6.3). The portion of the quoted string 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * from the initial backquote and the 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * characters up to the next backquote that 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is not preceded by a backslash (having 5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * escape characters removed) defines that 5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command whose output replaces `...` when 5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the word is expanded." 5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Section 3.6.3, Command Substitution: 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * "Within the backquoted style of command 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * substitution, backslash shall retain its 5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * literal meaning, except when followed by 5605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * $ ` \."). 5615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 56203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_bool = false; 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s2 = statep; 5645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = state_info.base; 56503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 5665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; s2 != base; s2--) { 56703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (s2->type == SDQUOTE) { 56803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_bool = true; 5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s2 != base) 5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 57403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!(s2 = s2->ls_base)) 5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = s2-- - STATE_BSIZE; 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case QCHAR: 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cf & LQCHAR) { 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = getsc(); 5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru store_char: 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SEQUOTE: 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') { 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\\') { 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = unbksl(true, s_get, s_put)) == -1) 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = s_get(); 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c2 == 0) 60203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->ls_bool = true; 60303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!statep->ls_bool) { 6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char ts[4]; 6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned int)c2 < 0x100) { 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c2; 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 61003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra cz = utf_wctomb(ts, c2 - 0x100); 61103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ts[cz] = 0; 61203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra for (cz = 0; ts[cz]; ++cz) { 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 61403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = ts[cz]; 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 61803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (!statep->ls_bool) { 6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSQUOTE: 6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') { 6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 627811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((cf & HEREDOC) || state == SQBRACE) 628811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser goto store_char; 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SDQUOTE: 6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '"') { 6395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subst; 6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 64503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* $(( ... )) */ 64603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SASPAREN: 6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') 64803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen++; 6495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ')') { 65003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra statep->nparen--; 65103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (statep->nparen == 1) { 65203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of EXPRSUB */ 65303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra POP_SRETRACE(); 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 '"': 836427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes PUSH_SRETRACE(SHEREDQUOTE); 837c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 838c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 8395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 840c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 841c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser default: 8425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 8435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 847c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* " in <<, <<-, <<< delimiter */ 84803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SHEREDQUOTE: 849c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (c != '"') 850c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto Subst; 851c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser POP_SRETRACE(); 852c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser dp = strnul(sp) - 1; 853c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* remove the trailing double quote */ 854c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *dp = '\0'; 855c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* store the quoted string */ 856c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *wp++ = OQUOTE; 857c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser XcheckN(ws, wp, (dp - sp)); 858c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser dp = sp; 859c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((c = *dp++)) { 8605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 861c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch ((c = *dp++)) { 86203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '\\': 86303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '"': 86403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '$': 86503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '`': 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 86803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = CHAR; 86903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = '\\'; 8705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 8745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 876c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser afree(sp, ATEMP); 877c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser *wp++ = CQUOTE; 878c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser state = statep->type = SHEREDELIM; 8795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 88103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* in *(...|...) pattern (*+?@!) */ 88203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case SPATTERN: 88303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == /*(*/ ')') { 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CPAT; 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '|') { 8875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = SPAT; 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '(') { 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OPAT; 89003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* simile for @ */ 89103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = ' '; 8925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SPATTERN); 8935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 8945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Sbase1; 8955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Done: 8995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (statep != &states[1]) 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX figure out what is missing */ 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyerror("no closing quote\n"); 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This done to avoid tests for SHEREDELIM wherever SBASE tested */ 905c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (state == SHEREDELIM) 9065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SBASE; 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = Xstring(ws, wp); 909811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (state == SBASE && ( 910811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#ifndef MKSH_LEGACY_MODE 911811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser (c == '&' && !Flag(FSH) && !Flag(FPOSIX)) || 912811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser#endif 913811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser c == '<' || c == '>')) { 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct ioword *iop = alloc(sizeof(struct ioword), ATEMP); 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Xlength(ws, wp) == 0) 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->unit = c == '<' ? 0 : 1; 9185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else for (iop->unit = 0, c2 = 0; c2 < Xlength(ws, wp); c2 += 2) { 9195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (dp[c2] != CHAR) 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isdigit(dp[c2 + 1])) 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->unit = (iop->unit * 10) + dp[c2 + 1] - '0'; 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->unit >= FDBASE) 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '&') { 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) != '>') { 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = c2; 9355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag = IOBASH; 9365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 9375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag = 0; 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = getsc(); 9405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* <<, >>, <> are ok, >< is not */ 9415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == c2 || (c == '<' && c2 == '>')) { 9425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= c == c2 ? 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '>' ? IOCAT : IOHERE) : IORDWR; 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->flag == IOHERE) { 94503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c2 = getsc()) == '-') { 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IOSKIP; 94703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c2 = getsc(); 94803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (c2 == '<') 94903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra iop->flag |= IOHERESTR; 95003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(c2); 95103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c2 == '\n') 95203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra iop->flag |= IONDELIM; 9535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c2 == '&') 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IODUP | (c == '<' ? IORDUP : 0); 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= c == '>' ? IOWRITE : IOREAD; 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '>' && c2 == '|') 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IOCLOB; 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 9625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->name = NULL; 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->delim = NULL; 9665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->heredoc = NULL; 96703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free word */ 96803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xfree(ws, wp); 9695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yylval.iop = iop; 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (REDIR); 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru no_iop: 97203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(iop, ATEMP); 9735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp == dp && state == SBASE) { 97603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free word */ 97703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xfree(ws, wp); 9785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* no word, process LEX1 character */ 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == '|') || (c == '&') || (c == ';') || (c == '('/*)*/)) { 9805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) == c) 9815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = (c == ';') ? BREAK : 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '|') ? LOGOR : 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '&') ? LOGAND : 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* c == '(' ) */ MDPAREN; 9855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '|' && c2 == '&') 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = COPROC; 98703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (c == ';' && c2 == '|') 98803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = BRKEV; 98903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (c == ';' && c2 == '&') 99003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = BRKFT; 9915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 99303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_SMALL 99403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == BREAK) { 99503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c2 = getsc()) == '&') 99603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = BRKEV; 99703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else 99803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(c2); 99903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 100003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\n') { 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gethere(false); 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cf & CONTIN) 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Again; 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\0') 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* need here strings at EOF */ 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gethere(true); 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 101103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* terminate word */ 101203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = EOS; 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yylval.cp = Xclose(ws, wp); 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SWORD || state == SLETPAREN 101503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* XXX ONEWORD? */) 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unget terminator */ 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * note: the alias-vs-function code below depends on several 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * interna: starting from here, source->str is not modified; 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the way getsc() and ungetsc() operate; etc. 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* copy word to unprefixed string ident */ 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sp = yylval.cp; 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = ident; 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & HEREDELIM) && (sp[1] == '<')) 1031c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((dp - ident) < IDENT) { 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = *sp++) == CHAR) 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *dp++ = *sp++; 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if ((c != OQUOTE) && (c != CQUOTE)) 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 1038c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser while ((dp - ident) < IDENT && (c = *sp++) == CHAR) 10395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *dp++ = *sp++; 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Make sure the ident array stays '\0' padded */ 1041c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser memset(dp, 0, (ident + IDENT) - dp + 1); 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != EOS) 104303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* word is not unquoted */ 104403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *ident = '\0'; 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 104603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*ident != '\0' && (cf & (KEYWORD | ALIAS))) { 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *p; 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h = hash(ident); 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) && 105103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (!(cf & ESACONLY) || p->val.i == ESAC || 105203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra p->val.i == /*{*/ '}')) { 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(yylval.cp, ATEMP); 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p->val.i); 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & ALIAS) && (p = ktsearch(&aliases, ident, h)) && 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (p->flag & ISSET)) { 10585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this still points to the same character as the 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ungetsc'd terminator from above 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp = source->str; 10635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prefer POSIX but not Korn functions over aliases */ 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp == ' ' || *cp == '\t') 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is like getsc() without skipping 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * over Source boundaries (including not 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parsing ungetsc'd characters that got 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pushed into an SREREAD) which is what 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * we want here anyway: find out whether 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the alias name is followed by a POSIX 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * function definition (only the opening 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parenthesis is checked though) 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++cp; 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prefer functions over aliases */ 107803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (cp[0] != '(' || cp[1] != ')') { 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s = source; 10805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (s && (s->flags & SF_HASALIAS)) 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->u.tblp == p) 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 10855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = s->next; 10865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* push alias expansion */ 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SALIAS, source->areap); 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = p->val.s; 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.tblp = p; 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_HASALIAS; 10915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->type == SEOF) { 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prevent infinite recursion at EOS */ 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->u.tblp = p; 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= SF_HASALIAS; 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(yylval.cp, ATEMP); 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Again; 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 11055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugethere(bool iseof) 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct ioword **p; 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = heres; p < herep; p++) 111303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (iseof && !((*p)->flag & IOHERESTR)) 11145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* only here strings at EOF */ 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru readhere(*p); 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru herep = heres; 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 11225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * read "<<word" text into temp file 11235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querureadhere(struct ioword *iop) 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 112903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *eof, *eofp; 11305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString xs; 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int xpos; 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 113403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (iop->flag & IOHERESTR) { 11355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* process the here string */ 113603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra iop->heredoc = xp = evalstr(iop->delim, DOBLANK); 113703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xpos = strlen(xp) - 1; 113803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra memmove(xp, xp + 1, xpos); 113903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp[xpos] = '\n'; 11405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 114303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra eof = iop->flag & IONDELIM ? "<<" : evalstr(iop->delim, 0); 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(iop->flag & IOEVAL)) 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(xs, xp, 256, ATEMP); 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 115003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_read_line: 115103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* beginning of line */ 115203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra eofp = eof; 115303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xpos = Xsavepos(xs, xp); 115403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (iop->flag & IOSKIP) { 115503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip over leading tabs */ 115603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while ((c = getsc()) == '\t') 115703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* nothing */; 115803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_parse_char; 115903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 116003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_read_char: 116103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = getsc(); 116203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_parse_char: 116303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* compare with here document marker */ 116403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!*eofp) { 116503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of here document marker, what to do? */ 116603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra switch (c) { 116703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case /*(*/ ')': 1168c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!subshell_nesting_type) 116903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /*- 117003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * not allowed outside $(...) or (...) 117103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * => mismatch 117203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 11735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 117403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* allow $(...) or (...) to close here */ 117503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(/*(*/ ')'); 117603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* FALLTHROUGH */ 117703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case 0: 117803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 117903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Allow EOF here to commands without trailing 118003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * newlines (mksh -c '...') will work as well. 118103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 118203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case '\n': 118303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Newline terminates here document marker */ 118403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_found_terminator; 11855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 118603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (c == *eofp++) 118703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* store; then read and compare next character */ 118803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_store_and_loop; 118903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* nope, mismatch; read until end of line */ 119003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (c != '\n') { 119103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!c) 119203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* oops, reached EOF */ 119303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra yyerror("%s '%s' unclosed\n", "here document", eof); 119403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* store character */ 11955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(xs, xp); 11965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, c); 119703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* read next character */ 119803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = getsc(); 11995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 120003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* we read a newline as last character */ 120103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_store_and_loop: 120203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* store character */ 120303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xcheck(xs, xp); 120403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Xput(xs, xp, c); 120503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (c == '\n') 120603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_read_line; 120703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto heredoc_read_char; 120803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 120903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra heredoc_found_terminator: 121003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* jump back to saved beginning of line */ 121103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp = Xrestpos(xs, xp, xpos); 121203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* terminate, close and store */ 12135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\0'); 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->heredoc = Xclose(xs, xp); 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(iop->flag & IOEVAL)) 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 12185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruyyerror(const char *fmt, ...) 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* pop aliases and re-reads */ 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (source->type == SALIAS || source->type == SREREAD) 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = source->next; 122803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* zap pending input */ 122903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra source->str = null; 12305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru error_prefix(true); 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 12335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_vfprintf(shl_out, fmt, va); 12345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorfz(); 12365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 12395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * input for yylex with alias expansion 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste QueruSource * 12435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupushs(int type, Area *areap) 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = alloc(sizeof(Source), areap); 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memset(s, 0, sizeof(Source)); 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = type; 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = null; 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->areap = areap; 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (type == SFILE || type == SSTDIN) 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XinitN(s->xs, 256, s->areap); 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 125803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condragetsc_uu(void) 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s = source; 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = *s->str++) == 0) { 126403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* return 0 for EOF by default */ 126503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s->str = NULL; 12665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (s->type) { 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SEOF: 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = null; 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSTDIN: 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SFILE: 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getsc_line(s); 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWSTR: 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSTRING: 1280c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case SSTRINGCMDLINE: 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWORDS: 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = *s->u.strv++; 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SWORDSEP; 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWORDSEP: 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s->u.strv == NULL) { 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = "\n"; 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SEOF; 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = " "; 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SWORDS; 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SALIAS: 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->flags & SF_ALIASEND) { 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* pass on an unused SF_ALIAS flag */ 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s->next; 13025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= s->flags & SF_ALIAS; 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = source; 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*s->u.tblp->val.s && 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c = strnul(s->u.tblp->val.s)[-1], ksh_isspace(c))) { 130603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* pop source stack */ 130703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra source = s = s->next; 130803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 130903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Note that this alias ended with a 131003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * space, enabling alias expansion on 131103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * the following word. 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_ALIAS; 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 131503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 131603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * At this point, we need to keep the current 13175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * alias in the source list so recursive 131803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * aliases can be detected and we also need to 131903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * return the next character. Do this by 132003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * temporarily popping the alias to get the 132103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * next character and then put it back in the 132203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * source list with the SF_ALIASEND flag set. 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 132403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* pop source stack */ 132503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra source = s->next; 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= s->flags & SF_ALIAS; 132703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = getsc_uu(); 13285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 13295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_ALIASEND; 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->ugbuf[0] = c; s->ugbuf[1] = '\0'; 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = s->ugbuf; 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 13335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = source; 133603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* avoid reading EOF twice */ 13375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = NULL; 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SREREAD: 134403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (s->start != s->ugbuf) 134503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* yuck */ 13465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(s->u.freeme, ATEMP); 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s = s->next; 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->str == NULL) { 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SEOF; 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = null; 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ('\0'); 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->flags & SF_ECHO) { 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(s->str, shl_out); 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 13615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 13645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc_line(Source *s) 13655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp = Xstring(s->xs, xp), *cp; 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool interactive = Flag(FTALKING) && s->type == SSTDIN; 1368c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool have_tty = tobool(interactive && (s->flags & SF_TTY)); 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Done here to ensure nothing odd happens when a timeout occurs */ 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(s->xs, xp, LINE); 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *xp = '\0'; 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = xp; 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ksh_tmout) { 13765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_READING; 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alarm(ksh_tmout); 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru change_winsz(); 1381c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_NO_CMDLINE_EDITING 13825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ( 13835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !MKSH_S_NOVI 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FVI) || 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FEMACS) || Flag(FGMACS))) { 13875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nread; 13885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1389811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser nread = x_read(xp); 139003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (nread < 0) 139103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* read error */ 13925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nread = 0; 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp[nread] = '\0'; 13945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += nread; 1395c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else 1396c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1397c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser { 13985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pprompt(prompt, 0); 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->line++; 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 140303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p = shf_getse(xp, Xnleft(s->xs, xp), s->u.shf); 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!p && shf_error(s->u.shf) && 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_errno(s->u.shf) == EINTR) { 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_clearerr(s->u.shf); 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (trap) 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru runtraps(0); 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!p || (xp = p, xp[-1] == '\n')) 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* double buffer size */ 141603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* move past NUL so doubling works... */ 141703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp++; 14185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(s->xs, xp, Xlength(s->xs, xp)); 141903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* ...and move back again */ 142003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra xp--; 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 142203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 142303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * flush any unwanted input so other programs/builtins 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * can read it. Not very optimal, but less error prone 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * than flushing else where, dealing with redirections, 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * etc. 142703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * TODO: reduce size of shf buffer (~128?) if SSTDIN 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->type == SSTDIN) 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(s->u.shf); 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 143203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 143303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * XXX: temporary kludge to restore source after a 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * trap may have been executed. 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ksh_tmout) { 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_EXECUTING; 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alarm(0); 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = Xstring(s->xs, xp); 1442427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes rndpush(cp); 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{ 15245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char delimiter = 0; 1525427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes bool doprint = (ntruncate != -1); 1526427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes bool indelimit = false; 1527427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes int columns = 0, lines = 0; 15285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 152903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 153003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Undocumented AT&T ksh feature: 153103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * If the second char in the prompt string is \r then the first 153203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * char is taken to be a non-printing delimiter and any chars 153303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * between two instances of the delimiter are not considered to 153403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * be part of the prompt length 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp && cp[1] == '\r') { 15375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru delimiter = *cp; 15385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp += 2; 15395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *cp; cp++) { 15415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (indelimit && *cp != delimiter) 15425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 15435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*cp == '\n' || *cp == '\r') { 15445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lines += columns / x_cols + ((*cp == '\n') ? 1 : 0); 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns = 0; 15465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == '\t') { 15475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns = (columns | 7) + 1; 15485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == '\b') { 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (columns > 0) 15505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns--; 15515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == delimiter) 15525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru indelimit = !indelimit; 15535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (UTFMODE && ((unsigned char)*cp > 0x7F)) { 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp2; 15555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns += utf_widthadj(cp, &cp2); 1556427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (doprint && (indelimit || 1557427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes (ntruncate < (x_cols * lines + columns)))) 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_write(cp, cp2 - cp, shl_out); 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = cp2 - /* loop increment */ 1; 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 15625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns++; 1563427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (doprint && (*cp != delimiter) && 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (indelimit || (ntruncate < (x_cols * lines + columns)))) 15655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc(*cp, shl_out); 15665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1567427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes if (doprint) 1568427d76ccc44aea287b51b233f0254a6107b2b3d1Elliott Hughes shf_flush(shl_out); 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (x_cols * lines + columns); 15705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 157203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 157303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Read the variable part of a ${...} expression (i.e. up to but not 157403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * including the :[-+?=#%] or close-brace). 15755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char * 15775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruget_brace_var(XString *wsp, char *wp) 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 157903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char c; 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru enum parse_state { 15815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PS_INITIAL, PS_SAW_HASH, PS_IDENT, 15825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PS_NUMBER, PS_VAR1 158303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } state = PS_INITIAL; 15845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 158503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 15865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* State machine to figure out where the variable part ends. */ 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (state) { 15895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_INITIAL: 15905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '#' || c == '!' || c == '%') { 15915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_SAW_HASH; 15925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 15955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_SAW_HASH: 15965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isalphx(c)) 15975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_IDENT; 15985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (ksh_isdigit(c)) 15995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_NUMBER; 160003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (c == '#') { 160103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (state == PS_SAW_HASH) { 160203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char c2; 160303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 160403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c2 = getsc(); 160503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(c2); 1606c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (c2 != /*{*/ '}') { 160703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ungetsc(c); 160803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto out; 160903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 161003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 161103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra state = PS_VAR1; 161203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else if (ctype(c, C_VAR1)) 16135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_VAR1; 16145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 16155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_IDENT: 16185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isalnux(c)) { 16195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') { 16205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *tmp, *p; 16215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!arraysub(&tmp)) 16235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyerror("missing ]\n"); 16245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = tmp; *p; ) { 16265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(*wsp, wp); 16275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = *p++; 16285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, ATEMP); 163003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* the ] */ 163103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = getsc(); 16325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_NUMBER: 16375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isdigit(c)) 16385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_VAR1: 16415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(*wsp, wp); 16445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru out: 164703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* end of variable part */ 164803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *wp++ = '\0'; 16495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 16505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (wp); 16515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 16545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Save an array subscript - returns true if matching bracket found, false 16555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if eof or newline was found. 16565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (Returned string double null terminated) 16575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 165803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic bool 16595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarraysub(char **strp) 16605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 16615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString ws; 166203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *wp, c; 166303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* we are just past the initial [ */ 1664c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unsigned int depth = 1; 16655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(ws, wp, 32, ATEMP); 16675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 16695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 16705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 16715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') 16735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth++; 16745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ']') 16755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth--; 16765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (depth > 0 && c && c != '\n'); 16775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 16795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *strp = Xclose(ws, wp); 16805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 168103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (tobool(depth == 0)); 16825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Unget a char: handles case when we are already at the start of the buffer */ 168503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void 16865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruungetsc(int c) 16875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 168803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct sretrace_info *rp = retrace_info; 168903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 16905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (backslash_skip) 16915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip--; 169203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* Don't unget EOF... */ 16935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->str == null && c == '\0') 169403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 169503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (rp) { 169603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (Xlength(rp->xs, rp->xp)) 169703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rp->xp--; 169803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rp = rp->next; 169903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 1700c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c); 170103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 170203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic void 1703c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserungetsc_i(int c) 170403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 17055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->str > source->start) 17065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->str--; 17075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 17085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 17095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SREREAD, source->areap); 17115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->ugbuf[0] = c; s->ugbuf[1] = '\0'; 17125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = s->ugbuf; 17135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 17145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 17155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called to get a char that isn't a \newline sequence. */ 17205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 17215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc_bn(void) 17225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c, c2; 17245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ignore_backslash_newline) 172603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (o_getsc_u()); 17275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (backslash_skip == 1) { 17295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 2; 173003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (o_getsc_u()); 17315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 0; 17345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 173503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 173603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra c = o_getsc_u(); 17375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 173803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((c2 = o_getsc_u()) == '\n') 17395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignore the \newline; get the next char... */ 17405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 1741c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c2); 17425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 1; 17435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 17455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 174803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid 174903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrayyskiputf8bom(void) 175003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 175103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int c; 175203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 175303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((unsigned char)(c = o_getsc_u()) != 0xEF) { 1754c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c); 175503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 175603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 175703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((unsigned char)(c = o_getsc_u()) != 0xBB) { 1758c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c); 1759c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(0xEF); 176003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 176103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 176203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((unsigned char)(c = o_getsc_u()) != 0xBF) { 1763c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(c); 1764c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(0xBB); 1765c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ungetsc_i(0xEF); 176603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 176703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 176803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra UTFMODE |= 8; 176903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 177003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 17715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Lex_state * 1772c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserpush_state_i(State_info *si, Lex_state *old_end) 17735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 177403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra Lex_state *news = alloc2(STATE_BSIZE, sizeof(Lex_state), ATEMP); 17755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 177603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra news[0].ls_base = old_end; 17775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru si->base = &news[0]; 17785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru si->end = &news[STATE_BSIZE]; 17795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (&news[1]); 17805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Lex_state * 1783c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserpop_state_i(State_info *si, Lex_state *old_end) 17845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *old_base = si->base; 17865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 178703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra si->base = old_end->ls_base - STATE_BSIZE; 178803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra si->end = old_end->ls_base; 17895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(old_base, ATEMP); 17915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (si->base + STATE_BSIZE - 1); 17935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 17965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_get(void) 17975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (getsc()); 17995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 18005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 18015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 18025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_put(int c) 18035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 18045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 18055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1806