lex.c revision 5155f1c7438ef540d7b25eb70aa1639579795b07
15155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: lex.c,v 1.44 2008/07/03 17:52:08 otto Exp $ */ 25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 45155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 55155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Thorsten Glaser <tg@mirbsd.org> 65155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 75155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Provided that these terms and disclaimer and all copyright notices 85155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are retained or reproduced in an accompanying document, permission 95155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is granted to deal in this work without restriction, including un- 105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * limited rights to use, publicly perform, distribute, sell, modify, 115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * merge, give away, or sublicence. 125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the utmost extent permitted by applicable law, neither express nor 155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * implied; without malicious intent or gross negligence. In no event 165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * may a licensor, author or contributor be held liable for indirect, 175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * direct, other damage, loss, or other issues arising in any way out 185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of dealing in the work, even if advised of the possibility of such 195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * damage or existence of a defect, except proven that it results out 205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of said person's immediate fault when using the work as intended. 215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "sh.h" 245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.118 2010/07/25 11:35:41 tg Exp $"); 265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * states while lexing word 295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SBASE 0 /* outside any lexical constructs */ 315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SWORD 1 /* implicit quoting for substitute() */ 325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SLETPAREN 2 /* inside (( )), implicit quoting */ 335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SSQUOTE 3 /* inside '' */ 345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SDQUOTE 4 /* inside "" */ 355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SEQUOTE 5 /* inside $'' */ 365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SBRACE 6 /* inside ${} */ 375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SQBRACE 7 /* inside "${}" */ 385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SCSPAREN 8 /* inside $() */ 395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SBQUOTE 9 /* inside `` */ 405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SASPAREN 10 /* inside $(( )) */ 415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SHEREDELIM 11 /* parsing <<,<<- delimiter */ 425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SHEREDQUOTE 12 /* parsing " in <<,<<- delimiter */ 435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SPATTERN 13 /* parsing *(...|...) pattern (*+?@!) */ 445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define STBRACE 14 /* parsing ${...[#%]...} */ 455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SLETARRAY 15 /* inside =( ), just copy */ 465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SADELIM 16 /* like SBASE, looking for delimiter */ 475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SHERESTRING 17 /* parsing <<< string */ 485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Structure to keep track of the lexing state and the various pieces of info 505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * needed for each particular state. */ 515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutypedef struct lex_state Lex_state; 525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct lex_state { 535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int ls_state; 545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru union { 555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* $(...) */ 565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct scsparen_info { 575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nparen; /* count open parenthesis */ 585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int csstate; /* XXX remove */ 595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ls_scsparen ls_info.u_scsparen 605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } u_scsparen; 615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* $((...)) */ 635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct sasparen_info { 645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nparen; /* count open parenthesis */ 655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int start; /* marks start of $(( in output str */ 665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ls_sasparen ls_info.u_sasparen 675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } u_sasparen; 685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ((...)) */ 705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct sletparen_info { 715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nparen; /* count open parenthesis */ 725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ls_sletparen ls_info.u_sletparen 735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } u_sletparen; 745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* `...` */ 765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct sbquote_info { 775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int indquotes; /* true if in double quotes: "`...`" */ 785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ls_sbquote ls_info.u_sbquote 795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } u_sbquote; 805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* =(...) */ 835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct sletarray_info { 845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nparen; /* count open parentheses */ 855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ls_sletarray ls_info.u_sletarray 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } u_sletarray; 875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ADELIM */ 905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct sadelim_info { 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char nparen; /* count open parentheses */ 925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SADELIM_BASH 0 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define SADELIM_MAKE 1 945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char style; 955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char delimiter; 965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char num; 975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char flags; /* ofs. into sadelim_flags[] */ 985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ls_sadelim ls_info.u_sadelim 995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } u_sadelim; 1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* $'...' */ 1025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct sequote_info { 1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool got_NUL; /* ignore rest of string */ 1045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define ls_sequote ls_info.u_sequote 1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } u_sequote; 1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *base; /* used to point to next state block */ 1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } ls_info; 1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutypedef struct { 1125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *base; 1135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *end; 1145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} State_info; 1155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void readhere(struct ioword *); 1175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int getsc__(void); 1185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void getsc_line(Source *); 1195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int getsc_bn(void); 1205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int s_get(void); 1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void s_put(int); 1225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char *get_brace_var(XString *, char *); 1235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int arraysub(char **); 1245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *ungetsc(int); 1255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void gethere(bool); 1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Lex_state *push_state_(State_info *, Lex_state *); 1275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Lex_state *pop_state_(State_info *, Lex_state *); 1285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int dopprompt(const char *, int, bool); 1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int backslash_skip; 1325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int ignore_backslash_newline; 1335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* optimised getsc_bn() */ 1355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define _getsc() (*source->str != '\0' && *source->str != '\\' \ 1365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru && !backslash_skip && !(source->flags & SF_FIRST) \ 1375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ? *source->str++ : getsc_bn()) 1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* optimised getsc__() */ 1395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define _getsc_() ((*source->str != '\0') && !(source->flags & SF_FIRST) \ 1405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ? *source->str++ : getsc__()) 1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef MKSH_SMALL 1435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int getsc(void); 1445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int getsc_(void); 1455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 1475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc(void) 1485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (_getsc()); 1505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 1535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc_(void) 1545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (_getsc_()); 1565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 1585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* !MKSH_SMALL: use them inline */ 1595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define getsc() _getsc() 1605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define getsc_() _getsc_() 1615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 1625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define STATE_BSIZE 32 1645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define PUSH_STATE(s) do { \ 1665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (++statep == state_info.end) \ 1675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep = push_state_(&state_info, statep); \ 1685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = statep->ls_state = (s); \ 1695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} while (0) 1705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define POP_STATE() do { \ 1725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (--statep == state_info.base) \ 1735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep = pop_state_(&state_info, statep); \ 1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = statep->ls_state; \ 1755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} while (0) 1765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/** 1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Lexical analyser 1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * tokens are not regular expressions, they are LL(1). 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for example, "${var:-${PWD}}", and "$(size $(whence ksh))". 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * hence the state stack. 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruyylex(int cf) 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state states[STATE_BSIZE], *statep, *s2, *base; 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru State_info state_info; 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c, c2, state; 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString ws; /* expandable output word */ 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *wp; /* output word pointer */ 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *sp, *dp; 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Again: 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru states[0].ls_state = -1; 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru states[0].ls_info.base = NULL; 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep = &states[1]; 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state_info.base = states; 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state_info.end = &state_info.base[STATE_BSIZE]; 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(ws, wp, 64, ATEMP); 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 0; 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline = 0; 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cf&ONEWORD) 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SWORD; 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (cf&LETEXPR) { 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* enclose arguments in (double) quotes */ 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SLETPAREN; 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sletparen.nparen = 0; 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (cf&LETARRAY) { 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SLETARRAY; 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sletarray.nparen = 0; 2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { /* normal lexing */ 2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = (cf & HEREDELIM) ? SHEREDELIM : SBASE; 2215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) == ' ' || c == '\t') 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '#') { 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) != '\0' && c != '\n') 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->flags & SF_ALIAS) { /* trailing ' ' in alias definition */ 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags &= ~SF_ALIAS; 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cf |= ALIAS; 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Initial state: one of SBASE SHEREDELIM SWORD SASPAREN */ 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_state = state; 2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check for here string */ 2405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SHEREDELIM) { 2415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '<') { 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SHERESTRING; 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) == ' ' || c == '\t') 2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = '<'; 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto accept_nonword; 2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 2515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* collect non-special or quoted characters to form word */ 2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (!((c = getsc()) == 0 || 2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((state == SBASE || state == SHEREDELIM || state == SHERESTRING) && 2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ctype(c, C_LEX1)))) { 2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru accept_nonword: 2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 2595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (state) { 2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SADELIM: 2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') 2625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.nparen++; 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ')') 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.nparen--; 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (statep->ls_sadelim.nparen == 0 && 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == /*{*/ '}' || c == statep->ls_sadelim.delimiter)) { 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == /*{*/ '}' || --statep->ls_sadelim.num == 0) 2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == /*{*/ '}') 2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SBASE: 2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[' && (cf & (VARASN|ARRAYVAR))) { 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp = EOS; /* temporary */ 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (is_wdvarname(Xstring(ws, wp), false)) { 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *tmp; 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arraysub(&tmp)) { 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = tmp; *p; ) { 2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = *p++; 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, ATEMP); 2915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SREREAD, 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->areap); 2975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = 2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.freeme = tmp; 2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Sbase1: /* includes *(...|...) pattern (*+?@!) */ 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '*' || c == '@' || c == '+' || c == '?' || 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '!') { 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = getsc(); 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c2 == '(' /*)*/ ) { 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OPAT; 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SPATTERN); 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Sbase2: /* doesn't include *(...|...) pattern (*+?@!) */ 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getsc_qchar: 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = getsc())) { 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\'': 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru open_ssquote: 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SSQUOTE); 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru open_sdquote: 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SDQUOTE); 3415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subst; 3445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Subst: 3485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 3515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 3535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & HEREDOC)) 3545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto heredocquote; 3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 3565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 3575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': case '`': 3585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru store_qchar: 3595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 3635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru heredocquote: 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 3655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 3665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\\'; 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru subst_dollar: 3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') /*)*/ { 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') /*)*/ { 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SASPAREN); 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sasparen.nparen = 2; 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sasparen.start = 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xsavepos(ws, wp); 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = EXPRSUB; 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SCSPAREN); 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.nparen = 1; 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.csstate = 0; 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = COMSUB; 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '{') /*}*/ { 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '{'; /*}*/ 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp = get_brace_var(&ws, wp); 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* allow :# and :% (ksh88 compat) */ 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == ':') { 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == ':') { 4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '0'; 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ':'; 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.style = SADELIM_BASH; 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.delimiter = ':'; 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.num = 1; 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.nparen = 0; 4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ksh_isdigit(c) || 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '('/*)*/ || c == ' ' || 4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '$' /* XXX what else? */) { 4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* substring subst. */ 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != ' ') { 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ' '; 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.style = SADELIM_BASH; 4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.delimiter = ':'; 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.num = 2; 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.nparen = 0; 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '/') { 4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = getsc()) == '/') { 4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ADELIM; 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SADELIM); 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.style = SADELIM_BASH; 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.delimiter = '/'; 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.num = 1; 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sadelim.nparen = 0; 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* If this is a trim operation, 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * treat (,|,) specially in STBRACE. 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ctype(c, C_SUBOP2)) { 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(STBRACE); 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SDQUOTE) 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SQBRACE); 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBRACE); 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ksh_isalphx(c)) { 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (ksh_isalnux(c)); 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ctype(c, C_VAR1 | C_DIGIT)) { 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OSUBST; 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 'X'; 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\'' && (state == SBASE)) { 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX which other states are valid? */ 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SEQUOTE); 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sequote.got_NUL = false; 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '$'; 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '`': 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru subst_gravis: 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SBQUOTE); 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = COMSUB; 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Need to know if we are inside double quotes 4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * since sh/AT&T-ksh translate the \" to " in 5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * "`...\"...`". 5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This is not done in POSIX mode (section 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 3.2.3, Double Quotes: "The backquote shall 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * retain its special meaning introducing the 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * other form of command substitution (see 5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 3.6.3). The portion of the quoted string 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * from the initial backquote and the 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * characters up to the next backquote that 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is not preceded by a backslash (having 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * escape characters removed) defines that 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * command whose output replaces `...` when 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the word is expanded." 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Section 3.6.3, Command Substitution: 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * "Within the backquoted style of command 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * substitution, backslash shall retain its 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * literal meaning, except when followed by 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * $ ` \."). 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sbquote.indquotes = 0; 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s2 = statep; 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = state_info.base; 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (1) { 5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; s2 != base; s2--) { 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s2->ls_state == SDQUOTE) { 5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sbquote.indquotes = 1; 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s2 != base) 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(s2 = s2->ls_info.base)) 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = s2-- - STATE_BSIZE; 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case QCHAR: 5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cf & LQCHAR) { 5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = getsc(); 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru store_char: 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 5455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SEQUOTE: 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') { 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\\') { 5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = unbksl(true, s_get, s_put)) == -1) 5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = s_get(); 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c2 == 0) 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sequote.got_NUL = true; 5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!statep->ls_sequote.got_NUL) { 5605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char ts[4]; 5615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((unsigned int)c2 < 0x100) { 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 5645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c2; 5655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 5665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = utf_wctomb(ts, c2 - 0x100); 5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ts[c] = 0; 5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (c = 0; ts[c]; ++c) { 5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ts[c]; 5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!statep->ls_sequote.got_NUL) { 5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSQUOTE: 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') { 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SDQUOTE: 5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '"') { 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subst; 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SCSPAREN: /* $( ... ) */ 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* todo: deal with $(...) quoting properly 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * kludge to partly fake quoting inside $(...): doesn't 6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * really work because nested $(...) or ${...} inside 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * double quotes aren't dealt with. 6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (statep->ls_scsparen.csstate) { 6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 0: /* normal */ 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '(': 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.nparen++; 6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case ')': 6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.nparen--; 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.csstate = 1; 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.csstate = 2; 6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\'': 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.csstate = 4; 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 1: /* backslash in normal mode */ 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 3: /* backslash in double quotes */ 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --statep->ls_scsparen.csstate; 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 2: /* double quotes */ 6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '"') 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.csstate = 0; 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '\\') 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.csstate = 3; 6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 4: /* single quotes */ 6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') { 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.csstate = 0; 6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (statep->ls_scsparen.nparen == 0) { 6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 0; /* end of COMSUB */ 6495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 6515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SASPAREN: /* $(( ... )) */ 6545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX should nest using existing state machine 6555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (embed "...", $(...), etc.) */ 6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '(') 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sasparen.nparen++; 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ')') { 6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sasparen.nparen--; 6605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (statep->ls_sasparen.nparen == 1) { 6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*(*/ 6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) == ')') { 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* end of EXPRSUB */ 6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 0; 6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s; 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* mismatched parenthesis - 6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * assume we were really 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parsing a $(...) expression 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = Xrestpos(ws, wp, 6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sasparen.start); 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memmove(s + 1, s, wp - s); 6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *s++ = COMSUB; 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *s = '('; /*)*/ 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.nparen = 1; 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_scsparen.csstate = 0; 6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = statep->ls_state = 6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SCSPAREN; 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SQBRACE: 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * perform POSIX "quote removal" if the back- 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * slash is "special", i.e. same cases as the 6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * {case '\\':} in Subst: plus closing brace; 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * in mksh code "quote removal" on '\c' means 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * write QCHAR+c, otherwise CHAR+\+CHAR+c are 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * emitted (in heredocquote:) 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = getsc()) == '"' || c == '\\' || 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c == '$' || c == '`' || c == /*{*/'}') 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto store_qchar; 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto heredocquote; 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto common_SQBRACE; 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SBRACE: 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\'') 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto open_ssquote; 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '\\') 7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto getsc_qchar; 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru common_SQBRACE: 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '"') 7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto open_sdquote; 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '$') 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto subst_dollar; 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '`') 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto subst_gravis; 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c != /*{*/ '}') 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto store_char; 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = /*{*/ '}'; 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case STBRACE: 7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Same as SBASE, except (,|,) treated specially */ 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == /*{*/ '}') { 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CSUBST; 7325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = /*{*/ '}'; 7335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '|') { 7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = SPAT; 7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '(') { 7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OPAT; 7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ' '; /* simile for @ */ 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SPATTERN); 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Sbase1; 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SBQUOTE: 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '`') { 7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = 0; 7465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 7475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\\') { 7485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c = getsc()) { 7495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': 7505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': case '`': 7515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 7525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '"': 7545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (statep->ls_sbquote.indquotes) { 7555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 7565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 7595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 7605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 7615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 7625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\\'; 7635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 7645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 7685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 7695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWORD: /* ONEWORD */ 7725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Subst; 7735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SLETPAREN: /* LETEXPR: (( ... )) */ 7755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*(*/ 7765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == ')') { 7775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (statep->ls_sletparen.nparen > 0) 7785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --statep->ls_sletparen.nparen; 7795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if ((c2 = getsc()) == /*(*/ ')') { 7805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = 0; 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 7825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Done; 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 7845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 7855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 7875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* mismatched parenthesis - 7885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * assume we were really 7895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parsing a $(...) expression 7905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp = EOS; 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sp = Xstring(ws, wp); 7935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = wdstrip(sp, true, false); 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 == '(') 8015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* parenthesis inside quotes and backslashes 8025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are lost, but AT&T ksh doesn't count them 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * either 8045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++statep->ls_sletparen.nparen; 8065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Sbase2; 8075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 8095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SLETARRAY: /* LETARRAY: =( ... ) */ 8105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '('/*)*/) 8115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++statep->ls_sletarray.nparen; 8125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == /*(*/')') 8135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (statep->ls_sletarray.nparen-- == 0) { 8145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = 0; 8155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Done; 8165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 8185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SHERESTRING: /* <<< delimiter */ 8235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 8255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 8265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 8275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 8285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* invoke quoting mode */ 8315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xstring(ws, wp)[0] = QCHAR; 8325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '$') { 8335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) == '\'') { 8345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SEQUOTE); 8355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sequote.got_NUL = false; 8365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto sherestring_quoted; 8375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 8395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto sherestring_regular; 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\'') { 8415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SSQUOTE); 8425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sherestring_quoted: 8435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 8455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* invoke quoting mode */ 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xstring(ws, wp)[0] = QCHAR; 8475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '"') { 8485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = statep->ls_state = SHEREDQUOTE; 8495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 8505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* just don't IFS split; no quoting mode */ 8515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 8525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sherestring_regular: 8535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 8545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SHEREDELIM: /* <<,<<- delimiter */ 8595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX chuck this state (and the next) - use 8605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the existing states ($ and \`...` should be 8615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * stripped of their specialness after the 8625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * fact). 8635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* here delimiters need a special case since 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * $ and `...` are not to be treated specially 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 8695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 8705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ is lost */ 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = QCHAR; 8725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '$') { 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) == '\'') { 8765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SEQUOTE); 8775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru statep->ls_sequote.got_NUL = false; 8785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto sheredelim_quoted; 8795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 8815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto sheredelim_regular; 8825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\'') { 8835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SSQUOTE); 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sheredelim_quoted: 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 8875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '"') { 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = statep->ls_state = SHEREDQUOTE; 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OQUOTE; 8905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 8915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sheredelim_regular: 8925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 8935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 8945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SHEREDQUOTE: /* " in <<,<<- delimiter */ 8985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '"') { 8995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CQUOTE; 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = statep->ls_state = 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* dp[1] == '<' means here string */ 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xstring(ws, wp)[1] == '<' ? 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SHERESTRING : SHEREDELIM; 9045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 9065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c = getsc()) { 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '\\': case '"': 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': case '`': 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 9115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 9125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trailing \ lost */ 9135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\\'; 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CHAR; 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SPATTERN: /* in *(...|...) pattern (*+?@!) */ 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ( /*(*/ c == ')') { 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = CPAT; 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru POP_STATE(); 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '|') { 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = SPAT; 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '(') { 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = OPAT; 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = ' '; /* simile for @ */ 9335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PUSH_STATE(SPATTERN); 9345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 9355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Sbase1; 9365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Done: 9405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 9415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (statep != &states[1]) 9425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX figure out what is missing */ 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyerror("no closing quote\n"); 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SLETARRAY && statep->ls_sletarray.nparen != -1) 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyerror("%s: ')' missing\n", T_synerr); 9485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 9495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This done to avoid tests for SHEREDELIM wherever SBASE tested */ 9515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SHEREDELIM || state == SHERESTRING) 9525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = SBASE; 9535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = Xstring(ws, wp); 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == '<' || c == '>' || c == '&') && state == SBASE) { 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct ioword *iop = alloc(sizeof(struct ioword), ATEMP); 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Xlength(ws, wp) == 0) 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->unit = c == '<' ? 0 : 1; 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else for (iop->unit = 0, c2 = 0; c2 < Xlength(ws, wp); c2 += 2) { 9615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (dp[c2] != CHAR) 9625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isdigit(dp[c2 + 1])) 9645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->unit = (iop->unit * 10) + dp[c2 + 1] - '0'; 9665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->unit >= FDBASE) 9695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '&') { 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) != '>') { 9735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 9745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto no_iop; 9755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = c2; 9775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag = IOBASH; 9785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag = 0; 9805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c2 = getsc(); 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* <<, >>, <> are ok, >< is not */ 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == c2 || (c == '<' && c2 == '>')) { 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= c == c2 ? 9855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '>' ? IOCAT : IOHERE) : IORDWR; 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->flag == IOHERE) { 9875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) == '-') 9885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IOSKIP; 9895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 9915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c2 == '&') 9935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IODUP | (c == '<' ? IORDUP : 0); 9945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 9955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= c == '>' ? IOWRITE : IOREAD; 9965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '>' && c2 == '|') 9975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->flag |= IOCLOB; 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->name = NULL; 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->delim = NULL; 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->heredoc = NULL; 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xfree(ws, wp); /* free word */ 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yylval.iop = iop; 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (REDIR); 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru no_iop: 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (wp == dp && state == SBASE) { 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xfree(ws, wp); /* free word */ 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* no word, process LEX1 character */ 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c == '|') || (c == '&') || (c == ';') || (c == '('/*)*/)) { 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc()) == c) 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = (c == ';') ? BREAK : 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '|') ? LOGOR : 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c == '&') ? LOGAND : 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* c == '(' ) */ MDPAREN; 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == '|' && c2 == '&') 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = COPROC; 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\n') { 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gethere(false); 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cf & CONTIN) 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Again; 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '\0') 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* need here strings at EOF */ 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gethere(true); 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = EOS; /* terminate word */ 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yylval.cp = Xclose(ws, wp); 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (state == SWORD || state == SLETPAREN 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX ONEWORD? */ 10395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru || state == SLETARRAY 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ) 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unget terminator */ 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * note: the alias-vs-function code below depends on several 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * interna: starting from here, source->str is not modified; 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the way getsc() and ungetsc() operate; etc. 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* copy word to unprefixed string ident */ 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sp = yylval.cp; 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dp = ident; 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & HEREDELIM) && (sp[1] == '<')) 10585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (dp < ident+IDENT) { 10595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c = *sp++) == CHAR) 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *dp++ = *sp++; 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if ((c != OQUOTE) && (c != CQUOTE)) 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (dp < ident+IDENT && (c = *sp++) == CHAR) 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *dp++ = *sp++; 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Make sure the ident array stays '\0' padded */ 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memset(dp, 0, (ident+IDENT) - dp + 1); 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != EOS) 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *ident = '\0'; /* word is not unquoted */ 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ident != '\0' && (cf&(KEYWORD|ALIAS))) { 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *p; 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h = hash(ident); 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* { */ 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) && 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!(cf & ESACONLY) || p->val.i == ESAC || p->val.i == '}')) { 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(yylval.cp, ATEMP); 10805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p->val.i); 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cf & ALIAS) && (p = ktsearch(&aliases, ident, h)) && 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (p->flag & ISSET)) { 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this still points to the same character as the 10865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * ungetsc'd terminator from above 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp = source->str; 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prefer POSIX but not Korn functions over aliases */ 10915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp == ' ' || *cp == '\t') 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is like getsc() without skipping 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * over Source boundaries (including not 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parsing ungetsc'd characters that got 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pushed into an SREREAD) which is what 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * we want here anyway: find out whether 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the alias name is followed by a POSIX 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * function definition (only the opening 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * parenthesis is checked though) 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++cp; 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prefer functions over aliases */ 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp == '(' /*)*/) 11055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * delete alias upon encountering function 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * definition 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ktdelete(p); 11105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s = source; 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (s && (s->flags & SF_HASALIAS)) 11145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->u.tblp == p) 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 11165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = s->next; 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* push alias expansion */ 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SALIAS, source->areap); 11205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = p->val.s; 11215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->u.tblp = p; 11225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_HASALIAS; 11235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->type == SEOF) { 11255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prevent infinite recursion at EOS */ 11265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->u.tblp = p; 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= SF_HASALIAS; 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 11305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(yylval.cp, ATEMP); 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto Again; 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (LWORD); 11375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugethere(bool iseof) 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct ioword **p; 11435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = heres; p < herep; p++) 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iseof && (*p)->delim[1] != '<') 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* only here strings at EOF */ 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru readhere(*p); 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru herep = heres; 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 11545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * read "<<word" text into temp file 11555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querureadhere(struct ioword *iop) 11595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 11615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *volatile eof; 11625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *eofp; 11635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int skiptabs; 11645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString xs; 11655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 11665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int xpos; 11675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (iop->delim[1] == '<') { 11695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* process the here string */ 11705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp = iop->heredoc = evalstr(iop->delim, DOBLANK); 11715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = strlen(xp) - 1; 11725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memmove(xp, xp + 1, c); 11735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp[c] = '\n'; 11745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru eof = evalstr(iop->delim, 0); 11785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(iop->flag & IOEVAL)) 11805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline++; 11815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(xs, xp, 256, ATEMP); 11835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (;;) { 11855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru eofp = eof; 11865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru skiptabs = iop->flag & IOSKIP; 11875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xpos = Xsavepos(xs, xp); 11885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) != 0) { 11895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (skiptabs) { 11905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\t') 11915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 11925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru skiptabs = 0; 11935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c != *eofp) 11955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(xs, xp); 11975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, c); 11985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru eofp++; 11995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Allow EOF here so commands with out trailing newlines 12015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * will work (eg, ksh -c '...', $(...), etc). 12025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*eofp == '\0' && (c == 0 || c == '\n')) { 12045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp = Xrestpos(xs, xp, xpos); 12055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 12085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = getsc()) != '\n') { 12095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == 0) 12105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyerror("here document '%s' unclosed\n", eof); 12115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(xs, xp); 12125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, c); 12135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(xs, xp); 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, c); 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xput(xs, xp, '\0'); 12185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru iop->heredoc = Xclose(xs, xp); 12195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(iop->flag & IOEVAL)) 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ignore_backslash_newline--; 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruyyerror(const char *fmt, ...) 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_list va; 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* pop aliases and re-reads */ 12305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (source->type == SALIAS || source->type == SREREAD) 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = source->next; 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->str = null; /* zap pending input */ 12335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru error_prefix(true); 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_start(va, fmt); 12365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_vfprintf(shl_out, fmt, va); 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru va_end(va); 12385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorfz(); 12395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 12425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * input for yylex with alias expansion 12435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste QueruSource * 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupushs(int type, Area *areap) 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = alloc(sizeof(Source), areap); 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memset(s, 0, sizeof(Source)); 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = type; 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = null; 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->areap = areap; 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (type == SFILE || type == SSTDIN) 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XinitN(s->xs, 256, s->areap); 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc__(void) 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s = source; 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 12655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getsc_again: 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = *s->str++) == 0) { 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = NULL; /* return 0 for EOF by default */ 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (s->type) { 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SEOF: 12715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = null; 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSTDIN: 12755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SFILE: 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getsc_line(s); 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWSTR: 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SSTRING: 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWORDS: 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = *s->u.strv++; 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SWORDSEP; 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SWORDSEP: 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s->u.strv == NULL) { 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = "\n"; 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SEOF; 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = " "; 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SWORDS; 12975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SALIAS: 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->flags & SF_ALIASEND) { 13025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* pass on an unused SF_ALIAS flag */ 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s->next; 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= s->flags & SF_ALIAS; 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = source; 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*s->u.tblp->val.s && 13075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (c = strnul(s->u.tblp->val.s)[-1], ksh_isspace(c))) { 13085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s = s->next; /* pop source stack */ 13095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Note that this alias ended with a space, 13105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * enabling alias expansion on the following 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * word. 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_ALIAS; 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 13155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* At this point, we need to keep the current 13165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * alias in the source list so recursive 13175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * aliases can be detected and we also need 13185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to return the next character. Do this 13195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * by temporarily popping the alias to get 13205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the next character and then put it back 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * in the source list with the SF_ALIASEND 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * flag set. 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s->next; /* pop source stack */ 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->flags |= s->flags & SF_ALIAS; 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc__(); 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c) { 13285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags |= SF_ALIASEND; 13295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->ugbuf[0] = c; s->ugbuf[1] = '\0'; 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = s->ugbuf; 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 13335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = source; 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* avoid reading eof twice */ 13365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = NULL; 13375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 13415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SREREAD: 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->start != s->ugbuf) /* yuck */ 13445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(s->u.freeme, ATEMP); 13455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s = s->next; 13465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->str == NULL) { 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->type = SEOF; 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = null; 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ('\0'); 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->flags & SF_ECHO) { 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_puts(s->str, shl_out); 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check for UTF-8 byte order mark */ 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->flags & SF_FIRST) { 13605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->flags &= ~SF_FIRST; 13615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (((unsigned char)c == 0xEF) && 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (((const unsigned char *)(s->str))[0] == 0xBB) && 13635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (((const unsigned char *)(s->str))[1] == 0xBF)) { 13645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str += 2; 13655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru UTFMODE = 1; 13665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto getsc_again; 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetsc_line(Source *s) 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp = Xstring(s->xs, xp), *cp; 13765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool interactive = Flag(FTALKING) && s->type == SSTDIN; 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int have_tty = interactive && (s->flags & SF_TTY); 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Done here to ensure nothing odd happens when a timeout occurs */ 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(s->xs, xp, LINE); 13815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *xp = '\0'; 13825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = xp; 13835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ksh_tmout) { 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_READING; 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alarm(ksh_tmout); 13875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 13895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru change_winsz(); 13905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ( 13915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !MKSH_S_NOVI 13925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FVI) || 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 13945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Flag(FEMACS) || Flag(FGMACS))) { 13955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nread; 13965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nread = x_read(xp, LINE); 13985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (nread < 0) /* read error */ 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nread = 0; 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp[nread] = '\0'; 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += nread; 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru pprompt(prompt, 0); 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->line++; 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (1) { 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p = shf_getse(xp, Xnleft(s->xs, xp), s->u.shf); 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!p && shf_error(s->u.shf) && 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_errno(s->u.shf) == EINTR) { 14135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_clearerr(s->u.shf); 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (trap) 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru runtraps(0); 14165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 14175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!p || (xp = p, xp[-1] == '\n')) 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* double buffer size */ 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp++; /* move past NUL so doubling works... */ 14225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(s->xs, xp, Xlength(s->xs, xp)); 14235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp--; /* ...and move back again */ 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* flush any unwanted input so other programs/builtins 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * can read it. Not very optimal, but less error prone 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * than flushing else where, dealing with redirections, 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * etc. 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * todo: reduce size of shf buffer (~128?) if SSTDIN 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->type == SSTDIN) 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(s->u.shf); 14335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX: temporary kludge to restore source after a 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * trap may have been executed. 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_tty && ksh_tmout) { 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_EXECUTING; 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alarm(0); 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = Xstring(s->xs, xp); 14435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 14445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive && *cp == '!' && cur_prompt == PS1) { 14455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int linelen; 14465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru linelen = Xlength(s->xs, xp); 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(s->xs, xp, fc_e_n + /* NUL */ 1); 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* reload after potential realloc */ 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = Xstring(s->xs, xp); 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* change initial '!' into space */ 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *cp = ' '; 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* NUL terminate the current string */ 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *xp = '\0'; 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* move the actual string forward */ 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memmove(cp + fc_e_n, cp, linelen + /* NUL */ 1); 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += fc_e_n; 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* prepend it with "fc -e -" */ 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(cp, fc_e_, fc_e_n); 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = cp; 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp)); 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Note: if input is all nulls, this is not eof */ 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Xlength(s->xs, xp) == 0) { 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* EOF */ 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s->type == SFILE) 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fdclose(s->u.shf); 14695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->str = NULL; 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (interactive && *s->str && 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (cur_prompt != PS1 || !ctype(*s->str, C_IFS | C_IFSWS))) { 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsave(&s->line, s->str, true, true); 14735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (interactive && cur_prompt == PS1) { 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = Xstring(s->xs, xp); 14765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*cp && ctype(*cp, C_IFSWS)) 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++cp; 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*cp) 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsync(); 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (interactive) 14835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set_prompt(PS2, NULL); 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruset_prompt(int to, Source *s) 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cur_prompt = to; 14905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (to) { 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS1: /* command */ 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Substitute ! and !! here, before substitutions are done 14945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * so ! in expanded variables are not expanded. 14955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * NOTE: this is not what AT&T ksh does (it does it after 14965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * substitutions, POSIX doesn't say which is to be done. 14975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 14995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct shf *shf; 15005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char * volatile ps1; 15015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Area *saved_atemp; 15025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ps1 = str_val(global("PS1")); 15045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf = shf_sopen(NULL, strlen(ps1) * 2, 15055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SHF_WR | SHF_DYNAMIC, NULL); 15065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*ps1) 15075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ps1 != '!' || *++ps1 == '!') 15085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putchar(*ps1++, shf); 15095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 15105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%d", 15115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s ? s->line + 1 : 0); 15125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ps1 = shf_sclose(shf); 15135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru saved_atemp = ATEMP; 15145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru newenv(E_ERRH); 15155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sigsetjmp(e->jbuf, 0)) { 15165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prompt = safe_prompt; 15175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Don't print an error - assume it has already 15185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * been printed. Reason is we may have forked 15195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * to run a command and the child may be 15205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * unwinding its stack through this code as it 15215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * exits. 15225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 15245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp = substitute(ps1, 0); 15255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(prompt, cp, saved_atemp); 15265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru quitenv(NULL); 15285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS2: /* command continuation */ 15315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prompt = str_val(global("PS2")); 15325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 15375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querudopprompt(const char *cp, int ntruncate, bool doprint) 15385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int columns = 0, lines = 0, indelimit = 0; 15405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char delimiter = 0; 15415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Undocumented AT&T ksh feature: 15435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If the second char in the prompt string is \r then the first char 15445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is taken to be a non-printing delimiter and any chars between two 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * instances of the delimiter are not considered to be part of the 15465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * prompt length 15475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 15485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*cp && cp[1] == '\r') { 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru delimiter = *cp; 15505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp += 2; 15515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; *cp; cp++) { 15535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (indelimit && *cp != delimiter) 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 15555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (*cp == '\n' || *cp == '\r') { 15565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lines += columns / x_cols + ((*cp == '\n') ? 1 : 0); 15575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns = 0; 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == '\t') { 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns = (columns | 7) + 1; 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == '\b') { 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (columns > 0) 15625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns--; 15635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (*cp == delimiter) 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru indelimit = !indelimit; 15655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (UTFMODE && ((unsigned char)*cp > 0x7F)) { 15665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cp2; 15675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns += utf_widthadj(cp, &cp2); 15685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (doprint && (indelimit || 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (ntruncate < (x_cols * lines + columns)))) 15705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_write(cp, cp2 - cp, shl_out); 15715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = cp2 - /* loop increment */ 1; 15725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 15735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 15745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru columns++; 15755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (doprint && (*cp != delimiter) && 15765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (indelimit || (ntruncate < (x_cols * lines + columns)))) 15775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc(*cp, shl_out); 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (doprint) 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_out); 15815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (x_cols * lines + columns); 15825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupprompt(const char *cp, int ntruncate) 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru dopprompt(cp, ntruncate, true); 15895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 15925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupromptlen(const char *cp) 15935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (dopprompt(cp, 0, false)); 15955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Read the variable part of a ${...} expression (ie, up to but not including 15985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the :[-+?=#%] or close-brace. 15995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 16005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char * 16015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruget_brace_var(XString *wsp, char *wp) 16025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 16035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru enum parse_state { 16045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PS_INITIAL, PS_SAW_HASH, PS_IDENT, 16055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru PS_NUMBER, PS_VAR1 16065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } state; 16075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char c; 16085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_INITIAL; 16105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (1) { 16115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 16125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* State machine to figure out where the variable part ends. */ 16135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (state) { 16145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_INITIAL: 16155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '#' || c == '!' || c == '%') { 16165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_SAW_HASH; 16175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* FALLTHROUGH */ 16205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_SAW_HASH: 16215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isalphx(c)) 16225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_IDENT; 16235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (ksh_isdigit(c)) 16245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_NUMBER; 16255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (ctype(c, C_VAR1)) 16265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = PS_VAR1; 16275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 16285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_IDENT: 16315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isalnux(c)) { 16325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') { 16335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *tmp, *p; 16345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!arraysub(&tmp)) 16365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru yyerror("missing ]\n"); 16375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = tmp; *p; ) { 16395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(*wsp, wp); 16405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = *p++; 16415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, ATEMP); 16435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); /* the ] */ 16445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_NUMBER: 16495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isdigit(c)) 16505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 16525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case PS_VAR1: 16535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto out; 16545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(*wsp, wp); 16565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 16585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru out: 16595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; /* end of variable part */ 16605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 16615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (wp); 16625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 16655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Save an array subscript - returns true if matching bracket found, false 16665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if eof or newline was found. 16675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (Returned string double null terminated) 16685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 16695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 16705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarraysub(char **strp) 16715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 16725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString ws; 16735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *wp; 16745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char c; 16755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int depth = 1; /* we are just past the initial [ */ 16765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(ws, wp, 32, ATEMP); 16785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 16805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc(); 16815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xcheck(ws, wp); 16825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = c; 16835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') 16845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth++; 16855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ']') 16865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth--; 16875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (depth > 0 && c && c != '\n'); 16885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *wp++ = '\0'; 16905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *strp = Xclose(ws, wp); 16915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (depth == 0 ? 1 : 0); 16935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Unget a char: handles case when we are already at the start of the buffer */ 16965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * 16975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruungetsc(int c) 16985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 16995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (backslash_skip) 17005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip--; 17015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Don't unget eof... */ 17025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->str == null && c == '\0') 17035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (source->str); 17045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (source->str > source->start) 17055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source->str--; 17065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 17075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *s; 17085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = pushs(SREREAD, source->areap); 17105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->ugbuf[0] = c; s->ugbuf[1] = '\0'; 17115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->start = s->str = s->ugbuf; 17125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->next = source; 17135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = s; 17145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (source->str); 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) 17265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (getsc_()); 17275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (backslash_skip == 1) { 17295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 2; 17305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (getsc_()); 17315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 0; 17345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (1) { 17365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = getsc_(); 17375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '\\') { 17385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((c2 = getsc_()) == '\n') 17395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* ignore the \newline; get the next char... */ 17405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 17415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c2); 17425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru backslash_skip = 1; 17435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (c); 17455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 17465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Lex_state * 17495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupush_state_(State_info *si, Lex_state *old_end) 17505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *news = alloc(STATE_BSIZE * sizeof(Lex_state), ATEMP); 17525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news[0].ls_info.base = old_end; 17545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru si->base = &news[0]; 17555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru si->end = &news[STATE_BSIZE]; 17565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (&news[1]); 17575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Lex_state * 17605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupop_state_(State_info *si, Lex_state *old_end) 17615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Lex_state *old_base = si->base; 17635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru si->base = old_end->ls_info.base - STATE_BSIZE; 17655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru si->end = old_end->ls_info.base; 17665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(old_base, ATEMP); 17685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (si->base + STATE_BSIZE - 1); 17705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 17735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_get(void) 17745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (getsc()); 17765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 17775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 17785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 17795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querus_put(int c) 17805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 17815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ungetsc(c); 17825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1783