Sun Nov 14 19:49:17 2010 UTC ()
revert previous. breaks other stuff.


(christos)
diff -r1.75 -r1.76 src/bin/sh/parser.c

cvs diff -r1.75 -r1.76 src/bin/sh/parser.c (expand / switch to unified diff)

--- src/bin/sh/parser.c 2010/11/14 19:43:38 1.75
+++ src/bin/sh/parser.c 2010/11/14 19:49:16 1.76
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: parser.c,v 1.75 2010/11/14 19:43:38 christos Exp $ */ 1/* $NetBSD: parser.c,v 1.76 2010/11/14 19:49:16 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
38static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; 38static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95";
39#else 39#else
40__RCSID("$NetBSD: parser.c,v 1.75 2010/11/14 19:43:38 christos Exp $"); 40__RCSID("$NetBSD: parser.c,v 1.76 2010/11/14 19:49:16 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"
@@ -886,77 +886,69 @@ breakloop: @@ -886,77 +886,69 @@ breakloop:
886#define PARSEREDIR() {goto parseredir; parseredir_return:;} 886#define PARSEREDIR() {goto parseredir; parseredir_return:;}
887#define PARSESUB() {goto parsesub; parsesub_return:;} 887#define PARSESUB() {goto parsesub; parsesub_return:;}
888#define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;} 888#define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;}
889#define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;} 889#define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;}
890#define PARSEARITH() {goto parsearith; parsearith_return:;} 890#define PARSEARITH() {goto parsearith; parsearith_return:;}
891 891
892/* 892/*
893 * Keep track of nested doublequotes in dblquote and doublequotep. 893 * Keep track of nested doublequotes in dblquote and doublequotep.
894 * We use dblquote for the first 32 levels, and we expand to a malloc'ed 894 * We use dblquote for the first 32 levels, and we expand to a malloc'ed
895 * region for levels above that. Usually we never need to malloc. 895 * region for levels above that. Usually we never need to malloc.
896 * This code assumes that an int is 32 bits. We don't use uint32_t, 896 * This code assumes that an int is 32 bits. We don't use uint32_t,
897 * because the rest of the code does not. 897 * because the rest of the code does not.
898 */ 898 */
899#define VN (varnest - insub) 899#define ISDBLQUOTE() ((varnest < 32) ? (dblquote & (1 << varnest)) : \
900#define ISDBLQUOTE() ((VN < 32) ? (dblquote & (1 << VN)) : \ 900 (dblquotep[(varnest / 32) - 1] & (1 << (varnest % 32))))
901 (dblquotep[(VN / 32) - 1] & (1 << (VN % 32)))) 
902 901
903#define SETDBLQUOTE() \ 902#define SETDBLQUOTE() \
904 do { \ 903 if (varnest < 32) \
905 TRACE(("setdblquote %d\n", varnest)); \ 904 dblquote |= (1 << varnest); \
906 if (varnest < 32) \ 905 else \
907 dblquote |= (1 << varnest); \ 906 dblquotep[(varnest / 32) - 1] |= (1 << (varnest % 32))
908 else \ 
909 dblquotep[(varnest / 32) - 1] |= (1 << (varnest % 32));\ 
910 } while (/*CONSTCOND*/0) 
911 907
912#define CLRDBLQUOTE() \ 908#define CLRDBLQUOTE() \
913 do { \ 909 if (varnest < 32) \
914 TRACE(("clrdblquote %d\n", varnest)); \ 910 dblquote &= ~(1 << varnest); \
915 if (varnest < 32) \ 911 else \
916 dblquote &= ~(1 << varnest); \ 912 dblquotep[(varnest / 32) - 1] &= ~(1 << (varnest % 32))
917 else \ 
918 dblquotep[(varnest / 32) - 1] &= ~(1 << (varnest % 32)); \ 
919 } while (/*CONSTCOND*/0) 
920 913
921STATIC int 914STATIC int
922readtoken1(int firstc, char const *syn, char *eofmark, int striptabs) 915readtoken1(int firstc, char const *syn, char *eofmark, int striptabs)
923{ 916{
924 char const * volatile syntax = syn; 917 char const * volatile syntax = syn;
925 int c = firstc; 918 int c = firstc;
926 char * volatile out; 919 char * volatile out;
927 int len; 920 int len;
928 char line[EOFMARKLEN + 1]; 921 char line[EOFMARKLEN + 1];
929 struct nodelist *bqlist; 922 struct nodelist *bqlist;
930 volatile int quotef; 923 volatile int quotef;
931 int * volatile dblquotep = NULL; 924 int * volatile dblquotep = NULL;
932 volatile size_t maxnest = 32; 925 volatile size_t maxnest = 32;
933 volatile int dblquote; 926 volatile int dblquote;
934 volatile size_t varnest; /* levels of variables expansion */ 927 volatile size_t varnest; /* levels of variables expansion */
935 volatile int arinest; /* levels of arithmetic expansion */ 928 volatile int arinest; /* levels of arithmetic expansion */
936 volatile int parenlevel; /* levels of parens in arithmetic */ 929 volatile int parenlevel; /* levels of parens in arithmetic */
937 volatile int oldstyle; 930 volatile int oldstyle;
938 volatile int insub; 
939 char const * volatile prevsyntax; /* syntax before arithmetic */ 931 char const * volatile prevsyntax; /* syntax before arithmetic */
940#ifdef __GNUC__ 932#ifdef __GNUC__
941 prevsyntax = NULL; /* XXX gcc4 */ 933 prevsyntax = NULL; /* XXX gcc4 */
942#endif 934#endif
943 935
944 startlinno = plinno; 936 startlinno = plinno;
945 dblquote = 0; 937 dblquote = 0;
946 varnest = 0; 938 varnest = 0;
947 insub = 0; 939 if (syntax == DQSYNTAX) {
948 if (syntax == DQSYNTAX) 
949 SETDBLQUOTE(); 940 SETDBLQUOTE();
 941 }
950 quotef = 0; 942 quotef = 0;
951 bqlist = NULL; 943 bqlist = NULL;
952 arinest = 0; 944 arinest = 0;
953 parenlevel = 0; 945 parenlevel = 0;
954 946
955 STARTSTACKSTR(out); 947 STARTSTACKSTR(out);
956 loop: { /* for each line, until end of word */ 948 loop: { /* for each line, until end of word */
957#if ATTY 949#if ATTY
958 if (c == '\034' && doprompt 950 if (c == '\034' && doprompt
959 && attyset() && ! equal(termval(), "emacs")) { 951 && attyset() && ! equal(termval(), "emacs")) {
960 attyline(); 952 attyline();
961 if (syntax == BASESYNTAX) 953 if (syntax == BASESYNTAX)
962 return readtoken(); 954 return readtoken();
@@ -992,34 +984,30 @@ readtoken1(int firstc, char const *syn,  @@ -992,34 +984,30 @@ readtoken1(int firstc, char const *syn,
992 if (c == PEOF) { 984 if (c == PEOF) {
993 USTPUTC('\\', out); 985 USTPUTC('\\', out);
994 pungetc(); 986 pungetc();
995 break; 987 break;
996 } 988 }
997 if (c == '\n') { 989 if (c == '\n') {
998 if (doprompt) 990 if (doprompt)
999 setprompt(2); 991 setprompt(2);
1000 else 992 else
1001 setprompt(0); 993 setprompt(0);
1002 break; 994 break;
1003 } 995 }
1004 quotef = 1; 996 quotef = 1;
1005 TRACE(("varnest=%d doubleq=%d c=%c\n", 
1006 varnest, ISDBLQUOTE(), c)); 
1007 if (ISDBLQUOTE() && c != '\\' && 997 if (ISDBLQUOTE() && c != '\\' &&
1008 c != '`' && c != '$' && 998 c != '`' && c != '$' &&
1009 (c != '"' || eofmark != NULL)) { 999 (c != '"' || eofmark != NULL))
1010 USTPUTC(CTLESC, out); 1000 USTPUTC('\\', out);
1011 USTPUTC(CTLESC, out); 
1012 } 
1013 if (SQSYNTAX[c] == CCTL) 1001 if (SQSYNTAX[c] == CCTL)
1014 USTPUTC(CTLESC, out); 1002 USTPUTC(CTLESC, out);
1015 else if (eofmark == NULL) { 1003 else if (eofmark == NULL) {
1016 USTPUTC(CTLQUOTEMARK, out); 1004 USTPUTC(CTLQUOTEMARK, out);
1017 USTPUTC(c, out); 1005 USTPUTC(c, out);
1018 if (varnest != 0) 1006 if (varnest != 0)
1019 USTPUTC(CTLQUOTEEND, out); 1007 USTPUTC(CTLQUOTEEND, out);
1020 break; 1008 break;
1021 } 1009 }
1022 USTPUTC(c, out); 1010 USTPUTC(c, out);
1023 break; 1011 break;
1024 case CSQUOTE: 1012 case CSQUOTE:
1025 if (syntax != SQSYNTAX) { 1013 if (syntax != SQSYNTAX) {
@@ -1070,27 +1058,26 @@ readtoken1(int firstc, char const *syn,  @@ -1070,27 +1058,26 @@ readtoken1(int firstc, char const *syn,
1070 USTPUTC(CTLQUOTEEND, out); 1058 USTPUTC(CTLQUOTEEND, out);
1071 syntax = BASESYNTAX; 1059 syntax = BASESYNTAX;
1072 CLRDBLQUOTE(); 1060 CLRDBLQUOTE();
1073 } else { 1061 } else {
1074 syntax = DQSYNTAX; 1062 syntax = DQSYNTAX;
1075 SETDBLQUOTE(); 1063 SETDBLQUOTE();
1076 USTPUTC(CTLQUOTEMARK, out); 1064 USTPUTC(CTLQUOTEMARK, out);
1077 } 1065 }
1078 break; 1066 break;
1079 case CVAR: /* '$' */ 1067 case CVAR: /* '$' */
1080 PARSESUB(); /* parse substitution */ 1068 PARSESUB(); /* parse substitution */
1081 break; 1069 break;
1082 case CENDVAR: /* CLOSEBRACE */ 1070 case CENDVAR: /* CLOSEBRACE */
1083 insub = 0; 
1084 if (varnest > 0 && !ISDBLQUOTE()) { 1071 if (varnest > 0 && !ISDBLQUOTE()) {
1085 varnest--; 1072 varnest--;
1086 USTPUTC(CTLENDVAR, out); 1073 USTPUTC(CTLENDVAR, out);
1087 } else { 1074 } else {
1088 USTPUTC(c, out); 1075 USTPUTC(c, out);
1089 } 1076 }
1090 break; 1077 break;
1091 case CLP: /* '(' in arithmetic */ 1078 case CLP: /* '(' in arithmetic */
1092 parenlevel++; 1079 parenlevel++;
1093 USTPUTC(c, out); 1080 USTPUTC(c, out);
1094 break; 1081 break;
1095 case CRP: /* ')' in arithmetic */ 1082 case CRP: /* ')' in arithmetic */
1096 if (parenlevel > 0) { 1083 if (parenlevel > 0) {
@@ -1343,29 +1330,27 @@ badsub: synerror("Bad substitution"); @@ -1343,29 +1330,27 @@ badsub: synerror("Bad substitution");
1343 subtype++; 1330 subtype++;
1344 else 1331 else
1345 pungetc(); 1332 pungetc();
1346 break; 1333 break;
1347 } 1334 }
1348 } 1335 }
1349 } else { 1336 } else {
1350 pungetc(); 1337 pungetc();
1351 } 1338 }
1352 if (ISDBLQUOTE() || arinest) 1339 if (ISDBLQUOTE() || arinest)
1353 flags |= VSQUOTE; 1340 flags |= VSQUOTE;
1354 *(stackblock() + typeloc) = subtype | flags; 1341 *(stackblock() + typeloc) = subtype | flags;
1355 if (subtype != VSNORMAL) { 1342 if (subtype != VSNORMAL) {
1356 TRACE(("varnest=%d subtype=%d\n", varnest, subtype)); 
1357 varnest++; 1343 varnest++;
1358 insub = 1; 
1359 if (varnest >= maxnest) { 1344 if (varnest >= maxnest) {
1360 dblquotep = ckrealloc(dblquotep, maxnest / 8); 1345 dblquotep = ckrealloc(dblquotep, maxnest / 8);
1361 dblquotep[(maxnest / 32) - 1] = 0; 1346 dblquotep[(maxnest / 32) - 1] = 0;
1362 maxnest += 32; 1347 maxnest += 32;
1363 } 1348 }
1364 } 1349 }
1365 } 1350 }
1366 goto parsesub_return; 1351 goto parsesub_return;
1367} 1352}
1368 1353
1369 1354
1370/* 1355/*
1371 * Called to parse command substitutions. Newstyle is set if the command 1356 * Called to parse command substitutions. Newstyle is set if the command