| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: parser.c,v 1.108 2016/03/27 14:34:46 christos Exp $ */ | | 1 | /* $NetBSD: parser.c,v 1.109 2016/03/27 14:35:30 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.108 2016/03/27 14:34:46 christos Exp $"); | | 40 | __RCSID("$NetBSD: parser.c,v 1.109 2016/03/27 14:35:30 christos Exp $"); |
41 | #endif | | 41 | #endif |
42 | #endif /* not lint */ | | 42 | #endif /* not lint */ |
43 | | | 43 | |
44 | #include <stdio.h> | | 44 | #include <stdio.h> |
45 | #include <stdlib.h> | | 45 | #include <stdlib.h> |
46 | #include <limits.h> | | 46 | #include <limits.h> |
47 | | | 47 | |
48 | #include "shell.h" | | 48 | #include "shell.h" |
49 | #include "parser.h" | | 49 | #include "parser.h" |
50 | #include "nodes.h" | | 50 | #include "nodes.h" |
51 | #include "expand.h" /* defines rmescapes() */ | | 51 | #include "expand.h" /* defines rmescapes() */ |
52 | #include "eval.h" /* defines commandname */ | | 52 | #include "eval.h" /* defines commandname */ |
53 | #include "redir.h" /* defines copyfd() */ | | 53 | #include "redir.h" /* defines copyfd() */ |
| @@ -1081,119 +1081,115 @@ cleanup_state_stack(VSS *stack) | | | @@ -1081,119 +1081,115 @@ cleanup_state_stack(VSS *stack) |
1081 | /* | | 1081 | /* |
1082 | * Called to parse command substitutions. oldstyle is true if the command | | 1082 | * Called to parse command substitutions. oldstyle is true if the command |
1083 | * is enclosed inside `` (otherwise it was enclosed in "$( )") | | 1083 | * is enclosed inside `` (otherwise it was enclosed in "$( )") |
1084 | * | | 1084 | * |
1085 | * Internally nlpp is a pointer to the head of the linked | | 1085 | * Internally nlpp is a pointer to the head of the linked |
1086 | * list of commands (passed by reference), and savelen is the number of | | 1086 | * list of commands (passed by reference), and savelen is the number of |
1087 | * characters on the top of the stack which must be preserved. | | 1087 | * characters on the top of the stack which must be preserved. |
1088 | */ | | 1088 | */ |
1089 | static char * | | 1089 | static char * |
1090 | parsebackq(VSS *const stack, char * const in, | | 1090 | parsebackq(VSS *const stack, char * const in, |
1091 | struct nodelist **const pbqlist, const int oldstyle) | | 1091 | struct nodelist **const pbqlist, const int oldstyle) |
1092 | { | | 1092 | { |
1093 | struct nodelist **nlpp; | | 1093 | struct nodelist **nlpp; |
1094 | int savepbq; | | 1094 | const int savepbq = parsebackquote; |
1095 | union node *n; | | 1095 | union node *n; |
1096 | char *out; | | 1096 | char *out; |
1097 | char *str = NULL; | | 1097 | char *str = NULL; |
1098 | char *pout; | | | |
1099 | char *volatile sstr = str; | | 1098 | char *volatile sstr = str; |
1100 | struct jmploc jmploc; | | 1099 | struct jmploc jmploc; |
1101 | struct jmploc *const savehandler = handler; | | 1100 | struct jmploc *const savehandler = handler; |
1102 | int savelen; | | 1101 | const int savelen = in - stackblock(); |
1103 | int saveprompt; | | 1102 | int saveprompt; |
1104 | | | 1103 | |
1105 | savepbq = parsebackquote; | | | |
1106 | if (setjmp(jmploc.loc)) { | | 1104 | if (setjmp(jmploc.loc)) { |
1107 | if (sstr) | | 1105 | if (sstr) |
1108 | ckfree(__UNVOLATILE(sstr)); | | 1106 | ckfree(__UNVOLATILE(sstr)); |
1109 | cleanup_state_stack(stack); | | 1107 | cleanup_state_stack(stack); |
1110 | parsebackquote = 0; | | 1108 | parsebackquote = 0; |
1111 | handler = savehandler; | | 1109 | handler = savehandler; |
1112 | longjmp(handler->loc, 1); | | 1110 | longjmp(handler->loc, 1); |
1113 | } | | 1111 | } |
1114 | INTOFF; | | 1112 | INTOFF; |
1115 | out = in; | | | |
1116 | sstr = str = NULL; | | 1113 | sstr = str = NULL; |
1117 | savelen = out - stackblock(); | | | |
1118 | if (savelen > 0) { | | 1114 | if (savelen > 0) { |
1119 | sstr = str = ckmalloc(savelen); | | 1115 | sstr = str = ckmalloc(savelen); |
1120 | memcpy(str, stackblock(), savelen); | | 1116 | memcpy(str, stackblock(), savelen); |
1121 | } | | 1117 | } |
1122 | handler = &jmploc; | | 1118 | handler = &jmploc; |
1123 | INTON; | | 1119 | INTON; |
1124 | if (oldstyle) { | | 1120 | if (oldstyle) { |
1125 | /* We must read until the closing backquote, giving special | | 1121 | /* We must read until the closing backquote, giving special |
1126 | treatment to some slashes, and then push the string and | | 1122 | treatment to some slashes, and then push the string and |
1127 | reread it as input, interpreting it normally. */ | | 1123 | reread it as input, interpreting it normally. */ |
1128 | int pc; | | 1124 | int pc; |
1129 | int psavelen; | | 1125 | int psavelen; |
1130 | char *pstr; | | 1126 | char *pstr; |
1131 | | | 1127 | |
1132 | /* | | 1128 | /* |
1133 | * Because the entire `...` is read here, we don't | | 1129 | * Because the entire `...` is read here, we don't |
1134 | * need to bother the state stack. That will be used | | 1130 | * need to bother the state stack. That will be used |
1135 | * (as appropriate) when the processed string is re-read. | | 1131 | * (as appropriate) when the processed string is re-read. |
1136 | */ | | 1132 | */ |
1137 | STARTSTACKSTR(pout); | | 1133 | STARTSTACKSTR(out); |
1138 | for (;;) { | | 1134 | for (;;) { |
1139 | if (needprompt) { | | 1135 | if (needprompt) { |
1140 | setprompt(2); | | 1136 | setprompt(2); |
1141 | needprompt = 0; | | 1137 | needprompt = 0; |
1142 | } | | 1138 | } |
1143 | switch (pc = pgetc()) { | | 1139 | switch (pc = pgetc()) { |
1144 | case '`': | | 1140 | case '`': |
1145 | goto done; | | 1141 | goto done; |
1146 | | | 1142 | |
1147 | case '\\': | | 1143 | case '\\': |
1148 | if ((pc = pgetc()) == '\n') { | | 1144 | if ((pc = pgetc()) == '\n') { |
1149 | plinno++; | | 1145 | plinno++; |
1150 | if (doprompt) | | 1146 | if (doprompt) |
1151 | setprompt(2); | | 1147 | setprompt(2); |
1152 | else | | 1148 | else |
1153 | setprompt(0); | | 1149 | setprompt(0); |
1154 | /* | | 1150 | /* |
1155 | * If eating a newline, avoid putting | | 1151 | * If eating a newline, avoid putting |
1156 | * the newline into the new character | | 1152 | * the newline into the new character |
1157 | * stream (via the STPUTC after the | | 1153 | * stream (via the STPUTC after the |
1158 | * switch). | | 1154 | * switch). |
1159 | */ | | 1155 | */ |
1160 | continue; | | 1156 | continue; |
1161 | } | | 1157 | } |
1162 | if (pc != '\\' && pc != '`' && pc != '$' | | 1158 | if (pc != '\\' && pc != '`' && pc != '$' |
1163 | && (!ISDBLQUOTE() || pc != '"')) | | 1159 | && (!ISDBLQUOTE() || pc != '"')) |
1164 | STPUTC('\\', pout); | | 1160 | STPUTC('\\', out); |
1165 | break; | | 1161 | break; |
1166 | | | 1162 | |
1167 | case '\n': | | 1163 | case '\n': |
1168 | plinno++; | | 1164 | plinno++; |
1169 | needprompt = doprompt; | | 1165 | needprompt = doprompt; |
1170 | break; | | 1166 | break; |
1171 | | | 1167 | |
1172 | case PEOF: | | 1168 | case PEOF: |
1173 | startlinno = plinno; | | 1169 | startlinno = plinno; |
1174 | synerror("EOF in backquote substitution"); | | 1170 | synerror("EOF in backquote substitution"); |
1175 | break; | | 1171 | break; |
1176 | | | 1172 | |
1177 | default: | | 1173 | default: |
1178 | break; | | 1174 | break; |
1179 | } | | 1175 | } |
1180 | STPUTC(pc, pout); | | 1176 | STPUTC(pc, out); |
1181 | } | | 1177 | } |
1182 | done: | | 1178 | done: |
1183 | STPUTC('\0', pout); | | 1179 | STPUTC('\0', out); |
1184 | psavelen = pout - stackblock(); | | 1180 | psavelen = out - stackblock(); |
1185 | if (psavelen > 0) { | | 1181 | if (psavelen > 0) { |
1186 | pstr = grabstackstr(pout); | | 1182 | pstr = grabstackstr(out); |
1187 | setinputstring(pstr, 1); | | 1183 | setinputstring(pstr, 1); |
1188 | } | | 1184 | } |
1189 | } | | 1185 | } |
1190 | nlpp = pbqlist; | | 1186 | nlpp = pbqlist; |
1191 | while (*nlpp) | | 1187 | while (*nlpp) |
1192 | nlpp = &(*nlpp)->next; | | 1188 | nlpp = &(*nlpp)->next; |
1193 | *nlpp = stalloc(sizeof(struct nodelist)); | | 1189 | *nlpp = stalloc(sizeof(struct nodelist)); |
1194 | (*nlpp)->next = NULL; | | 1190 | (*nlpp)->next = NULL; |
1195 | parsebackquote = oldstyle; | | 1191 | parsebackquote = oldstyle; |
1196 | | | 1192 | |
1197 | if (oldstyle) { | | 1193 | if (oldstyle) { |
1198 | saveprompt = doprompt; | | 1194 | saveprompt = doprompt; |
1199 | doprompt = 0; | | 1195 | doprompt = 0; |
| @@ -1210,45 +1206,46 @@ done: | | | @@ -1210,45 +1206,46 @@ done: |
1210 | synexpect(TRP, 0); | | 1206 | synexpect(TRP, 0); |
1211 | } | | 1207 | } |
1212 | } | | 1208 | } |
1213 | | | 1209 | |
1214 | (*nlpp)->n = n; | | 1210 | (*nlpp)->n = n; |
1215 | if (oldstyle) { | | 1211 | if (oldstyle) { |
1216 | /* | | 1212 | /* |
1217 | * Start reading from old file again, ignoring any pushed back | | 1213 | * Start reading from old file again, ignoring any pushed back |
1218 | * tokens left from the backquote parsing | | 1214 | * tokens left from the backquote parsing |
1219 | */ | | 1215 | */ |
1220 | popfile(); | | 1216 | popfile(); |
1221 | tokpushback = 0; | | 1217 | tokpushback = 0; |
1222 | } | | 1218 | } |
| | | 1219 | |
1223 | while (stackblocksize() <= savelen) | | 1220 | while (stackblocksize() <= savelen) |
1224 | growstackblock(); | | 1221 | growstackblock(); |
1225 | STARTSTACKSTR(pout); | | 1222 | STARTSTACKSTR(out); |
1226 | if (str) { | | 1223 | if (str) { |
1227 | memcpy(pout, str, savelen); | | 1224 | memcpy(out, str, savelen); |
1228 | STADJUST(savelen, pout); | | 1225 | STADJUST(savelen, out); |
1229 | INTOFF; | | 1226 | INTOFF; |
1230 | ckfree(str); | | 1227 | ckfree(str); |
1231 | sstr = str = NULL; | | 1228 | sstr = str = NULL; |
1232 | INTON; | | 1229 | INTON; |
1233 | } | | 1230 | } |
1234 | parsebackquote = savepbq; | | 1231 | parsebackquote = savepbq; |
1235 | handler = savehandler; | | 1232 | handler = savehandler; |
1236 | if (arinest || ISDBLQUOTE()) | | 1233 | if (arinest || ISDBLQUOTE()) |
1237 | USTPUTC(CTLBACKQ | CTLQUOTE, pout); | | 1234 | USTPUTC(CTLBACKQ | CTLQUOTE, out); |
1238 | else | | 1235 | else |
1239 | USTPUTC(CTLBACKQ, pout); | | 1236 | USTPUTC(CTLBACKQ, out); |
1240 | | | 1237 | |
1241 | return pout; | | 1238 | return out; |
1242 | } | | 1239 | } |
1243 | | | 1240 | |
1244 | STATIC int | | 1241 | STATIC int |
1245 | readtoken1(int firstc, char const *syn, char *eofmark, int striptabs) | | 1242 | readtoken1(int firstc, char const *syn, char *eofmark, int striptabs) |
1246 | { | | 1243 | { |
1247 | int c = firstc; | | 1244 | int c = firstc; |
1248 | char * out; | | 1245 | char * out; |
1249 | int len; | | 1246 | int len; |
1250 | char line[EOFMARKLEN + 1]; | | 1247 | char line[EOFMARKLEN + 1]; |
1251 | struct nodelist *bqlist; | | 1248 | struct nodelist *bqlist; |
1252 | int quotef; | | 1249 | int quotef; |
1253 | VSS static_stack; | | 1250 | VSS static_stack; |
1254 | VSS *stack = &static_stack; | | 1251 | VSS *stack = &static_stack; |