Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/bin/sh Move the command substitution "internal subroutine" p...
details: https://anonhg.NetBSD.org/src/rev/1fa1ec50e252
branches: trunk
changeset: 344303:1fa1ec50e252
user: christos <christos%NetBSD.org@localhost>
date: Sun Mar 20 22:56:39 2016 +0000
description:
Move the command substitution "internal subroutine" part of
readtoken1() into a real function of its own (inspired by a
similar change made by FreeBSD - the other internal routines
they moved out are expected to move out here as well soon.)
This change helps avoid gcc 5.3 demanded (not required!) volatile
noise which would slow down parsing. (from kre)
diffstat:
bin/sh/parser.c | 358 ++++++++++++++++++++++++++++----------------------------
1 files changed, 179 insertions(+), 179 deletions(-)
diffs (truncated from 443 to 300 lines):
diff -r d186857eb9e8 -r 1fa1ec50e252 bin/sh/parser.c
--- a/bin/sh/parser.c Sun Mar 20 22:27:44 2016 +0000
+++ b/bin/sh/parser.c Sun Mar 20 22:56:39 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: parser.c,v 1.105 2016/03/18 18:07:28 christos Exp $ */
+/* $NetBSD: parser.c,v 1.106 2016/03/20 22:56:39 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
#else
-__RCSID("$NetBSD: parser.c,v 1.105 2016/03/18 18:07:28 christos Exp $");
+__RCSID("$NetBSD: parser.c,v 1.106 2016/03/20 22:56:39 christos Exp $");
#endif
#endif /* not lint */
@@ -948,7 +948,7 @@
* quoted is special - we need to know 2 things ... are we inside "..."
* (even if inherited from some previous nesting level) and was there
* an opening '"' at this level (so the next will be closing).
- * "..." can span nexting levels, but cannot be opened in one and
+ * "..." can span nesting levels, but cannot be opened in one and
* closed in a different one.
* To handle this, "quoted" has two fields, the bottom 4 (really 2)
* bits are 0, 1, or 2, for un, single, and double quoted (single quoted
@@ -964,15 +964,14 @@
unsigned short ts_quoted; /* 1 -> single, 2 -> double */
};
-#define NQ 0x00
-#define SQ 0x01
-#define DQ 0x02
-#define QF 0x0F
-#define QS 0x10
+#define NQ 0x00 /* Unquoted */
+#define SQ 0x01 /* Single Quotes */
+#define DQ 0x02 /* Double Quotes (or equivalent) */
+#define QF 0x0F /* Mask to extract previous values */
+#define QS 0x10 /* Quoting started at this level in stack */
#define LEVELS_PER_BLOCK 8
#define VSS struct statestack
-#define VVSS volatile VSS
struct statestack {
VSS *prev; /* previous block in list */
@@ -1034,7 +1033,7 @@
stack = ss->prev;
if (stack == NULL)
return ss;
- ckfree(__UNVOLATILE(ss));
+ ckfree(ss);
}
--stack->cur;
return stack;
@@ -1052,8 +1051,6 @@
#define CHECKEND() {goto checkend; checkend_return:;}
#define PARSEREDIR() {goto parseredir; parseredir_return:;}
#define PARSESUB() {goto parsesub; parsesub_return:;}
-#define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
-#define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
#define PARSEARITH() {goto parsearith; parsearith_return:;}
/*
@@ -1080,8 +1077,171 @@
#define varnest (currentstate(stack)->ts_varnest)
#define arinest (currentstate(stack)->ts_arinest)
#define quoted (currentstate(stack)->ts_quoted)
-#define TS_PUSH() (vstack = stack = bump_state_level(stack))
-#define TS_POP() (vstack = stack = drop_state_level(stack))
+#define TS_PUSH() (stack = bump_state_level(stack))
+#define TS_POP() (stack = drop_state_level(stack))
+
+/*
+ * Called to parse command substitutions. oldstyle is true if the command
+ * is enclosed inside `` (otherwise it was enclosed in "$( )")
+ *
+ * Internally nlpp is a pointer to the head of the linked
+ * list of commands (passed by reference), and savelen is the number of
+ * characters on the top of the stack which must be preserved.
+ */
+static char *
+parsebackq(VSS *const stack, const char *in,
+ struct nodelist **const pbqlist, const int oldstyle)
+{
+ struct nodelist **nlpp;
+ int savepbq;
+ union node *n;
+ const char *out;
+ char *str = NULL;
+ char *pout;
+ char *volatile sstr = str;
+ struct jmploc jmploc;
+ struct jmploc *const savehandler = handler;
+ int savelen;
+ int saveprompt;
+
+ savepbq = parsebackquote;
+ if (setjmp(jmploc.loc)) {
+ if (sstr)
+ ckfree(__UNVOLATILE(sstr));
+ cleanup_state_stack(stack);
+ parsebackquote = 0;
+ handler = savehandler;
+ longjmp(handler->loc, 1);
+ }
+ INTOFF;
+ out = in;
+ sstr = str = NULL;
+ savelen = out - stackblock();
+ if (savelen > 0) {
+ sstr = str = ckmalloc(savelen);
+ memcpy(str, stackblock(), savelen);
+ }
+ handler = &jmploc;
+ INTON;
+ if (oldstyle) {
+ /* We must read until the closing backquote, giving special
+ treatment to some slashes, and then push the string and
+ reread it as input, interpreting it normally. */
+ int pc;
+ int psavelen;
+ char *pstr;
+
+ /*
+ * Because the entire `...` is read here, we don't
+ * need to bother the state stack. That will be used
+ * (as appropriate) when the processed string is re-read.
+ */
+ STARTSTACKSTR(pout);
+ for (;;) {
+ if (needprompt) {
+ setprompt(2);
+ needprompt = 0;
+ }
+ switch (pc = pgetc()) {
+ case '`':
+ goto done;
+
+ case '\\':
+ if ((pc = pgetc()) == '\n') {
+ plinno++;
+ if (doprompt)
+ setprompt(2);
+ else
+ setprompt(0);
+ /*
+ * If eating a newline, avoid putting
+ * the newline into the new character
+ * stream (via the STPUTC after the
+ * switch).
+ */
+ continue;
+ }
+ if (pc != '\\' && pc != '`' && pc != '$'
+ && (!ISDBLQUOTE() || pc != '"'))
+ STPUTC('\\', pout);
+ break;
+
+ case '\n':
+ plinno++;
+ needprompt = doprompt;
+ break;
+
+ case PEOF:
+ startlinno = plinno;
+ synerror("EOF in backquote substitution");
+ break;
+
+ default:
+ break;
+ }
+ STPUTC(pc, pout);
+ }
+done:
+ STPUTC('\0', pout);
+ psavelen = pout - stackblock();
+ if (psavelen > 0) {
+ pstr = grabstackstr(pout);
+ setinputstring(pstr, 1);
+ }
+ }
+ nlpp = pbqlist;
+ while (*nlpp)
+ nlpp = &(*nlpp)->next;
+ *nlpp = stalloc(sizeof(struct nodelist));
+ (*nlpp)->next = NULL;
+ parsebackquote = oldstyle;
+
+ if (oldstyle) {
+ saveprompt = doprompt;
+ doprompt = 0;
+ } else
+ saveprompt = 0;
+
+ n = list(0, oldstyle);
+
+ if (oldstyle)
+ doprompt = saveprompt;
+ else {
+ if (readtoken() != TRP) {
+ cleanup_state_stack(stack);
+ synexpect(TRP);
+ }
+ }
+
+ (*nlpp)->n = n;
+ if (oldstyle) {
+ /*
+ * Start reading from old file again, ignoring any pushed back
+ * tokens left from the backquote parsing
+ */
+ popfile();
+ tokpushback = 0;
+ }
+ while (stackblocksize() <= savelen)
+ growstackblock();
+ STARTSTACKSTR(pout);
+ if (str) {
+ memcpy(pout, str, savelen);
+ STADJUST(savelen, pout);
+ INTOFF;
+ ckfree(str);
+ sstr = str = NULL;
+ INTON;
+ }
+ parsebackquote = savepbq;
+ handler = savehandler;
+ if (arinest || ISDBLQUOTE())
+ USTPUTC(CTLBACKQ | CTLQUOTE, pout);
+ else
+ USTPUTC(CTLBACKQ, pout);
+
+ return pout;
+}
STATIC int
readtoken1(int firstc, char const *syn, char *eofmark, int striptabs)
@@ -1091,11 +1251,9 @@
int len;
char line[EOFMARKLEN + 1];
struct nodelist *bqlist;
- volatile int quotef;
- volatile int oldstyle;
+ int quotef;
VSS static_stack;
- VSS * volatile stack = &static_stack;
- VVSS * volatile vstack = stack;
+ VSS *stack = &static_stack;
stack->prev = NULL;
stack->cur = 0;
@@ -1269,7 +1427,7 @@
}
break;
case CBQUOTE: /* '`' */
- PARSEBACKQOLD();
+ out = parsebackq(stack, out, &bqlist, 1);
break;
case CEOF:
goto endword; /* exit outer loop */
@@ -1445,7 +1603,7 @@
PARSEARITH();
} else {
pungetc();
- PARSEBACKQNEW();
+ out = parsebackq(stack, out, &bqlist, 0);
}
} else {
USTPUTC(CTLVAR, out);
@@ -1548,165 +1706,6 @@
/*
- * Called to parse command substitutions. Newstyle is set if the command
- * is enclosed inside $(...); nlpp is a pointer to the head of the linked
- * list of commands (passed by reference), and savelen is the number of
- * characters on the top of the stack which must be preserved.
- */
-
-parsebackq: {
- struct nodelist **nlpp;
- int savepbq;
- union node *n;
- char * volatile str = NULL;
- struct jmploc jmploc;
- struct jmploc *volatile savehandler = NULL;
- int savelen;
- int saveprompt;
-
- savepbq = parsebackquote;
- if (setjmp(jmploc.loc)) {
- if (str)
- ckfree(str);
- cleanup_state_stack(__UNVOLATILE(vstack));
- parsebackquote = 0;
- handler = savehandler;
- longjmp(handler->loc, 1);
Home |
Main Index |
Thread Index |
Old Index