Date: Sat, 13 Mar 2010 20:43:11 +0000 (UTC) From: Jilles Tjoelker <jilles@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r205130 - head/bin/sh Message-ID: <201003132043.o2DKhBMu028182@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jilles Date: Sat Mar 13 20:43:11 2010 New Revision: 205130 URL: http://svn.freebsd.org/changeset/base/205130 Log: sh: Fix longjmp clobber warnings in parser.c. Make parsebackq a function instead of an emulated nested function. This puts the setjmp usage in a smaller function where it is easier to avoid bad optimizations. Modified: head/bin/sh/parser.c Modified: head/bin/sh/parser.c ============================================================================== --- head/bin/sh/parser.c Sat Mar 13 19:30:29 2010 (r205129) +++ head/bin/sh/parser.c Sat Mar 13 20:43:11 2010 (r205130) @@ -863,6 +863,164 @@ breakloop: } +/* + * Called to parse command substitutions. + */ + +STATIC char * +parsebackq(char *out, struct nodelist **pbqlist, + int oldstyle, int dblquote, int quoted) +{ + struct nodelist **nlpp; + union node *n; + char *volatile str; + struct jmploc jmploc; + struct jmploc *const savehandler = handler; + int savelen; + int saveprompt; + const int bq_startlinno = plinno; + char *volatile ostr = NULL; + struct parsefile *const savetopfile = getcurrentfile(); + + str = NULL; + if (setjmp(jmploc.loc)) { + popfilesupto(savetopfile); + if (str) + ckfree(str); + if (ostr) + ckfree(ostr); + handler = savehandler; + if (exception == EXERROR) { + startlinno = bq_startlinno; + synerror("Error in command substitution"); + } + longjmp(handler->loc, 1); + } + INTOFF; + savelen = out - stackblock(); + if (savelen > 0) { + 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. */ + char *oout; + int c; + int olen; + + + STARTSTACKSTR(oout); + for (;;) { + if (needprompt) { + setprompt(2); + needprompt = 0; + } + switch (c = pgetc()) { + case '`': + goto done; + + case '\\': + if ((c = 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 (c != '\\' && c != '`' && c != '$' + && (!dblquote || c != '"')) + STPUTC('\\', oout); + break; + + case '\n': + plinno++; + needprompt = doprompt; + break; + + case PEOF: + startlinno = plinno; + synerror("EOF in backquote substitution"); + break; + + default: + break; + } + STPUTC(c, oout); + } +done: + STPUTC('\0', oout); + olen = oout - stackblock(); + INTOFF; + ostr = ckmalloc(olen); + memcpy(ostr, stackblock(), olen); + setinputstring(ostr, 1); + INTON; + } + nlpp = pbqlist; + while (*nlpp) + nlpp = &(*nlpp)->next; + *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); + (*nlpp)->next = NULL; + + if (oldstyle) { + saveprompt = doprompt; + doprompt = 0; + } + + n = list(0); + + if (oldstyle) + doprompt = saveprompt; + else { + if (readtoken() != TRP) + 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(out); + if (str) { + memcpy(out, str, savelen); + STADJUST(savelen, out); + INTOFF; + ckfree(str); + str = NULL; + INTON; + } + if (ostr) { + INTOFF; + ckfree(ostr); + ostr = NULL; + INTON; + } + handler = savehandler; + if (quoted) + USTPUTC(CTLBACKQ | CTLQUOTE, out); + else + USTPUTC(CTLBACKQ, out); + return out; +} + /* * If eofmark is NULL, read a word or a redirection symbol. If eofmark @@ -879,8 +1037,6 @@ breakloop: #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:;} STATIC int @@ -896,7 +1052,6 @@ readtoken1(int firstc, char const *synta int varnest; /* levels of variables expansion */ int arinest; /* levels of arithmetic expansion */ int parenlevel; /* levels of parens in arithmetic */ - int oldstyle; char const *prevsyntax; /* syntax before arithmetic */ int synentry; @@ -1029,7 +1184,8 @@ readtoken1(int firstc, char const *synta } break; case CBQUOTE: /* '`' */ - PARSEBACKQOLD(); + out = parsebackq(out, &bqlist, 1, dblquote, + arinest || dblquote); break; case CEOF: goto endword; /* exit outer loop */ @@ -1189,7 +1345,8 @@ parsesub: { PARSEARITH(); } else { pungetc(); - PARSEBACKQNEW(); + out = parsebackq(out, &bqlist, 0, dblquote, + arinest || dblquote); } } else { USTPUTC(CTLVAR, out); @@ -1296,167 +1453,6 @@ parsesub: { /* - * 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; - union node *n; - char *volatile str; - struct jmploc jmploc; - struct jmploc *const savehandler = handler; - int savelen; - int saveprompt; - const int bq_startlinno = plinno; - char *volatile ostr = NULL; - struct parsefile *const savetopfile = getcurrentfile(); - - str = NULL; - if (setjmp(jmploc.loc)) { - popfilesupto(savetopfile); - if (str) - ckfree(str); - if (ostr) - ckfree(ostr); - handler = savehandler; - if (exception == EXERROR) { - startlinno = bq_startlinno; - synerror("Error in command substitution"); - } - longjmp(handler->loc, 1); - } - INTOFF; - savelen = out - stackblock(); - if (savelen > 0) { - 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. */ - char *oout; - int c; - int olen; - - - STARTSTACKSTR(oout); - for (;;) { - if (needprompt) { - setprompt(2); - needprompt = 0; - } - switch (c = pgetc()) { - case '`': - goto done; - - case '\\': - if ((c = 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 (c != '\\' && c != '`' && c != '$' - && (!dblquote || c != '"')) - STPUTC('\\', oout); - break; - - case '\n': - plinno++; - needprompt = doprompt; - break; - - case PEOF: - startlinno = plinno; - synerror("EOF in backquote substitution"); - break; - - default: - break; - } - STPUTC(c, oout); - } -done: - STPUTC('\0', oout); - olen = oout - stackblock(); - INTOFF; - ostr = ckmalloc(olen); - memcpy(ostr, stackblock(), olen); - setinputstring(ostr, 1); - INTON; - } - nlpp = &bqlist; - while (*nlpp) - nlpp = &(*nlpp)->next; - *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); - (*nlpp)->next = NULL; - - if (oldstyle) { - saveprompt = doprompt; - doprompt = 0; - } - - n = list(0); - - if (oldstyle) - doprompt = saveprompt; - else { - if (readtoken() != TRP) - 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(out); - if (str) { - memcpy(out, str, savelen); - STADJUST(savelen, out); - INTOFF; - ckfree(str); - str = NULL; - INTON; - } - if (ostr) { - INTOFF; - ckfree(ostr); - ostr = NULL; - INTON; - } - handler = savehandler; - if (arinest || dblquote) - USTPUTC(CTLBACKQ | CTLQUOTE, out); - else - USTPUTC(CTLBACKQ, out); - if (oldstyle) - goto parsebackq_oldreturn; - else - goto parsebackq_newreturn; -} - -/* * Parse an arithmetic expansion (indicate start of one and set state) */ parsearith: {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003132043.o2DKhBMu028182>