parser.h revision 1.25
142468Speter/* $NetBSD: parser.h,v 1.25 2018/12/01 01:21:06 kre Exp $ */ 2131377Stjr 342468Speter/*- 442468Speter * Copyright (c) 1991, 1993 5131377Stjr * The Regents of the University of California. All rights reserved. 6205471Sdelphij * 7205471Sdelphij * This code is derived from software contributed to Berkeley by 842468Speter * Kenneth Almquist. 942468Speter * 1092111Sgreen * Redistribution and use in source and binary forms, with or without 1142468Speter * modification, are permitted provided that the following conditions 1292111Sgreen * are met: 1342468Speter * 1. Redistributions of source code must retain the above copyright 1492111Sgreen * notice, this list of conditions and the following disclaimer. 1542468Speter * 2. Redistributions in binary form must reproduce the above copyright 16205471Sdelphij * notice, this list of conditions and the following disclaimer in the 17205471Sdelphij * documentation and/or other materials provided with the distribution. 18205471Sdelphij * 3. Neither the name of the University nor the names of its contributors 1942468Speter * may be used to endorse or promote products derived from this software 2092111Sgreen * without specific prior written permission. 2142468Speter * 2292111Sgreen * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23205471Sdelphij * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24145474Skientzle * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2542468Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26145474Skientzle * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2742468Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28205471Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29205471Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30205471Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3192111Sgreen * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3242468Speter * SUCH DAMAGE. 33145474Skientzle * 3442468Speter * @(#)parser.h 8.3 (Berkeley) 5/4/95 35205471Sdelphij */ 36205471Sdelphij 37205471Sdelphij/* control characters in argument strings */ 38205471Sdelphij#define CTL_FIRST '\201' /* first 'special' character */ 39205471Sdelphij#define CTLESC '\201' /* escape next character */ 40205471Sdelphij#define CTLVAR '\202' /* variable defn */ 41205471Sdelphij#define CTLENDVAR '\203' 42205471Sdelphij#define CTLBACKQ '\204' 43205471Sdelphij#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */ 4442468Speter/* CTLBACKQ | CTLQUOTE == '\205' */ 4592111Sgreen#define CTLARI '\206' /* arithmetic expression */ 4642468Speter#define CTLENDARI '\207' 47237410Sdelphij#define CTLQUOTEMARK '\210' 48237410Sdelphij#define CTLQUOTEEND '\211' /* only inside ${...} */ 4942468Speter#define CTLNONL '\212' /* The \n in a deleted \ \n sequence */ 5092111Sgreen /* pure concidence that (CTLNONL & 0x7f) == '\n' */ 5142468Speter#define CTLCNL '\213' /* A $'\n' - newline not counted */ 52205471Sdelphij#define CTL_LAST '\213' /* last 'special' character */ 53205471Sdelphij 5442468Speter/* variable substitution byte (follows CTLVAR) */ 5592111Sgreen#define VSTYPE 0x0f /* type of variable substitution */ 5642468Speter#define VSNUL 0x10 /* colon--treat the empty string as unset */ 57205471Sdelphij#define VSLINENO 0x20 /* expansion of $LINENO, the line number 58205471Sdelphij follows immediately */ 59205471Sdelphij#define VSPATQ 0x40 /* ensure correct pattern quoting in ${x#pat} */ 60205471Sdelphij#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */ 6142468Speter 6292111Sgreen/* values of VSTYPE field */ 6342468Speter#define VSNORMAL 0x1 /* normal variable: $var or ${var} */ 6492111Sgreen#define VSMINUS 0x2 /* ${var-text} */ 6542468Speter#define VSPLUS 0x3 /* ${var+text} */ 6692111Sgreen#define VSQUESTION 0x4 /* ${var?message} */ 67131377Stjr#define VSASSIGN 0x5 /* ${var=text} */ 6892111Sgreen#define VSTRIMLEFT 0x6 /* ${var#pattern} */ 6992111Sgreen#define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */ 7042468Speter#define VSTRIMRIGHT 0x8 /* ${var%pattern} */ 7192111Sgreen#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */ 7242468Speter#define VSLENGTH 0xa /* ${#var} */ 73131377Stjr 7442468Speterunion node *parsecmd(int); 7592111Sgreenvoid fixredir(union node *, const char *, int); 7642468Speterint goodname(const char *); 77145474Skientzleconst char *getprompt(void *); 78145474Skientzleconst char *expandstr(char *, int); 7942468Speter 8092111Sgreenstruct HereDoc; 8142468Speterunion node; 82205471Sdelphijstruct nodelist; 8392111Sgreen 8442468Speterstruct parse_state { 8592111Sgreen int ps_noalias; /* when set, don't handle aliases */ 8692111Sgreen struct HereDoc *ps_heredoclist; /* list of here documents to read */ 87237410Sdelphij int ps_parsebackquote; /* nonzero inside backquotes */ 88237410Sdelphij int ps_doprompt; /* if set, prompt the user */ 89237410Sdelphij int ps_needprompt; /* true if interactive at line start */ 90237410Sdelphij int ps_lasttoken; /* last token read */ 9192111Sgreen int ps_tokpushback; /* last token pushed back */ 9292111Sgreen char *ps_wordtext; /* text of last word returned by readtoken */ 93131377Stjr int ps_checkkwd; /* 1 == check for kwds, 2 += eat newlines */ 9492111Sgreen struct nodelist *ps_backquotelist; /* list of cmdsubs to process */ 95145474Skientzle union node *ps_redirnode; /* node for current redirect */ 96145474Skientzle struct HereDoc *ps_heredoc; /* current heredoc << beign parsed */ 97131377Stjr int ps_quoteflag; /* set if (part) of token was quoted */ 9892111Sgreen int ps_startlinno; /* line # where last token started */ 99131377Stjr int ps_funclinno; /* line # of the current function */ 100131377Stjr int ps_elided_nl; /* count of \ \n pairs we have seen */ 101205471Sdelphij}; 102205471Sdelphij 103205471Sdelphij/* 104205471Sdelphij * The parser references the elements of struct parse_state quite 105131377Stjr * frequently - they used to be simple globals, so one memory ref 106145474Skientzle * per access, adding an indirect through global ptr would not be 10792111Sgreen * nice. The following gross hack allows most of that cost to be 10892111Sgreen * avoided, by allowing the compiler to understand that the global 109145474Skientzle * pointer is in fact constant in any function, and so its value can 110131377Stjr * be cached, rather than needing to be fetched every time in case 111145474Skientzle * some other called function has changed it. 112131377Stjr * 113205471Sdelphij * The rule to make this work is that any function that wants 114205471Sdelphij * to alter the global must restore it before it returns (and thus 115145474Skientzle * must have an error trap handler). That means that the struct 116145474Skientzle * used for the new parser state can be a local in that function's 117145474Skientzle * stack frame, it never needs to be malloc'd. 118145474Skientzle */ 119145474Skientzle 120145474Skientzleunion parse_state_p { 121145474Skientzle struct parse_state *const c_current_parser; 122145474Skientzle struct parse_state * v_current_parser; 123145474Skientzle}; 124145474Skientzle 125205471Sdelphijextern union parse_state_p psp; 126205471Sdelphij 127145474Skientzle#define current_parser (psp.c_current_parser) 128145474Skientzle 129145474Skientzle/* 130145474Skientzle * Perhaps one day emulate "static" by moving most of these definitions into 131145474Skientzle * parser.c ... (only checkkwd & tokpushback are used outside parser.c, 132131377Stjr * and only in init.c as a RESET activity) 133205471Sdelphij */ 134205471Sdelphij#define tokpushback (current_parser->ps_tokpushback) 135205471Sdelphij#define checkkwd (current_parser->ps_checkkwd) 136205471Sdelphij 137131377Stjr#define noalias (current_parser->ps_noalias) 138145474Skientzle#define heredoclist (current_parser->ps_heredoclist) 139131377Stjr#define parsebackquote (current_parser->ps_parsebackquote) 140205471Sdelphij#define doprompt (current_parser->ps_doprompt) 141205471Sdelphij#define needprompt (current_parser->ps_needprompt) 142205471Sdelphij#define lasttoken (current_parser->ps_lasttoken) 143205471Sdelphij#define wordtext (current_parser->ps_wordtext) 144205471Sdelphij#define backquotelist (current_parser->ps_backquotelist) 145131377Stjr#define redirnode (current_parser->ps_redirnode) 146145474Skientzle#define heredoc (current_parser->ps_heredoc) 147131377Stjr#define quoteflag (current_parser->ps_quoteflag) 148131377Stjr#define startlinno (current_parser->ps_startlinno) 149205471Sdelphij#define funclinno (current_parser->ps_funclinno) 150205471Sdelphij#define elided_nl (current_parser->ps_elided_nl) 151131377Stjr 152145474Skientzle/* 153131377Stjr * NEOF is returned by parsecmd when it encounters an end of file. It 154205471Sdelphij * must be distinct from NULL, so we use the address of a variable that 155205471Sdelphij * happens to be handy. 156131377Stjr */ 157205471Sdelphij#define NEOF ((union node *)&psp) 158205471Sdelphij 159131377Stjr#ifdef DEBUG 160131377Stjrextern int parsing; 161131377Stjr#endif 162131377Stjr