| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: parser.c,v 1.69 2008/08/23 10:05:52 christos Exp $ */ | | 1 | /* $NetBSD: parser.c,v 1.70 2008/11/05 22:04:43 christos Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1991, 1993 | | 4 | * Copyright (c) 1991, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Kenneth Almquist. | | 8 | * Kenneth Almquist. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
32 | * SUCH DAMAGE. | | 32 | * SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #include <sys/cdefs.h> | | 35 | #include <sys/cdefs.h> |
36 | #ifndef lint | | 36 | #ifndef lint |
37 | #if 0 | | 37 | #if 0 |
38 | static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; | | 38 | static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; |
39 | #else | | 39 | #else |
40 | __RCSID("$NetBSD: parser.c,v 1.69 2008/08/23 10:05:52 christos Exp $"); | | 40 | __RCSID("$NetBSD: parser.c,v 1.70 2008/11/05 22:04:43 christos Exp $"); |
41 | #endif | | 41 | #endif |
42 | #endif /* not lint */ | | 42 | #endif /* not lint */ |
43 | | | 43 | |
44 | #include <stdlib.h> | | 44 | #include <stdlib.h> |
45 | | | 45 | |
46 | #include "shell.h" | | 46 | #include "shell.h" |
47 | #include "parser.h" | | 47 | #include "parser.h" |
48 | #include "nodes.h" | | 48 | #include "nodes.h" |
49 | #include "expand.h" /* defines rmescapes() */ | | 49 | #include "expand.h" /* defines rmescapes() */ |
50 | #include "eval.h" /* defines commandname */ | | 50 | #include "eval.h" /* defines commandname */ |
51 | #include "redir.h" /* defines copyfd() */ | | 51 | #include "redir.h" /* defines copyfd() */ |
52 | #include "syntax.h" | | 52 | #include "syntax.h" |
53 | #include "options.h" | | 53 | #include "options.h" |
| @@ -1384,26 +1384,27 @@ parsebackq: { | | | @@ -1384,26 +1384,27 @@ parsebackq: { |
1384 | str = ckmalloc(savelen); | | 1384 | str = ckmalloc(savelen); |
1385 | memcpy(str, stackblock(), savelen); | | 1385 | memcpy(str, stackblock(), savelen); |
1386 | } | | 1386 | } |
1387 | savehandler = handler; | | 1387 | savehandler = handler; |
1388 | handler = &jmploc; | | 1388 | handler = &jmploc; |
1389 | INTON; | | 1389 | INTON; |
1390 | if (oldstyle) { | | 1390 | if (oldstyle) { |
1391 | /* We must read until the closing backquote, giving special | | 1391 | /* We must read until the closing backquote, giving special |
1392 | treatment to some slashes, and then push the string and | | 1392 | treatment to some slashes, and then push the string and |
1393 | reread it as input, interpreting it normally. */ | | 1393 | reread it as input, interpreting it normally. */ |
1394 | char *pout; | | 1394 | char *pout; |
1395 | int pc; | | 1395 | int pc; |
1396 | int psavelen; | | 1396 | int psavelen; |
| | | 1397 | int nparen = 0; |
1397 | char *pstr; | | 1398 | char *pstr; |
1398 | | | 1399 | |
1399 | | | 1400 | |
1400 | STARTSTACKSTR(pout); | | 1401 | STARTSTACKSTR(pout); |
1401 | for (;;) { | | 1402 | for (;;) { |
1402 | if (needprompt) { | | 1403 | if (needprompt) { |
1403 | setprompt(2); | | 1404 | setprompt(2); |
1404 | needprompt = 0; | | 1405 | needprompt = 0; |
1405 | } | | 1406 | } |
1406 | switch (pc = pgetc()) { | | 1407 | switch (pc = pgetc()) { |
1407 | case '`': | | 1408 | case '`': |
1408 | goto done; | | 1409 | goto done; |
1409 | | | 1410 | |
| @@ -1416,43 +1417,53 @@ parsebackq: { | | | @@ -1416,43 +1417,53 @@ parsebackq: { |
1416 | setprompt(0); | | 1417 | setprompt(0); |
1417 | /* | | 1418 | /* |
1418 | * If eating a newline, avoid putting | | 1419 | * If eating a newline, avoid putting |
1419 | * the newline into the new character | | 1420 | * the newline into the new character |
1420 | * stream (via the STPUTC after the | | 1421 | * stream (via the STPUTC after the |
1421 | * switch). | | 1422 | * switch). |
1422 | */ | | 1423 | */ |
1423 | continue; | | 1424 | continue; |
1424 | } | | 1425 | } |
1425 | if (pc != '\\' && pc != '`' && pc != '$' | | 1426 | if (pc != '\\' && pc != '`' && pc != '$' |
1426 | && (!ISDBLQUOTE() || pc != '"')) | | 1427 | && (!ISDBLQUOTE() || pc != '"')) |
1427 | STPUTC('\\', pout); | | 1428 | STPUTC('\\', pout); |
1428 | break; | | 1429 | break; |
| | | 1430 | case '(': |
| | | 1431 | nparen++; |
| | | 1432 | break; |
| | | 1433 | |
| | | 1434 | case ')': |
| | | 1435 | if (--nparen < 0) |
| | | 1436 | synerror("`)' unexpected"); |
| | | 1437 | break; |
1429 | | | 1438 | |
1430 | case '\n': | | 1439 | case '\n': |
1431 | plinno++; | | 1440 | plinno++; |
1432 | needprompt = doprompt; | | 1441 | needprompt = doprompt; |
1433 | break; | | 1442 | break; |
1434 | | | 1443 | |
1435 | case PEOF: | | 1444 | case PEOF: |
1436 | startlinno = plinno; | | 1445 | startlinno = plinno; |
1437 | synerror("EOF in backquote substitution"); | | 1446 | synerror("EOF in backquote substitution"); |
1438 | break; | | 1447 | break; |
1439 | | | 1448 | |
1440 | default: | | 1449 | default: |
1441 | break; | | 1450 | break; |
1442 | } | | 1451 | } |
1443 | STPUTC(pc, pout); | | 1452 | STPUTC(pc, pout); |
1444 | } | | 1453 | } |
1445 | done: | | 1454 | done: |
| | | 1455 | if (nparen) |
| | | 1456 | synerror("Missing `)'"); |
1446 | STPUTC('\0', pout); | | 1457 | STPUTC('\0', pout); |
1447 | psavelen = pout - stackblock(); | | 1458 | psavelen = pout - stackblock(); |
1448 | if (psavelen > 0) { | | 1459 | if (psavelen > 0) { |
1449 | pstr = grabstackstr(pout); | | 1460 | pstr = grabstackstr(pout); |
1450 | setinputstring(pstr, 1); | | 1461 | setinputstring(pstr, 1); |
1451 | } | | 1462 | } |
1452 | } | | 1463 | } |
1453 | nlpp = &bqlist; | | 1464 | nlpp = &bqlist; |
1454 | while (*nlpp) | | 1465 | while (*nlpp) |
1455 | nlpp = &(*nlpp)->next; | | 1466 | nlpp = &(*nlpp)->next; |
1456 | *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); | | 1467 | *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); |
1457 | (*nlpp)->next = NULL; | | 1468 | (*nlpp)->next = NULL; |
1458 | parsebackquote = oldstyle; | | 1469 | parsebackquote = oldstyle; |