]> git.ipfire.org Git - thirdparty/bash.git/blob - y.tab.c
Imported from ../bash-2.0.tar.gz.
[thirdparty/bash.git] / y.tab.c
1
2 /* A Bison parser, made from ./parse.y
3 by GNU Bison version 1.25
4 */
5
6 #define YYBISON 1 /* Identify Bison output. */
7
8 #define IF 258
9 #define THEN 259
10 #define ELSE 260
11 #define ELIF 261
12 #define FI 262
13 #define CASE 263
14 #define ESAC 264
15 #define FOR 265
16 #define SELECT 266
17 #define WHILE 267
18 #define UNTIL 268
19 #define DO 269
20 #define DONE 270
21 #define FUNCTION 271
22 #define IN 272
23 #define BANG 273
24 #define TIME 274
25 #define TIMEOPT 275
26 #define WORD 276
27 #define ASSIGNMENT_WORD 277
28 #define NUMBER 278
29 #define AND_AND 279
30 #define OR_OR 280
31 #define GREATER_GREATER 281
32 #define LESS_LESS 282
33 #define LESS_AND 283
34 #define GREATER_AND 284
35 #define SEMI_SEMI 285
36 #define LESS_LESS_MINUS 286
37 #define AND_GREATER 287
38 #define LESS_GREATER 288
39 #define GREATER_BAR 289
40 #define yacc_EOF 290
41
42 #line 21 "./parse.y"
43
44 #include "config.h"
45
46 #include "bashtypes.h"
47 #include "bashansi.h"
48
49 #if defined (HAVE_UNISTD_H)
50 # include <unistd.h>
51 #endif
52
53 #if defined (HAVE_LOCALE_H)
54 # include <locale.h>
55 #endif
56
57 #include <stdio.h>
58 #include <signal.h>
59
60 #include "memalloc.h"
61
62 #include "shell.h"
63 #include "trap.h"
64 #include "flags.h"
65 #include "parser.h"
66 #include "mailcheck.h"
67 #include "builtins/common.h"
68 #include "builtins/builtext.h"
69
70 #if defined (READLINE)
71 # include "bashline.h"
72 # include <readline/readline.h>
73 #endif /* READLINE */
74
75 #if defined (HISTORY)
76 # include "bashhist.h"
77 # include <readline/history.h>
78 #endif /* HISTORY */
79
80 #if defined (JOB_CONTROL)
81 # include "jobs.h"
82 #endif /* JOB_CONTROL */
83
84 #if defined (ALIAS)
85 # include "alias.h"
86 #endif /* ALIAS */
87
88 #if defined (PROMPT_STRING_DECODE)
89 #include <sys/param.h>
90 #include <time.h>
91 #include "maxpath.h"
92 #endif /* PROMPT_STRING_DECODE */
93
94 #define RE_READ_TOKEN -99
95 #define NO_EXPANSION -100
96
97 #define YYDEBUG 0
98
99 extern int eof_encountered;
100 extern int no_line_editing, running_under_emacs;
101 extern int current_command_number;
102 extern int interactive, interactive_shell, login_shell;
103 extern int sourcelevel;
104 extern int posixly_correct;
105 extern int last_command_exit_value;
106 extern int interrupt_immediately;
107 extern char *shell_name, *current_host_name;
108 extern char *dist_version;
109 extern int patch_level;
110 extern int dump_translatable_strings;
111 extern Function *last_shell_builtin, *this_shell_builtin;
112 #if defined (BUFFERED_INPUT)
113 extern int bash_input_fd_changed;
114 #endif
115
116 /* **************************************************************** */
117 /* */
118 /* "Forward" declarations */
119 /* */
120 /* **************************************************************** */
121
122 static char *ansiexpand ();
123 static char *localeexpand ();
124 static int reserved_word_acceptable ();
125 static int read_token ();
126 static int yylex ();
127 static int read_token_word ();
128 static void discard_parser_constructs ();
129
130 static void report_syntax_error ();
131 static void handle_eof_input_unit ();
132 static void prompt_again ();
133 static void reset_readline_prompt ();
134 static void print_prompt ();
135
136 /* Default prompt strings */
137 char *primary_prompt = PPROMPT;
138 char *secondary_prompt = SPROMPT;
139
140 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
141 char *ps1_prompt, *ps2_prompt;
142
143 /* Handle on the current prompt string. Indirectly points through
144 ps1_ or ps2_prompt. */
145 char **prompt_string_pointer = (char **)NULL;
146 char *current_prompt_string;
147
148 /* Non-zero means we expand aliases in commands. */
149 int expand_aliases = 0;
150
151 /* If non-zero, the decoded prompt string undergoes parameter and
152 variable substitution, command substitution, arithmetic substitution,
153 string expansion, process substitution, and quote removal in
154 decode_prompt_string. */
155 int promptvars = 1;
156
157 /* The decoded prompt string. Used if READLINE is not defined or if
158 editing is turned off. Analogous to current_readline_prompt. */
159 static char *current_decoded_prompt;
160
161 /* The number of lines read from input while creating the current command. */
162 int current_command_line_count;
163
164 /* Variables to manage the task of reading here documents, because we need to
165 defer the reading until after a complete command has been collected. */
166 static REDIRECT *redir_stack[10];
167 int need_here_doc;
168
169 /* Where shell input comes from. History expansion is performed on each
170 line when the shell is interactive. */
171 static char *shell_input_line = (char *)NULL;
172 static int shell_input_line_index;
173 static int shell_input_line_size; /* Amount allocated for shell_input_line. */
174 static int shell_input_line_len; /* strlen (shell_input_line) */
175
176 /* Either zero or EOF. */
177 static int shell_input_line_terminator;
178
179 /* The line number in a script on which a function definition starts. */
180 static int function_dstart;
181
182 /* The line number in a script on which a function body starts. */
183 static int function_bstart;
184
185 static REDIRECTEE redir;
186
187 #line 166 "./parse.y"
188 typedef union {
189 WORD_DESC *word; /* the word that we read. */
190 int number; /* the number that we read. */
191 WORD_LIST *word_list;
192 COMMAND *command;
193 REDIRECT *redirect;
194 ELEMENT element;
195 PATTERN_LIST *pattern;
196 } YYSTYPE;
197 #include <stdio.h>
198
199 #ifndef __cplusplus
200 #ifndef __STDC__
201 #define const
202 #endif
203 #endif
204
205
206
207 #define YYFINAL 263
208 #define YYFLAG -32768
209 #define YYNTBASE 47
210
211 #define YYTRANSLATE(x) ((unsigned)(x) <= 290 ? yytranslate[x] : 78)
212
213 static const char yytranslate[] = { 0,
214 2, 2, 2, 2, 2, 2, 2, 2, 2, 37,
215 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
216 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
217 2, 2, 2, 2, 2, 2, 2, 35, 2, 45,
218 46, 2, 2, 2, 42, 2, 2, 2, 2, 2,
219 2, 2, 2, 2, 2, 2, 2, 2, 36, 41,
220 2, 40, 2, 2, 2, 2, 2, 2, 2, 2,
221 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
222 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
223 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
224 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
225 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
226 2, 2, 43, 39, 44, 2, 2, 2, 2, 2,
227 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
228 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
229 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
230 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
231 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
232 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
233 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
234 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
235 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
236 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
237 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
238 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
239 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
240 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
241 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
242 26, 27, 28, 29, 30, 31, 32, 33, 34, 38
243 };
244
245 #if YYDEBUG != 0
246 static const short yyprhs[] = { 0,
247 0, 3, 5, 8, 10, 12, 15, 18, 21, 25,
248 29, 32, 36, 39, 43, 46, 50, 53, 57, 60,
249 64, 67, 71, 74, 78, 81, 85, 88, 92, 95,
250 99, 102, 105, 109, 111, 113, 115, 117, 120, 122,
251 125, 127, 129, 132, 134, 136, 142, 148, 150, 152,
252 154, 156, 158, 165, 172, 180, 188, 199, 210, 217,
253 224, 232, 240, 251, 262, 269, 277, 284, 290, 297,
254 302, 306, 312, 320, 327, 331, 336, 343, 349, 351,
255 354, 359, 364, 370, 376, 379, 383, 385, 389, 392,
256 394, 397, 401, 405, 409, 414, 419, 424, 429, 434,
257 436, 438, 440, 442, 443, 446, 448, 451, 454, 459,
258 464, 468, 472, 474, 476, 479, 482, 486, 490, 495,
259 497, 499
260 };
261
262 static const short yyrhs[] = { 73,
263 37, 0, 37, 0, 1, 37, 0, 38, 0, 21,
264 0, 48, 21, 0, 40, 21, 0, 41, 21, 0,
265 23, 40, 21, 0, 23, 41, 21, 0, 26, 21,
266 0, 23, 26, 21, 0, 27, 21, 0, 23, 27,
267 21, 0, 28, 23, 0, 23, 28, 23, 0, 29,
268 23, 0, 23, 29, 23, 0, 28, 21, 0, 23,
269 28, 21, 0, 29, 21, 0, 23, 29, 21, 0,
270 31, 21, 0, 23, 31, 21, 0, 29, 42, 0,
271 23, 29, 42, 0, 28, 42, 0, 23, 28, 42,
272 0, 32, 21, 0, 23, 33, 21, 0, 33, 21,
273 0, 34, 21, 0, 23, 34, 21, 0, 21, 0,
274 22, 0, 49, 0, 49, 0, 51, 49, 0, 50,
275 0, 52, 50, 0, 52, 0, 54, 0, 54, 51,
276 0, 55, 0, 57, 0, 12, 68, 14, 68, 15,
277 0, 13, 68, 14, 68, 15, 0, 56, 0, 60,
278 0, 59, 0, 61, 0, 58, 0, 10, 21, 72,
279 14, 67, 15, 0, 10, 21, 72, 43, 67, 44,
280 0, 10, 21, 36, 72, 14, 67, 15, 0, 10,
281 21, 36, 72, 43, 67, 44, 0, 10, 21, 72,
282 17, 48, 71, 72, 14, 67, 15, 0, 10, 21,
283 72, 17, 48, 71, 72, 43, 67, 44, 0, 11,
284 21, 72, 14, 67, 15, 0, 11, 21, 72, 43,
285 67, 44, 0, 11, 21, 36, 72, 14, 67, 15,
286 0, 11, 21, 36, 72, 43, 67, 44, 0, 11,
287 21, 72, 17, 48, 71, 72, 14, 67, 15, 0,
288 11, 21, 72, 17, 48, 71, 72, 43, 67, 44,
289 0, 8, 21, 72, 17, 72, 9, 0, 8, 21,
290 72, 17, 65, 72, 9, 0, 8, 21, 72, 17,
291 63, 9, 0, 21, 45, 46, 72, 61, 0, 16,
292 21, 45, 46, 72, 61, 0, 16, 21, 72, 61,
293 0, 45, 68, 46, 0, 3, 68, 4, 68, 7,
294 0, 3, 68, 4, 68, 5, 68, 7, 0, 3,
295 68, 4, 68, 62, 7, 0, 43, 67, 44, 0,
296 6, 68, 4, 68, 0, 6, 68, 4, 68, 5,
297 68, 0, 6, 68, 4, 68, 62, 0, 64, 0,
298 65, 64, 0, 72, 66, 46, 68, 0, 72, 66,
299 46, 72, 0, 72, 45, 66, 46, 68, 0, 72,
300 45, 66, 46, 72, 0, 64, 30, 0, 65, 64,
301 30, 0, 21, 0, 66, 39, 21, 0, 72, 69,
302 0, 67, 0, 72, 70, 0, 70, 37, 72, 0,
303 70, 35, 72, 0, 70, 36, 72, 0, 70, 24,
304 72, 70, 0, 70, 25, 72, 70, 0, 70, 35,
305 72, 70, 0, 70, 36, 72, 70, 0, 70, 37,
306 72, 70, 0, 75, 0, 37, 0, 36, 0, 38,
307 0, 0, 72, 37, 0, 74, 0, 74, 35, 0,
308 74, 36, 0, 74, 24, 72, 74, 0, 74, 25,
309 72, 74, 0, 74, 35, 74, 0, 74, 36, 74,
310 0, 75, 0, 76, 0, 18, 76, 0, 77, 76,
311 0, 77, 18, 76, 0, 18, 77, 76, 0, 76,
312 39, 72, 76, 0, 53, 0, 19, 0, 19, 20,
313 0
314 };
315
316 #endif
317
318 #if YYDEBUG != 0
319 static const short yyrline[] = { 0,
320 209, 218, 225, 240, 250, 252, 256, 261, 266, 271,
321 276, 281, 286, 292, 298, 303, 308, 313, 318, 323,
322 328, 333, 338, 345, 352, 357, 362, 367, 372, 377,
323 382, 387, 392, 399, 401, 403, 407, 411, 422, 424,
324 428, 430, 432, 461, 463, 465, 467, 469, 471, 473,
325 475, 477, 481, 483, 485, 487, 489, 491, 495, 499,
326 503, 507, 511, 515, 521, 523, 525, 529, 533, 536,
327 540, 544, 546, 548, 553, 557, 559, 561, 565, 566,
328 570, 572, 574, 576, 580, 581, 585, 587, 596, 604,
329 605, 611, 612, 619, 623, 625, 627, 634, 636, 638,
330 642, 643, 644, 647, 648, 657, 663, 672, 680, 682,
331 684, 691, 694, 698, 700, 705, 710, 715, 722, 725,
332 729, 731
333 };
334 #endif
335
336
337 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
338
339 static const char * const yytname[] = { "$","error","$undefined.","IF","THEN",
340 "ELSE","ELIF","FI","CASE","ESAC","FOR","SELECT","WHILE","UNTIL","DO","DONE",
341 "FUNCTION","IN","BANG","TIME","TIMEOPT","WORD","ASSIGNMENT_WORD","NUMBER","AND_AND",
342 "OR_OR","GREATER_GREATER","LESS_LESS","LESS_AND","GREATER_AND","SEMI_SEMI","LESS_LESS_MINUS",
343 "AND_GREATER","LESS_GREATER","GREATER_BAR","'&'","';'","'\\n'","yacc_EOF","'|'",
344 "'>'","'<'","'-'","'{'","'}'","'('","')'","inputunit","word_list","redirection",
345 "simple_command_element","redirection_list","simple_command","command","shell_command",
346 "for_command","select_command","case_command","function_def","subshell","if_command",
347 "group_command","elif_clause","case_clause","pattern_list","case_clause_sequence",
348 "pattern","list","compound_list","list0","list1","list_terminator","newline_list",
349 "simple_list","simple_list1","pipeline_command","pipeline","timespec", NULL
350 };
351 #endif
352
353 static const short yyr1[] = { 0,
354 47, 47, 47, 47, 48, 48, 49, 49, 49, 49,
355 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
356 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
357 49, 49, 49, 50, 50, 50, 51, 51, 52, 52,
358 53, 53, 53, 54, 54, 54, 54, 54, 54, 54,
359 54, 54, 55, 55, 55, 55, 55, 55, 56, 56,
360 56, 56, 56, 56, 57, 57, 57, 58, 58, 58,
361 59, 60, 60, 60, 61, 62, 62, 62, 63, 63,
362 64, 64, 64, 64, 65, 65, 66, 66, 67, 68,
363 68, 69, 69, 69, 70, 70, 70, 70, 70, 70,
364 71, 71, 71, 72, 72, 73, 73, 73, 74, 74,
365 74, 74, 74, 75, 75, 75, 75, 75, 76, 76,
366 77, 77
367 };
368
369 static const short yyr2[] = { 0,
370 2, 1, 2, 1, 1, 2, 2, 2, 3, 3,
371 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
372 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
373 2, 2, 3, 1, 1, 1, 1, 2, 1, 2,
374 1, 1, 2, 1, 1, 5, 5, 1, 1, 1,
375 1, 1, 6, 6, 7, 7, 10, 10, 6, 6,
376 7, 7, 10, 10, 6, 7, 6, 5, 6, 4,
377 3, 5, 7, 6, 3, 4, 6, 5, 1, 2,
378 4, 4, 5, 5, 2, 3, 1, 3, 2, 1,
379 2, 3, 3, 3, 4, 4, 4, 4, 4, 1,
380 1, 1, 1, 0, 2, 1, 2, 2, 4, 4,
381 3, 3, 1, 1, 2, 2, 3, 3, 4, 1,
382 1, 2
383 };
384
385 static const short yydefact[] = { 0,
386 0, 104, 0, 0, 0, 104, 104, 0, 0, 121,
387 34, 35, 0, 0, 0, 0, 0, 0, 0, 0,
388 0, 2, 4, 0, 0, 104, 104, 36, 39, 41,
389 120, 42, 44, 48, 45, 52, 50, 49, 51, 0,
390 106, 113, 114, 0, 3, 90, 0, 0, 104, 104,
391 104, 0, 0, 104, 115, 0, 122, 0, 0, 0,
392 0, 0, 0, 0, 0, 0, 0, 11, 13, 19,
393 15, 27, 21, 17, 25, 23, 29, 31, 32, 7,
394 8, 0, 0, 0, 34, 40, 37, 43, 1, 104,
395 104, 107, 108, 104, 0, 116, 104, 105, 89, 91,
396 100, 0, 104, 0, 104, 0, 104, 104, 0, 0,
397 118, 104, 12, 14, 20, 16, 28, 22, 18, 26,
398 24, 30, 33, 9, 10, 75, 0, 71, 38, 0,
399 0, 111, 112, 0, 117, 0, 104, 104, 104, 104,
400 104, 104, 0, 104, 0, 104, 0, 104, 0, 104,
401 0, 0, 104, 70, 0, 109, 110, 0, 0, 119,
402 104, 104, 72, 0, 0, 0, 93, 94, 92, 0,
403 79, 104, 0, 104, 104, 0, 5, 0, 0, 104,
404 104, 0, 0, 0, 46, 47, 0, 68, 0, 0,
405 74, 95, 96, 97, 98, 99, 67, 85, 80, 0,
406 65, 87, 0, 0, 0, 0, 53, 6, 102, 101,
407 103, 104, 54, 0, 0, 59, 104, 60, 69, 73,
408 104, 104, 104, 104, 86, 66, 0, 0, 104, 55,
409 56, 0, 61, 62, 0, 76, 0, 0, 0, 104,
410 88, 81, 82, 104, 104, 104, 104, 104, 78, 83,
411 84, 0, 0, 0, 0, 77, 57, 58, 63, 64,
412 0, 0, 0
413 };
414
415 static const short yydefgoto[] = { 261,
416 178, 28, 29, 88, 30, 31, 32, 33, 34, 35,
417 36, 37, 38, 39, 164, 170, 171, 172, 204, 46,
418 47, 99, 100, 212, 83, 40, 132, 101, 43, 44
419 };
420
421 static const short yypact[] = { 246,
422 -19,-32768, 8, 25, 29,-32768,-32768, 33, 354, 4,
423 34,-32768, 499, 46, 51, 32, 38, 56, 70, 72,
424 90,-32768,-32768, 97, 101,-32768,-32768,-32768,-32768, 161,
425 -32768, 483,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 6,
426 139,-32768, 84, 390,-32768,-32768, 120, 282,-32768, 89,
427 94, 112, 117, 87, 84, 462,-32768, 96, 123, 127,
428 52, 55, 128, 129, 133, 137, 140,-32768,-32768,-32768,
429 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
430 -32768, 121, 282, 122,-32768,-32768,-32768, 483,-32768,-32768,
431 -32768, 318, 318,-32768, 462, 84,-32768,-32768,-32768, 92,
432 -32768, -10,-32768, 2,-32768, 14,-32768,-32768, 130, -28,
433 84,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
434 -32768,-32768,-32768,-32768,-32768,-32768, 92,-32768,-32768, 282,
435 282, 10, 10, 426, 84, 93,-32768,-32768,-32768,-32768,
436 -32768,-32768, 23,-32768, 148,-32768, 26,-32768, 148,-32768,
437 158, 164,-32768,-32768, -28,-32768,-32768, 318, 318, 84,
438 -32768,-32768,-32768, 178, 282, 282, 282, 282, 282, 177,
439 166,-32768, -7,-32768,-32768, 176,-32768, 83, 153,-32768,
440 -32768, 183, 83, 155,-32768,-32768, -28,-32768, 193, 199,
441 -32768,-32768,-32768, 57, 57, 57,-32768,-32768, 174, -1,
442 -32768,-32768, 184, -29, 191, 163,-32768,-32768,-32768,-32768,
443 -32768,-32768,-32768, 194, 167,-32768,-32768,-32768,-32768,-32768,
444 -32768,-32768,-32768,-32768,-32768,-32768, -13, 187,-32768,-32768,
445 -32768, 27,-32768,-32768, 28, 103, 282, 282, 282,-32768,
446 -32768,-32768, 282,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
447 282, 197, 169, 201, 170,-32768,-32768,-32768,-32768,-32768,
448 217, 218,-32768
449 };
450
451 static const short yypgoto[] = {-32768,
452 74, -26, 195,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
453 -32768,-32768,-32768, -97, -12,-32768, 58,-32768, 30, -3,
454 5,-32768, -82, 45, -2,-32768, 3, 22, 12, 220
455 };
456
457
458 #define YYLAST 540
459
460
461 static const short yytable[] = { 48,
462 127, 201, 41, 48, 48, 87, 142, 226, 98, 228,
463 52, 53, 154, 202, 26, 144, 229, 45, 145, 202,
464 55, 42, 82, 57, 48, 228, 98, 148, 49, 98,
465 149, 84, 240, 90, 91, 98, 174, 203, 98, 180,
466 244, 246, 89, 203, 146, 50, 102, 104, 106, 51,
467 98, 110, 70, 54, 71, 96, 150, 188, 73, 98,
468 74, 129, 98, 98, 98, 175, 68, 111, 181, 245,
469 247, 69, 115, 72, 116, 118, 76, 119, 58, 75,
470 137, 138, 192, 193, 194, 195, 196, 130, 131, 219,
471 77, 134, 78, 117, 48, 133, 120, 161, 162, 163,
472 143, 136, 147, 208, 48, 48, 135, 248, 162, 155,
473 79, 151, 152, 42, 42, 137, 138, 80, 209, 210,
474 211, 81, 94, 97, 103, 107, 139, 140, 141, 105,
475 108, 109, 156, 157, 165, 166, 167, 168, 169, 173,
476 176, 112, 179, 113, 182, 160, 184, 114, 121, 122,
477 187, 42, 42, 123, 194, 195, 196, 124, 48, 48,
478 125, 133, 90, 91, 126, 189, 190, 128, 177, 200,
479 205, 206, 185, 92, 93, 153, 214, 215, 186, 42,
480 42, 85, 12, 13, 191, 197, 14, 15, 16, 17,
481 207, 18, 19, 20, 21, 198, 213, 216, 218, 220,
482 24, 25, 221, 225, 202, 230, 231, 241, 233, 232,
483 234, 257, 258, 260, 235, 259, 262, 263, 48, 237,
484 238, 239, 183, 249, 86, 236, 243, 217, 56, 199,
485 0, 0, 227, 242, 0, 0, 0, 251, 0, 0,
486 252, 253, 254, 255, 250, 48, 1, 0, 2, 0,
487 0, 0, 256, 3, 0, 4, 5, 6, 7, 0,
488 0, 8, 0, 9, 10, 0, 11, 12, 13, 0,
489 0, 14, 15, 16, 17, 0, 18, 19, 20, 21,
490 0, 0, 22, 23, 2, 24, 25, 0, 26, 3,
491 27, 4, 5, 6, 7, 0, 0, 8, 0, 9,
492 10, 0, 11, 12, 13, 0, 0, 14, 15, 16,
493 17, 0, 18, 19, 20, 21, 0, 0, 98, 0,
494 2, 24, 25, 0, 26, 3, 27, 4, 5, 6,
495 7, 0, 0, 8, 0, 9, 10, 0, 11, 12,
496 13, 0, 0, 14, 15, 16, 17, 0, 18, 19,
497 20, 21, 0, 0, 0, 0, 2, 24, 25, 0,
498 26, 3, 27, 4, 5, 6, 7, 0, 0, 8,
499 0, 0, 10, 0, 11, 12, 13, 0, 0, 14,
500 15, 16, 17, 0, 18, 19, 20, 21, 0, 0,
501 0, 0, 2, 24, 25, 0, 26, 3, 27, 4,
502 5, 6, 7, 0, 0, 8, 0, 95, 0, 0,
503 11, 12, 13, 0, 0, 14, 15, 16, 17, 0,
504 18, 19, 20, 21, 0, 0, 0, 0, 2, 24,
505 25, 0, 26, 3, 27, 4, 5, 6, 7, 0,
506 0, 8, 0, 0, 0, 0, 11, 12, 13, 0,
507 0, 14, 15, 16, 17, 0, 18, 19, 20, 21,
508 0, 0, 98, 0, 2, 24, 25, 0, 26, 3,
509 27, 4, 5, 6, 7, 0, 0, 8, 0, 0,
510 0, 0, 11, 12, 13, 0, 0, 14, 15, 16,
511 17, 0, 18, 19, 20, 21, 0, 0, 0, 0,
512 0, 24, 25, 0, 26, 13, 27, 0, 14, 15,
513 16, 17, 0, 18, 19, 20, 21, 0, 0, 0,
514 0, 0, 24, 25, 59, 60, 61, 62, 0, 63,
515 0, 64, 65, 0, 0, 0, 0, 0, 66, 67
516 };
517
518 static const short yycheck[] = { 2,
519 83, 9, 0, 6, 7, 32, 17, 9, 37, 39,
520 6, 7, 110, 21, 43, 14, 46, 37, 17, 21,
521 9, 0, 26, 20, 27, 39, 37, 14, 21, 37,
522 17, 27, 46, 24, 25, 37, 14, 45, 37, 14,
523 14, 14, 37, 45, 43, 21, 49, 50, 51, 21,
524 37, 54, 21, 21, 23, 44, 43, 155, 21, 37,
525 23, 88, 37, 37, 37, 43, 21, 56, 43, 43,
526 43, 21, 21, 42, 23, 21, 21, 23, 45, 42,
527 24, 25, 165, 166, 167, 168, 169, 90, 91, 187,
528 21, 94, 21, 42, 97, 93, 42, 5, 6, 7,
529 103, 97, 105, 21, 107, 108, 95, 5, 6, 112,
530 21, 107, 108, 92, 93, 24, 25, 21, 36, 37,
531 38, 21, 39, 4, 36, 14, 35, 36, 37, 36,
532 14, 45, 130, 131, 137, 138, 139, 140, 141, 142,
533 144, 46, 146, 21, 148, 134, 150, 21, 21, 21,
534 153, 130, 131, 21, 237, 238, 239, 21, 161, 162,
535 21, 159, 24, 25, 44, 161, 162, 46, 21, 172,
536 174, 175, 15, 35, 36, 46, 180, 181, 15, 158,
537 159, 21, 22, 23, 7, 9, 26, 27, 28, 29,
538 15, 31, 32, 33, 34, 30, 44, 15, 44, 7,
539 40, 41, 4, 30, 21, 15, 44, 21, 15, 212,
540 44, 15, 44, 44, 217, 15, 0, 0, 221, 222,
541 223, 224, 149, 236, 30, 221, 229, 183, 9, 172,
542 -1, -1, 203, 229, -1, -1, -1, 240, -1, -1,
543 244, 245, 246, 247, 240, 248, 1, -1, 3, -1,
544 -1, -1, 248, 8, -1, 10, 11, 12, 13, -1,
545 -1, 16, -1, 18, 19, -1, 21, 22, 23, -1,
546 -1, 26, 27, 28, 29, -1, 31, 32, 33, 34,
547 -1, -1, 37, 38, 3, 40, 41, -1, 43, 8,
548 45, 10, 11, 12, 13, -1, -1, 16, -1, 18,
549 19, -1, 21, 22, 23, -1, -1, 26, 27, 28,
550 29, -1, 31, 32, 33, 34, -1, -1, 37, -1,
551 3, 40, 41, -1, 43, 8, 45, 10, 11, 12,
552 13, -1, -1, 16, -1, 18, 19, -1, 21, 22,
553 23, -1, -1, 26, 27, 28, 29, -1, 31, 32,
554 33, 34, -1, -1, -1, -1, 3, 40, 41, -1,
555 43, 8, 45, 10, 11, 12, 13, -1, -1, 16,
556 -1, -1, 19, -1, 21, 22, 23, -1, -1, 26,
557 27, 28, 29, -1, 31, 32, 33, 34, -1, -1,
558 -1, -1, 3, 40, 41, -1, 43, 8, 45, 10,
559 11, 12, 13, -1, -1, 16, -1, 18, -1, -1,
560 21, 22, 23, -1, -1, 26, 27, 28, 29, -1,
561 31, 32, 33, 34, -1, -1, -1, -1, 3, 40,
562 41, -1, 43, 8, 45, 10, 11, 12, 13, -1,
563 -1, 16, -1, -1, -1, -1, 21, 22, 23, -1,
564 -1, 26, 27, 28, 29, -1, 31, 32, 33, 34,
565 -1, -1, 37, -1, 3, 40, 41, -1, 43, 8,
566 45, 10, 11, 12, 13, -1, -1, 16, -1, -1,
567 -1, -1, 21, 22, 23, -1, -1, 26, 27, 28,
568 29, -1, 31, 32, 33, 34, -1, -1, -1, -1,
569 -1, 40, 41, -1, 43, 23, 45, -1, 26, 27,
570 28, 29, -1, 31, 32, 33, 34, -1, -1, -1,
571 -1, -1, 40, 41, 26, 27, 28, 29, -1, 31,
572 -1, 33, 34, -1, -1, -1, -1, -1, 40, 41
573 };
574 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
575 #line 3 "/usr/local/lib/bison.simple"
576
577 /* Skeleton output parser for bison,
578 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
579
580 This program is free software; you can redistribute it and/or modify
581 it under the terms of the GNU General Public License as published by
582 the Free Software Foundation; either version 2, or (at your option)
583 any later version.
584
585 This program is distributed in the hope that it will be useful,
586 but WITHOUT ANY WARRANTY; without even the implied warranty of
587 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
588 GNU General Public License for more details.
589
590 You should have received a copy of the GNU General Public License
591 along with this program; if not, write to the Free Software
592 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
593
594 /* As a special exception, when this file is copied by Bison into a
595 Bison output file, you may use that output file without restriction.
596 This special exception was added by the Free Software Foundation
597 in version 1.24 of Bison. */
598
599 #ifndef alloca
600 #ifdef __GNUC__
601 #define alloca __builtin_alloca
602 #else /* not GNU C. */
603 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
604 #include <alloca.h>
605 #else /* not sparc */
606 #if defined (MSDOS) && !defined (__TURBOC__)
607 #include <malloc.h>
608 #else /* not MSDOS, or __TURBOC__ */
609 #if defined(_AIX)
610 #include <malloc.h>
611 #pragma alloca
612 #else /* not MSDOS, __TURBOC__, or _AIX */
613 #ifdef __hpux
614 #ifdef __cplusplus
615 extern "C" {
616 void *alloca (unsigned int);
617 };
618 #else /* not __cplusplus */
619 void *alloca ();
620 #endif /* not __cplusplus */
621 #endif /* __hpux */
622 #endif /* not _AIX */
623 #endif /* not MSDOS, or __TURBOC__ */
624 #endif /* not sparc. */
625 #endif /* not GNU C. */
626 #endif /* alloca not defined. */
627
628 /* This is the parser code that is written into each bison parser
629 when the %semantic_parser declaration is not specified in the grammar.
630 It was written by Richard Stallman by simplifying the hairy parser
631 used when %semantic_parser is specified. */
632
633 /* Note: there must be only one dollar sign in this file.
634 It is replaced by the list of actions, each action
635 as one case of the switch. */
636
637 #define yyerrok (yyerrstatus = 0)
638 #define yyclearin (yychar = YYEMPTY)
639 #define YYEMPTY -2
640 #define YYEOF 0
641 #define YYACCEPT return(0)
642 #define YYABORT return(1)
643 #define YYERROR goto yyerrlab1
644 /* Like YYERROR except do call yyerror.
645 This remains here temporarily to ease the
646 transition to the new meaning of YYERROR, for GCC.
647 Once GCC version 2 has supplanted version 1, this can go. */
648 #define YYFAIL goto yyerrlab
649 #define YYRECOVERING() (!!yyerrstatus)
650 #define YYBACKUP(token, value) \
651 do \
652 if (yychar == YYEMPTY && yylen == 1) \
653 { yychar = (token), yylval = (value); \
654 yychar1 = YYTRANSLATE (yychar); \
655 YYPOPSTACK; \
656 goto yybackup; \
657 } \
658 else \
659 { yyerror ("syntax error: cannot back up"); YYERROR; } \
660 while (0)
661
662 #define YYTERROR 1
663 #define YYERRCODE 256
664
665 #ifndef YYPURE
666 #define YYLEX yylex()
667 #endif
668
669 #ifdef YYPURE
670 #ifdef YYLSP_NEEDED
671 #ifdef YYLEX_PARAM
672 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
673 #else
674 #define YYLEX yylex(&yylval, &yylloc)
675 #endif
676 #else /* not YYLSP_NEEDED */
677 #ifdef YYLEX_PARAM
678 #define YYLEX yylex(&yylval, YYLEX_PARAM)
679 #else
680 #define YYLEX yylex(&yylval)
681 #endif
682 #endif /* not YYLSP_NEEDED */
683 #endif
684
685 /* If nonreentrant, generate the variables here */
686
687 #ifndef YYPURE
688
689 int yychar; /* the lookahead symbol */
690 YYSTYPE yylval; /* the semantic value of the */
691 /* lookahead symbol */
692
693 #ifdef YYLSP_NEEDED
694 YYLTYPE yylloc; /* location data for the lookahead */
695 /* symbol */
696 #endif
697
698 int yynerrs; /* number of parse errors so far */
699 #endif /* not YYPURE */
700
701 #if YYDEBUG != 0
702 int yydebug; /* nonzero means print parse trace */
703 /* Since this is uninitialized, it does not stop multiple parsers
704 from coexisting. */
705 #endif
706
707 /* YYINITDEPTH indicates the initial size of the parser's stacks */
708
709 #ifndef YYINITDEPTH
710 #define YYINITDEPTH 200
711 #endif
712
713 /* YYMAXDEPTH is the maximum size the stacks can grow to
714 (effective only if the built-in stack extension method is used). */
715
716 #if YYMAXDEPTH == 0
717 #undef YYMAXDEPTH
718 #endif
719
720 #ifndef YYMAXDEPTH
721 #define YYMAXDEPTH 10000
722 #endif
723
724 /* Prevent warning if -Wstrict-prototypes. */
725 #ifdef __GNUC__
726 int yyparse (void);
727 #endif
728 \f
729 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
730 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
731 #else /* not GNU C or C++ */
732 #ifndef __cplusplus
733
734 /* This is the most reliable way to avoid incompatibilities
735 in available built-in functions on various systems. */
736 static void
737 __yy_memcpy (to, from, count)
738 char *to;
739 char *from;
740 int count;
741 {
742 register char *f = from;
743 register char *t = to;
744 register int i = count;
745
746 while (i-- > 0)
747 *t++ = *f++;
748 }
749
750 #else /* __cplusplus */
751
752 /* This is the most reliable way to avoid incompatibilities
753 in available built-in functions on various systems. */
754 static void
755 __yy_memcpy (char *to, char *from, int count)
756 {
757 register char *f = from;
758 register char *t = to;
759 register int i = count;
760
761 while (i-- > 0)
762 *t++ = *f++;
763 }
764
765 #endif
766 #endif
767 \f
768 #line 196 "/usr/local/lib/bison.simple"
769
770 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
771 into yyparse. The argument should have type void *.
772 It should actually point to an object.
773 Grammar actions can access the variable by casting it
774 to the proper pointer type. */
775
776 #ifdef YYPARSE_PARAM
777 #ifdef __cplusplus
778 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
779 #define YYPARSE_PARAM_DECL
780 #else /* not __cplusplus */
781 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
782 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
783 #endif /* not __cplusplus */
784 #else /* not YYPARSE_PARAM */
785 #define YYPARSE_PARAM_ARG
786 #define YYPARSE_PARAM_DECL
787 #endif /* not YYPARSE_PARAM */
788
789 int
790 yyparse(YYPARSE_PARAM_ARG)
791 YYPARSE_PARAM_DECL
792 {
793 register int yystate;
794 register int yyn;
795 register short *yyssp;
796 register YYSTYPE *yyvsp;
797 int yyerrstatus; /* number of tokens to shift before error messages enabled */
798 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
799
800 short yyssa[YYINITDEPTH]; /* the state stack */
801 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
802
803 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
804 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
805
806 #ifdef YYLSP_NEEDED
807 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
808 YYLTYPE *yyls = yylsa;
809 YYLTYPE *yylsp;
810
811 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
812 #else
813 #define YYPOPSTACK (yyvsp--, yyssp--)
814 #endif
815
816 int yystacksize = YYINITDEPTH;
817
818 #ifdef YYPURE
819 int yychar;
820 YYSTYPE yylval;
821 int yynerrs;
822 #ifdef YYLSP_NEEDED
823 YYLTYPE yylloc;
824 #endif
825 #endif
826
827 YYSTYPE yyval; /* the variable used to return */
828 /* semantic values from the action */
829 /* routines */
830
831 int yylen;
832
833 #if YYDEBUG != 0
834 if (yydebug)
835 fprintf(stderr, "Starting parse\n");
836 #endif
837
838 yystate = 0;
839 yyerrstatus = 0;
840 yynerrs = 0;
841 yychar = YYEMPTY; /* Cause a token to be read. */
842
843 /* Initialize stack pointers.
844 Waste one element of value and location stack
845 so that they stay on the same level as the state stack.
846 The wasted elements are never initialized. */
847
848 yyssp = yyss - 1;
849 yyvsp = yyvs;
850 #ifdef YYLSP_NEEDED
851 yylsp = yyls;
852 #endif
853
854 /* Push a new state, which is found in yystate . */
855 /* In all cases, when you get here, the value and location stacks
856 have just been pushed. so pushing a state here evens the stacks. */
857 yynewstate:
858
859 *++yyssp = yystate;
860
861 if (yyssp >= yyss + yystacksize - 1)
862 {
863 /* Give user a chance to reallocate the stack */
864 /* Use copies of these so that the &'s don't force the real ones into memory. */
865 YYSTYPE *yyvs1 = yyvs;
866 short *yyss1 = yyss;
867 #ifdef YYLSP_NEEDED
868 YYLTYPE *yyls1 = yyls;
869 #endif
870
871 /* Get the current used size of the three stacks, in elements. */
872 int size = yyssp - yyss + 1;
873
874 #ifdef yyoverflow
875 /* Each stack pointer address is followed by the size of
876 the data in use in that stack, in bytes. */
877 #ifdef YYLSP_NEEDED
878 /* This used to be a conditional around just the two extra args,
879 but that might be undefined if yyoverflow is a macro. */
880 yyoverflow("parser stack overflow",
881 &yyss1, size * sizeof (*yyssp),
882 &yyvs1, size * sizeof (*yyvsp),
883 &yyls1, size * sizeof (*yylsp),
884 &yystacksize);
885 #else
886 yyoverflow("parser stack overflow",
887 &yyss1, size * sizeof (*yyssp),
888 &yyvs1, size * sizeof (*yyvsp),
889 &yystacksize);
890 #endif
891
892 yyss = yyss1; yyvs = yyvs1;
893 #ifdef YYLSP_NEEDED
894 yyls = yyls1;
895 #endif
896 #else /* no yyoverflow */
897 /* Extend the stack our own way. */
898 if (yystacksize >= YYMAXDEPTH)
899 {
900 yyerror("parser stack overflow");
901 return 2;
902 }
903 yystacksize *= 2;
904 if (yystacksize > YYMAXDEPTH)
905 yystacksize = YYMAXDEPTH;
906 yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
907 __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
908 yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
909 __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
910 #ifdef YYLSP_NEEDED
911 yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
912 __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
913 #endif
914 #endif /* no yyoverflow */
915
916 yyssp = yyss + size - 1;
917 yyvsp = yyvs + size - 1;
918 #ifdef YYLSP_NEEDED
919 yylsp = yyls + size - 1;
920 #endif
921
922 #if YYDEBUG != 0
923 if (yydebug)
924 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
925 #endif
926
927 if (yyssp >= yyss + yystacksize - 1)
928 YYABORT;
929 }
930
931 #if YYDEBUG != 0
932 if (yydebug)
933 fprintf(stderr, "Entering state %d\n", yystate);
934 #endif
935
936 goto yybackup;
937 yybackup:
938
939 /* Do appropriate processing given the current state. */
940 /* Read a lookahead token if we need one and don't already have one. */
941 /* yyresume: */
942
943 /* First try to decide what to do without reference to lookahead token. */
944
945 yyn = yypact[yystate];
946 if (yyn == YYFLAG)
947 goto yydefault;
948
949 /* Not known => get a lookahead token if don't already have one. */
950
951 /* yychar is either YYEMPTY or YYEOF
952 or a valid token in external form. */
953
954 if (yychar == YYEMPTY)
955 {
956 #if YYDEBUG != 0
957 if (yydebug)
958 fprintf(stderr, "Reading a token: ");
959 #endif
960 yychar = YYLEX;
961 }
962
963 /* Convert token to internal form (in yychar1) for indexing tables with */
964
965 if (yychar <= 0) /* This means end of input. */
966 {
967 yychar1 = 0;
968 yychar = YYEOF; /* Don't call YYLEX any more */
969
970 #if YYDEBUG != 0
971 if (yydebug)
972 fprintf(stderr, "Now at end of input.\n");
973 #endif
974 }
975 else
976 {
977 yychar1 = YYTRANSLATE(yychar);
978
979 #if YYDEBUG != 0
980 if (yydebug)
981 {
982 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
983 /* Give the individual parser a way to print the precise meaning
984 of a token, for further debugging info. */
985 #ifdef YYPRINT
986 YYPRINT (stderr, yychar, yylval);
987 #endif
988 fprintf (stderr, ")\n");
989 }
990 #endif
991 }
992
993 yyn += yychar1;
994 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
995 goto yydefault;
996
997 yyn = yytable[yyn];
998
999 /* yyn is what to do for this token type in this state.
1000 Negative => reduce, -yyn is rule number.
1001 Positive => shift, yyn is new state.
1002 New state is final state => don't bother to shift,
1003 just return success.
1004 0, or most negative number => error. */
1005
1006 if (yyn < 0)
1007 {
1008 if (yyn == YYFLAG)
1009 goto yyerrlab;
1010 yyn = -yyn;
1011 goto yyreduce;
1012 }
1013 else if (yyn == 0)
1014 goto yyerrlab;
1015
1016 if (yyn == YYFINAL)
1017 YYACCEPT;
1018
1019 /* Shift the lookahead token. */
1020
1021 #if YYDEBUG != 0
1022 if (yydebug)
1023 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
1024 #endif
1025
1026 /* Discard the token being shifted unless it is eof. */
1027 if (yychar != YYEOF)
1028 yychar = YYEMPTY;
1029
1030 *++yyvsp = yylval;
1031 #ifdef YYLSP_NEEDED
1032 *++yylsp = yylloc;
1033 #endif
1034
1035 /* count tokens shifted since error; after three, turn off error status. */
1036 if (yyerrstatus) yyerrstatus--;
1037
1038 yystate = yyn;
1039 goto yynewstate;
1040
1041 /* Do the default action for the current state. */
1042 yydefault:
1043
1044 yyn = yydefact[yystate];
1045 if (yyn == 0)
1046 goto yyerrlab;
1047
1048 /* Do a reduction. yyn is the number of a rule to reduce with. */
1049 yyreduce:
1050 yylen = yyr2[yyn];
1051 if (yylen > 0)
1052 yyval = yyvsp[1-yylen]; /* implement default value of the action */
1053
1054 #if YYDEBUG != 0
1055 if (yydebug)
1056 {
1057 int i;
1058
1059 fprintf (stderr, "Reducing via rule %d (line %d), ",
1060 yyn, yyrline[yyn]);
1061
1062 /* Print the symbols being reduced, and their result. */
1063 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
1064 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
1065 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
1066 }
1067 #endif
1068
1069
1070 switch (yyn) {
1071
1072 case 1:
1073 #line 210 "./parse.y"
1074 {
1075 /* Case of regular command. Discard the error
1076 safety net,and return the command just parsed. */
1077 global_command = yyvsp[-1].command;
1078 eof_encountered = 0;
1079 discard_parser_constructs (0);
1080 YYACCEPT;
1081 ;
1082 break;}
1083 case 2:
1084 #line 219 "./parse.y"
1085 {
1086 /* Case of regular command, but not a very
1087 interesting one. Return a NULL command. */
1088 global_command = (COMMAND *)NULL;
1089 YYACCEPT;
1090 ;
1091 break;}
1092 case 3:
1093 #line 226 "./parse.y"
1094 {
1095 /* Error during parsing. Return NULL command. */
1096 global_command = (COMMAND *)NULL;
1097 eof_encountered = 0;
1098 discard_parser_constructs (1);
1099 if (interactive)
1100 {
1101 YYACCEPT;
1102 }
1103 else
1104 {
1105 YYABORT;
1106 }
1107 ;
1108 break;}
1109 case 4:
1110 #line 241 "./parse.y"
1111 {
1112 /* Case of EOF seen by itself. Do ignoreeof or
1113 not. */
1114 global_command = (COMMAND *)NULL;
1115 handle_eof_input_unit ();
1116 YYACCEPT;
1117 ;
1118 break;}
1119 case 5:
1120 #line 251 "./parse.y"
1121 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1122 break;}
1123 case 6:
1124 #line 253 "./parse.y"
1125 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); ;
1126 break;}
1127 case 7:
1128 #line 257 "./parse.y"
1129 {
1130 redir.filename = yyvsp[0].word;
1131 yyval.redirect = make_redirection (1, r_output_direction, redir);
1132 ;
1133 break;}
1134 case 8:
1135 #line 262 "./parse.y"
1136 {
1137 redir.filename = yyvsp[0].word;
1138 yyval.redirect = make_redirection (0, r_input_direction, redir);
1139 ;
1140 break;}
1141 case 9:
1142 #line 267 "./parse.y"
1143 {
1144 redir.filename = yyvsp[0].word;
1145 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
1146 ;
1147 break;}
1148 case 10:
1149 #line 272 "./parse.y"
1150 {
1151 redir.filename = yyvsp[0].word;
1152 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
1153 ;
1154 break;}
1155 case 11:
1156 #line 277 "./parse.y"
1157 {
1158 redir.filename = yyvsp[0].word;
1159 yyval.redirect = make_redirection (1, r_appending_to, redir);
1160 ;
1161 break;}
1162 case 12:
1163 #line 282 "./parse.y"
1164 {
1165 redir.filename = yyvsp[0].word;
1166 yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
1167 ;
1168 break;}
1169 case 13:
1170 #line 287 "./parse.y"
1171 {
1172 redir.filename = yyvsp[0].word;
1173 yyval.redirect = make_redirection (0, r_reading_until, redir);
1174 redir_stack[need_here_doc++] = yyval.redirect;
1175 ;
1176 break;}
1177 case 14:
1178 #line 293 "./parse.y"
1179 {
1180 redir.filename = yyvsp[0].word;
1181 yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, redir);
1182 redir_stack[need_here_doc++] = yyval.redirect;
1183 ;
1184 break;}
1185 case 15:
1186 #line 299 "./parse.y"
1187 {
1188 redir.dest = yyvsp[0].number;
1189 yyval.redirect = make_redirection (0, r_duplicating_input, redir);
1190 ;
1191 break;}
1192 case 16:
1193 #line 304 "./parse.y"
1194 {
1195 redir.dest = yyvsp[0].number;
1196 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
1197 ;
1198 break;}
1199 case 17:
1200 #line 309 "./parse.y"
1201 {
1202 redir.dest = yyvsp[0].number;
1203 yyval.redirect = make_redirection (1, r_duplicating_output, redir);
1204 ;
1205 break;}
1206 case 18:
1207 #line 314 "./parse.y"
1208 {
1209 redir.dest = yyvsp[0].number;
1210 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
1211 ;
1212 break;}
1213 case 19:
1214 #line 319 "./parse.y"
1215 {
1216 redir.filename = yyvsp[0].word;
1217 yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
1218 ;
1219 break;}
1220 case 20:
1221 #line 324 "./parse.y"
1222 {
1223 redir.filename = yyvsp[0].word;
1224 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
1225 ;
1226 break;}
1227 case 21:
1228 #line 329 "./parse.y"
1229 {
1230 redir.filename = yyvsp[0].word;
1231 yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
1232 ;
1233 break;}
1234 case 22:
1235 #line 334 "./parse.y"
1236 {
1237 redir.filename = yyvsp[0].word;
1238 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
1239 ;
1240 break;}
1241 case 23:
1242 #line 339 "./parse.y"
1243 {
1244 redir.filename = yyvsp[0].word;
1245 yyval.redirect = make_redirection
1246 (0, r_deblank_reading_until, redir);
1247 redir_stack[need_here_doc++] = yyval.redirect;
1248 ;
1249 break;}
1250 case 24:
1251 #line 346 "./parse.y"
1252 {
1253 redir.filename = yyvsp[0].word;
1254 yyval.redirect = make_redirection
1255 (yyvsp[-2].number, r_deblank_reading_until, redir);
1256 redir_stack[need_here_doc++] = yyval.redirect;
1257 ;
1258 break;}
1259 case 25:
1260 #line 353 "./parse.y"
1261 {
1262 redir.dest = 0L;
1263 yyval.redirect = make_redirection (1, r_close_this, redir);
1264 ;
1265 break;}
1266 case 26:
1267 #line 358 "./parse.y"
1268 {
1269 redir.dest = 0L;
1270 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1271 ;
1272 break;}
1273 case 27:
1274 #line 363 "./parse.y"
1275 {
1276 redir.dest = 0L;
1277 yyval.redirect = make_redirection (0, r_close_this, redir);
1278 ;
1279 break;}
1280 case 28:
1281 #line 368 "./parse.y"
1282 {
1283 redir.dest = 0L;
1284 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1285 ;
1286 break;}
1287 case 29:
1288 #line 373 "./parse.y"
1289 {
1290 redir.filename = yyvsp[0].word;
1291 yyval.redirect = make_redirection (1, r_err_and_out, redir);
1292 ;
1293 break;}
1294 case 30:
1295 #line 378 "./parse.y"
1296 {
1297 redir.filename = yyvsp[0].word;
1298 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
1299 ;
1300 break;}
1301 case 31:
1302 #line 383 "./parse.y"
1303 {
1304 redir.filename = yyvsp[0].word;
1305 yyval.redirect = make_redirection (0, r_input_output, redir);
1306 ;
1307 break;}
1308 case 32:
1309 #line 388 "./parse.y"
1310 {
1311 redir.filename = yyvsp[0].word;
1312 yyval.redirect = make_redirection (1, r_output_force, redir);
1313 ;
1314 break;}
1315 case 33:
1316 #line 393 "./parse.y"
1317 {
1318 redir.filename = yyvsp[0].word;
1319 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
1320 ;
1321 break;}
1322 case 34:
1323 #line 400 "./parse.y"
1324 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1325 break;}
1326 case 35:
1327 #line 402 "./parse.y"
1328 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1329 break;}
1330 case 36:
1331 #line 404 "./parse.y"
1332 { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; ;
1333 break;}
1334 case 37:
1335 #line 408 "./parse.y"
1336 {
1337 yyval.redirect = yyvsp[0].redirect;
1338 ;
1339 break;}
1340 case 38:
1341 #line 412 "./parse.y"
1342 {
1343 register REDIRECT *t;
1344
1345 for (t = yyvsp[-1].redirect; t->next; t = t->next)
1346 ;
1347 t->next = yyvsp[0].redirect;
1348 yyval.redirect = yyvsp[-1].redirect;
1349 ;
1350 break;}
1351 case 39:
1352 #line 423 "./parse.y"
1353 { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); ;
1354 break;}
1355 case 40:
1356 #line 425 "./parse.y"
1357 { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); ;
1358 break;}
1359 case 41:
1360 #line 429 "./parse.y"
1361 { yyval.command = clean_simple_command (yyvsp[0].command); ;
1362 break;}
1363 case 42:
1364 #line 431 "./parse.y"
1365 { yyval.command = yyvsp[0].command; ;
1366 break;}
1367 case 43:
1368 #line 433 "./parse.y"
1369 {
1370 COMMAND *tc;
1371
1372 tc = yyvsp[-1].command;
1373 /* According to Posix.2 3.9.5, redirections
1374 specified after the body of a function should
1375 be attached to the function and performed when
1376 the function is executed, not as part of the
1377 function definition command. */
1378 if (tc->type == cm_function_def)
1379 {
1380 tc = tc->value.Function_def->command;
1381 if (tc->type == cm_group)
1382 tc = tc->value.Group->command;
1383 }
1384 if (tc->redirects)
1385 {
1386 register REDIRECT *t;
1387 for (t = tc->redirects; t->next; t = t->next)
1388 ;
1389 t->next = yyvsp[0].redirect;
1390 }
1391 else
1392 tc->redirects = yyvsp[0].redirect;
1393 yyval.command = yyvsp[-1].command;
1394 ;
1395 break;}
1396 case 44:
1397 #line 462 "./parse.y"
1398 { yyval.command = yyvsp[0].command; ;
1399 break;}
1400 case 45:
1401 #line 464 "./parse.y"
1402 { yyval.command = yyvsp[0].command; ;
1403 break;}
1404 case 46:
1405 #line 466 "./parse.y"
1406 { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); ;
1407 break;}
1408 case 47:
1409 #line 468 "./parse.y"
1410 { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); ;
1411 break;}
1412 case 48:
1413 #line 470 "./parse.y"
1414 { yyval.command = yyvsp[0].command; ;
1415 break;}
1416 case 49:
1417 #line 472 "./parse.y"
1418 { yyval.command = yyvsp[0].command; ;
1419 break;}
1420 case 50:
1421 #line 474 "./parse.y"
1422 { yyval.command = yyvsp[0].command; ;
1423 break;}
1424 case 51:
1425 #line 476 "./parse.y"
1426 { yyval.command = yyvsp[0].command; ;
1427 break;}
1428 case 52:
1429 #line 478 "./parse.y"
1430 { yyval.command = yyvsp[0].command; ;
1431 break;}
1432 case 53:
1433 #line 482 "./parse.y"
1434 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1435 break;}
1436 case 54:
1437 #line 484 "./parse.y"
1438 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1439 break;}
1440 case 55:
1441 #line 486 "./parse.y"
1442 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1443 break;}
1444 case 56:
1445 #line 488 "./parse.y"
1446 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1447 break;}
1448 case 57:
1449 #line 490 "./parse.y"
1450 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1451 break;}
1452 case 58:
1453 #line 492 "./parse.y"
1454 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1455 break;}
1456 case 59:
1457 #line 496 "./parse.y"
1458 {
1459 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1460 ;
1461 break;}
1462 case 60:
1463 #line 500 "./parse.y"
1464 {
1465 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command);
1466 ;
1467 break;}
1468 case 61:
1469 #line 504 "./parse.y"
1470 {
1471 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1472 ;
1473 break;}
1474 case 62:
1475 #line 508 "./parse.y"
1476 {
1477 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1478 ;
1479 break;}
1480 case 63:
1481 #line 512 "./parse.y"
1482 {
1483 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1484 ;
1485 break;}
1486 case 64:
1487 #line 516 "./parse.y"
1488 {
1489 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1490 ;
1491 break;}
1492 case 65:
1493 #line 522 "./parse.y"
1494 { yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL); ;
1495 break;}
1496 case 66:
1497 #line 524 "./parse.y"
1498 { yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern); ;
1499 break;}
1500 case 67:
1501 #line 526 "./parse.y"
1502 { yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern); ;
1503 break;}
1504 case 68:
1505 #line 530 "./parse.y"
1506 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1507 break;}
1508 case 69:
1509 #line 534 "./parse.y"
1510 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1511 break;}
1512 case 70:
1513 #line 537 "./parse.y"
1514 { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command, function_dstart, function_bstart); ;
1515 break;}
1516 case 71:
1517 #line 541 "./parse.y"
1518 { yyvsp[-1].command->flags |= CMD_WANT_SUBSHELL; yyval.command = yyvsp[-1].command; ;
1519 break;}
1520 case 72:
1521 #line 545 "./parse.y"
1522 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); ;
1523 break;}
1524 case 73:
1525 #line 547 "./parse.y"
1526 { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); ;
1527 break;}
1528 case 74:
1529 #line 549 "./parse.y"
1530 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); ;
1531 break;}
1532 case 75:
1533 #line 554 "./parse.y"
1534 { yyval.command = make_group_command (yyvsp[-1].command); ;
1535 break;}
1536 case 76:
1537 #line 558 "./parse.y"
1538 { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); ;
1539 break;}
1540 case 77:
1541 #line 560 "./parse.y"
1542 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); ;
1543 break;}
1544 case 78:
1545 #line 562 "./parse.y"
1546 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); ;
1547 break;}
1548 case 80:
1549 #line 567 "./parse.y"
1550 { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
1551 break;}
1552 case 81:
1553 #line 571 "./parse.y"
1554 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1555 break;}
1556 case 82:
1557 #line 573 "./parse.y"
1558 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1559 break;}
1560 case 83:
1561 #line 575 "./parse.y"
1562 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1563 break;}
1564 case 84:
1565 #line 577 "./parse.y"
1566 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1567 break;}
1568 case 86:
1569 #line 582 "./parse.y"
1570 { yyvsp[-1].pattern->next = yyvsp[-2].pattern; yyval.pattern = yyvsp[-1].pattern; ;
1571 break;}
1572 case 87:
1573 #line 586 "./parse.y"
1574 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1575 break;}
1576 case 88:
1577 #line 588 "./parse.y"
1578 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); ;
1579 break;}
1580 case 89:
1581 #line 597 "./parse.y"
1582 {
1583 yyval.command = yyvsp[0].command;
1584 if (need_here_doc)
1585 gather_here_documents ();
1586 ;
1587 break;}
1588 case 91:
1589 #line 606 "./parse.y"
1590 {
1591 yyval.command = yyvsp[0].command;
1592 ;
1593 break;}
1594 case 93:
1595 #line 613 "./parse.y"
1596 {
1597 if (yyvsp[-2].command->type == cm_connection)
1598 yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
1599 else
1600 yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
1601 ;
1602 break;}
1603 case 95:
1604 #line 624 "./parse.y"
1605 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1606 break;}
1607 case 96:
1608 #line 626 "./parse.y"
1609 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1610 break;}
1611 case 97:
1612 #line 628 "./parse.y"
1613 {
1614 if (yyvsp[-3].command->type == cm_connection)
1615 yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
1616 else
1617 yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
1618 ;
1619 break;}
1620 case 98:
1621 #line 635 "./parse.y"
1622 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1623 break;}
1624 case 99:
1625 #line 637 "./parse.y"
1626 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1627 break;}
1628 case 100:
1629 #line 639 "./parse.y"
1630 { yyval.command = yyvsp[0].command; ;
1631 break;}
1632 case 106:
1633 #line 658 "./parse.y"
1634 {
1635 yyval.command = yyvsp[0].command;
1636 if (need_here_doc)
1637 gather_here_documents ();
1638 ;
1639 break;}
1640 case 107:
1641 #line 664 "./parse.y"
1642 {
1643 if (yyvsp[-1].command->type == cm_connection)
1644 yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
1645 else
1646 yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
1647 if (need_here_doc)
1648 gather_here_documents ();
1649 ;
1650 break;}
1651 case 108:
1652 #line 673 "./parse.y"
1653 {
1654 yyval.command = yyvsp[-1].command;
1655 if (need_here_doc)
1656 gather_here_documents ();
1657 ;
1658 break;}
1659 case 109:
1660 #line 681 "./parse.y"
1661 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1662 break;}
1663 case 110:
1664 #line 683 "./parse.y"
1665 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1666 break;}
1667 case 111:
1668 #line 685 "./parse.y"
1669 {
1670 if (yyvsp[-2].command->type == cm_connection)
1671 yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
1672 else
1673 yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
1674 ;
1675 break;}
1676 case 112:
1677 #line 692 "./parse.y"
1678 { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); ;
1679 break;}
1680 case 113:
1681 #line 695 "./parse.y"
1682 { yyval.command = yyvsp[0].command; ;
1683 break;}
1684 case 114:
1685 #line 699 "./parse.y"
1686 { yyval.command = yyvsp[0].command; ;
1687 break;}
1688 case 115:
1689 #line 701 "./parse.y"
1690 {
1691 yyvsp[0].command->flags |= CMD_INVERT_RETURN;
1692 yyval.command = yyvsp[0].command;
1693 ;
1694 break;}
1695 case 116:
1696 #line 706 "./parse.y"
1697 {
1698 yyvsp[0].command->flags |= yyvsp[-1].number;
1699 yyval.command = yyvsp[0].command;
1700 ;
1701 break;}
1702 case 117:
1703 #line 711 "./parse.y"
1704 {
1705 yyvsp[0].command->flags |= yyvsp[-2].number;
1706 yyval.command = yyvsp[0].command;
1707 ;
1708 break;}
1709 case 118:
1710 #line 716 "./parse.y"
1711 {
1712 yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
1713 yyval.command = yyvsp[0].command;
1714 ;
1715 break;}
1716 case 119:
1717 #line 724 "./parse.y"
1718 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); ;
1719 break;}
1720 case 120:
1721 #line 726 "./parse.y"
1722 { yyval.command = yyvsp[0].command; ;
1723 break;}
1724 case 121:
1725 #line 730 "./parse.y"
1726 { yyval.number = CMD_TIME_PIPELINE; ;
1727 break;}
1728 case 122:
1729 #line 732 "./parse.y"
1730 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; ;
1731 break;}
1732 }
1733 /* the action file gets copied in in place of this dollarsign */
1734 #line 498 "/usr/local/lib/bison.simple"
1735 \f
1736 yyvsp -= yylen;
1737 yyssp -= yylen;
1738 #ifdef YYLSP_NEEDED
1739 yylsp -= yylen;
1740 #endif
1741
1742 #if YYDEBUG != 0
1743 if (yydebug)
1744 {
1745 short *ssp1 = yyss - 1;
1746 fprintf (stderr, "state stack now");
1747 while (ssp1 != yyssp)
1748 fprintf (stderr, " %d", *++ssp1);
1749 fprintf (stderr, "\n");
1750 }
1751 #endif
1752
1753 *++yyvsp = yyval;
1754
1755 #ifdef YYLSP_NEEDED
1756 yylsp++;
1757 if (yylen == 0)
1758 {
1759 yylsp->first_line = yylloc.first_line;
1760 yylsp->first_column = yylloc.first_column;
1761 yylsp->last_line = (yylsp-1)->last_line;
1762 yylsp->last_column = (yylsp-1)->last_column;
1763 yylsp->text = 0;
1764 }
1765 else
1766 {
1767 yylsp->last_line = (yylsp+yylen-1)->last_line;
1768 yylsp->last_column = (yylsp+yylen-1)->last_column;
1769 }
1770 #endif
1771
1772 /* Now "shift" the result of the reduction.
1773 Determine what state that goes to,
1774 based on the state we popped back to
1775 and the rule number reduced by. */
1776
1777 yyn = yyr1[yyn];
1778
1779 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1780 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1781 yystate = yytable[yystate];
1782 else
1783 yystate = yydefgoto[yyn - YYNTBASE];
1784
1785 goto yynewstate;
1786
1787 yyerrlab: /* here on detecting error */
1788
1789 if (! yyerrstatus)
1790 /* If not already recovering from an error, report this error. */
1791 {
1792 ++yynerrs;
1793
1794 #ifdef YYERROR_VERBOSE
1795 yyn = yypact[yystate];
1796
1797 if (yyn > YYFLAG && yyn < YYLAST)
1798 {
1799 int size = 0;
1800 char *msg;
1801 int x, count;
1802
1803 count = 0;
1804 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1805 for (x = (yyn < 0 ? -yyn : 0);
1806 x < (sizeof(yytname) / sizeof(char *)); x++)
1807 if (yycheck[x + yyn] == x)
1808 size += strlen(yytname[x]) + 15, count++;
1809 msg = (char *) malloc(size + 15);
1810 if (msg != 0)
1811 {
1812 strcpy(msg, "parse error");
1813
1814 if (count < 5)
1815 {
1816 count = 0;
1817 for (x = (yyn < 0 ? -yyn : 0);
1818 x < (sizeof(yytname) / sizeof(char *)); x++)
1819 if (yycheck[x + yyn] == x)
1820 {
1821 strcat(msg, count == 0 ? ", expecting `" : " or `");
1822 strcat(msg, yytname[x]);
1823 strcat(msg, "'");
1824 count++;
1825 }
1826 }
1827 yyerror(msg);
1828 free(msg);
1829 }
1830 else
1831 yyerror ("parse error; also virtual memory exceeded");
1832 }
1833 else
1834 #endif /* YYERROR_VERBOSE */
1835 yyerror("parse error");
1836 }
1837
1838 goto yyerrlab1;
1839 yyerrlab1: /* here on error raised explicitly by an action */
1840
1841 if (yyerrstatus == 3)
1842 {
1843 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1844
1845 /* return failure if at end of input */
1846 if (yychar == YYEOF)
1847 YYABORT;
1848
1849 #if YYDEBUG != 0
1850 if (yydebug)
1851 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1852 #endif
1853
1854 yychar = YYEMPTY;
1855 }
1856
1857 /* Else will try to reuse lookahead token
1858 after shifting the error token. */
1859
1860 yyerrstatus = 3; /* Each real token shifted decrements this */
1861
1862 goto yyerrhandle;
1863
1864 yyerrdefault: /* current state does not do anything special for the error token. */
1865
1866 #if 0
1867 /* This is wrong; only states that explicitly want error tokens
1868 should shift them. */
1869 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1870 if (yyn) goto yydefault;
1871 #endif
1872
1873 yyerrpop: /* pop the current state because it cannot handle the error token */
1874
1875 if (yyssp == yyss) YYABORT;
1876 yyvsp--;
1877 yystate = *--yyssp;
1878 #ifdef YYLSP_NEEDED
1879 yylsp--;
1880 #endif
1881
1882 #if YYDEBUG != 0
1883 if (yydebug)
1884 {
1885 short *ssp1 = yyss - 1;
1886 fprintf (stderr, "Error: state stack now");
1887 while (ssp1 != yyssp)
1888 fprintf (stderr, " %d", *++ssp1);
1889 fprintf (stderr, "\n");
1890 }
1891 #endif
1892
1893 yyerrhandle:
1894
1895 yyn = yypact[yystate];
1896 if (yyn == YYFLAG)
1897 goto yyerrdefault;
1898
1899 yyn += YYTERROR;
1900 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1901 goto yyerrdefault;
1902
1903 yyn = yytable[yyn];
1904 if (yyn < 0)
1905 {
1906 if (yyn == YYFLAG)
1907 goto yyerrpop;
1908 yyn = -yyn;
1909 goto yyreduce;
1910 }
1911 else if (yyn == 0)
1912 goto yyerrpop;
1913
1914 if (yyn == YYFINAL)
1915 YYACCEPT;
1916
1917 #if YYDEBUG != 0
1918 if (yydebug)
1919 fprintf(stderr, "Shifting error token, ");
1920 #endif
1921
1922 *++yyvsp = yylval;
1923 #ifdef YYLSP_NEEDED
1924 *++yylsp = yylloc;
1925 #endif
1926
1927 yystate = yyn;
1928 goto yynewstate;
1929 }
1930 #line 734 "./parse.y"
1931
1932
1933 /* Possible states for the parser that require it to do special things. */
1934 #define PST_CASEPAT 0x001 /* in a case pattern list */
1935 #define PST_ALEXPNEXT 0x002 /* expand next word for aliases */
1936 #define PST_ALLOWOPNBRC 0x004 /* allow open brace for function def */
1937 #define PST_NEEDCLOSBRC 0x008 /* need close brace */
1938 #define PST_DBLPAREN 0x010 /* double-paren parsing */
1939 #define PST_SUBSHELL 0x020 /* ( ... ) subshell */
1940 #define PST_CMDSUBST 0x040 /* $( ... ) command substitution */
1941 #define PST_CASESTMT 0x080 /* parsing a case statement */
1942
1943 /* Initial size to allocate for tokens, and the
1944 amount to grow them by. */
1945 #define TOKEN_DEFAULT_GROW_SIZE 512
1946
1947 /* Shell meta-characters that, when unquoted, separate words. */
1948 #define shellmeta(c) (strchr ("()<>;&|", (c)) != 0)
1949 #define shellbreak(c) (strchr ("()<>;&| \t\n", (c)) != 0)
1950 #define shellquote(c) ((c) == '"' || (c) == '`' || (c) == '\'')
1951 #define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>')
1952
1953 /* The token currently being read. */
1954 static int current_token;
1955
1956 /* The last read token, or NULL. read_token () uses this for context
1957 checking. */
1958 static int last_read_token;
1959
1960 /* The token read prior to last_read_token. */
1961 static int token_before_that;
1962
1963 /* The token read prior to token_before_that. */
1964 static int two_tokens_ago;
1965
1966 /* If non-zero, it is the token that we want read_token to return
1967 regardless of what text is (or isn't) present to be read. This
1968 is reset by read_token. If token_to_read == WORD or
1969 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
1970 static int token_to_read;
1971 static WORD_DESC *word_desc_to_read;
1972
1973 /* The current parser state. */
1974 static int parser_state;
1975
1976 /* Global var is non-zero when end of file has been reached. */
1977 int EOF_Reached = 0;
1978
1979 void
1980 debug_parser (i)
1981 int i;
1982 {
1983 #if YYDEBUG != 0
1984 yydebug = i;
1985 #endif
1986 }
1987
1988 /* yy_getc () returns the next available character from input or EOF.
1989 yy_ungetc (c) makes `c' the next character to read.
1990 init_yy_io (get, unget, type, location) makes the function GET the
1991 installed function for getting the next character, makes UNGET the
1992 installed function for un-getting a character, sets the type of stream
1993 (either string or file) from TYPE, and makes LOCATION point to where
1994 the input is coming from. */
1995
1996 /* Unconditionally returns end-of-file. */
1997 int
1998 return_EOF ()
1999 {
2000 return (EOF);
2001 }
2002
2003 /* Variable containing the current get and unget functions.
2004 See ./input.h for a clearer description. */
2005 BASH_INPUT bash_input;
2006
2007 /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
2008 is non-null, avoiding a memory leak. */
2009 void
2010 initialize_bash_input ()
2011 {
2012 bash_input.type = st_none;
2013 FREE (bash_input.name);
2014 bash_input.name = (char *)NULL;
2015 bash_input.location.file = (FILE *)NULL;
2016 bash_input.location.string = (char *)NULL;
2017 bash_input.getter = (Function *)NULL;
2018 bash_input.ungetter = (Function *)NULL;
2019 }
2020
2021 /* Set the contents of the current bash input stream from
2022 GET, UNGET, TYPE, NAME, and LOCATION. */
2023 void
2024 init_yy_io (get, unget, type, name, location)
2025 Function *get, *unget;
2026 int type;
2027 char *name;
2028 INPUT_STREAM location;
2029 {
2030 bash_input.type = type;
2031 FREE (bash_input.name);
2032 bash_input.name = name ? savestring (name) : (char *)NULL;
2033
2034 /* XXX */
2035 #if defined (CRAY)
2036 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
2037 #else
2038 bash_input.location = location;
2039 #endif
2040 bash_input.getter = get;
2041 bash_input.ungetter = unget;
2042 }
2043
2044 /* Call this to get the next character of input. */
2045 int
2046 yy_getc ()
2047 {
2048 return (*(bash_input.getter)) ();
2049 }
2050
2051 /* Call this to unget C. That is, to make C the next character
2052 to be read. */
2053 int
2054 yy_ungetc (c)
2055 int c;
2056 {
2057 return (*(bash_input.ungetter)) (c);
2058 }
2059
2060 #if defined (BUFFERED_INPUT)
2061 int
2062 input_file_descriptor ()
2063 {
2064 switch (bash_input.type)
2065 {
2066 case st_stream:
2067 return (fileno (bash_input.location.file));
2068 case st_bstream:
2069 return (bash_input.location.buffered_fd);
2070 case st_stdin:
2071 default:
2072 return (fileno (stdin));
2073 }
2074 }
2075 #endif /* BUFFERED_INPUT */
2076
2077 /* **************************************************************** */
2078 /* */
2079 /* Let input be read from readline (). */
2080 /* */
2081 /* **************************************************************** */
2082
2083 #if defined (READLINE)
2084 char *current_readline_prompt = (char *)NULL;
2085 char *current_readline_line = (char *)NULL;
2086 int current_readline_line_index = 0;
2087
2088 static int
2089 yy_readline_get ()
2090 {
2091 SigHandler *old_sigint;
2092 int line_len, c;
2093
2094 if (!current_readline_line)
2095 {
2096 if (!bash_readline_initialized)
2097 initialize_readline ();
2098
2099 #if defined (JOB_CONTROL)
2100 if (job_control)
2101 give_terminal_to (shell_pgrp);
2102 #endif /* JOB_CONTROL */
2103
2104 if (signal_is_ignored (SIGINT) == 0)
2105 {
2106 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
2107 interrupt_immediately++;
2108 }
2109
2110 current_readline_line = readline (current_readline_prompt ?
2111 current_readline_prompt : "");
2112
2113 if (signal_is_ignored (SIGINT) == 0)
2114 {
2115 interrupt_immediately--;
2116 set_signal_handler (SIGINT, old_sigint);
2117 }
2118
2119 #if 0
2120 /* Reset the prompt to the decoded value of prompt_string_pointer. */
2121 reset_readline_prompt ();
2122 #endif
2123
2124 if (current_readline_line == 0)
2125 return (EOF);
2126
2127 current_readline_line_index = 0;
2128 line_len = strlen (current_readline_line);
2129
2130 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
2131 current_readline_line[line_len++] = '\n';
2132 current_readline_line[line_len] = '\0';
2133 }
2134
2135 if (current_readline_line[current_readline_line_index] == 0)
2136 {
2137 free (current_readline_line);
2138 current_readline_line = (char *)NULL;
2139 return (yy_readline_get ());
2140 }
2141 else
2142 {
2143 c = (unsigned char)current_readline_line[current_readline_line_index++];
2144 return (c);
2145 }
2146 }
2147
2148 static int
2149 yy_readline_unget (c)
2150 int c;
2151 {
2152 if (current_readline_line_index && current_readline_line)
2153 current_readline_line[--current_readline_line_index] = c;
2154 return (c);
2155 }
2156
2157 void
2158 with_input_from_stdin ()
2159 {
2160 INPUT_STREAM location;
2161
2162 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
2163 {
2164 location.string = current_readline_line;
2165 init_yy_io (yy_readline_get, yy_readline_unget,
2166 st_stdin, "readline stdin", location);
2167 }
2168 }
2169
2170 #else /* !READLINE */
2171
2172 void
2173 with_input_from_stdin ()
2174 {
2175 with_input_from_stream (stdin, "stdin");
2176 }
2177 #endif /* !READLINE */
2178
2179 /* **************************************************************** */
2180 /* */
2181 /* Let input come from STRING. STRING is zero terminated. */
2182 /* */
2183 /* **************************************************************** */
2184
2185 static int
2186 yy_string_get ()
2187 {
2188 register char *string;
2189 register int c;
2190
2191 string = bash_input.location.string;
2192 c = EOF;
2193
2194 /* If the string doesn't exist, or is empty, EOF found. */
2195 if (string && *string)
2196 {
2197 c = *(unsigned char *)string++;
2198 bash_input.location.string = string;
2199 }
2200 return (c);
2201 }
2202
2203 static int
2204 yy_string_unget (c)
2205 int c;
2206 {
2207 *(--bash_input.location.string) = c;
2208 return (c);
2209 }
2210
2211 void
2212 with_input_from_string (string, name)
2213 char *string, *name;
2214 {
2215 INPUT_STREAM location;
2216
2217 location.string = string;
2218 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
2219 }
2220
2221 /* **************************************************************** */
2222 /* */
2223 /* Let input come from STREAM. */
2224 /* */
2225 /* **************************************************************** */
2226
2227 static int
2228 yy_stream_get ()
2229 {
2230 int result = EOF;
2231
2232 if (bash_input.location.file)
2233 {
2234 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2235 result = getc_with_restart (bash_input.location.file);
2236 #else /* HAVE_RESTARTABLE_SYSCALLS */
2237 result = getc (bash_input.location.file);
2238 result = (feof (bash_input.location.file)) ? EOF : (unsigned char)result;
2239 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2240 }
2241 return (result);
2242 }
2243
2244 static int
2245 yy_stream_unget (c)
2246 int c;
2247 {
2248 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2249 return (ungetc_with_restart (c, bash_input.location.file));
2250 #else /* HAVE_RESTARTABLE_SYSCALLS */
2251 return (ungetc (c, bash_input.location.file));
2252 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2253 }
2254
2255 void
2256 with_input_from_stream (stream, name)
2257 FILE *stream;
2258 char *name;
2259 {
2260 INPUT_STREAM location;
2261
2262 location.file = stream;
2263 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
2264 }
2265
2266 typedef struct stream_saver {
2267 struct stream_saver *next;
2268 BASH_INPUT bash_input;
2269 int line;
2270 #if defined (BUFFERED_INPUT)
2271 BUFFERED_STREAM *bstream;
2272 #endif /* BUFFERED_INPUT */
2273 } STREAM_SAVER;
2274
2275 /* The globally known line number. */
2276 int line_number = 0;
2277
2278 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
2279
2280 void
2281 push_stream (reset_lineno)
2282 int reset_lineno;
2283 {
2284 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
2285
2286 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
2287
2288 #if defined (BUFFERED_INPUT)
2289 saver->bstream = (BUFFERED_STREAM *)NULL;
2290 /* If we have a buffered stream, clear out buffers[fd]. */
2291 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2292 {
2293 saver->bstream = buffers[bash_input.location.buffered_fd];
2294 buffers[bash_input.location.buffered_fd] = (BUFFERED_STREAM *)NULL;
2295 }
2296 #endif /* BUFFERED_INPUT */
2297
2298 saver->line = line_number;
2299 bash_input.name = (char *)NULL;
2300 saver->next = stream_list;
2301 stream_list = saver;
2302 EOF_Reached = 0;
2303 if (reset_lineno)
2304 line_number = 0;
2305 }
2306
2307 void
2308 pop_stream ()
2309 {
2310 if (!stream_list)
2311 EOF_Reached = 1;
2312 else
2313 {
2314 STREAM_SAVER *saver = stream_list;
2315
2316 EOF_Reached = 0;
2317 stream_list = stream_list->next;
2318
2319 init_yy_io (saver->bash_input.getter,
2320 saver->bash_input.ungetter,
2321 saver->bash_input.type,
2322 saver->bash_input.name,
2323 saver->bash_input.location);
2324
2325 #if defined (BUFFERED_INPUT)
2326 /* If we have a buffered stream, restore buffers[fd]. */
2327 /* If the input file descriptor was changed while this was on the
2328 save stack, update the buffered fd to the new file descriptor and
2329 re-establish the buffer <-> bash_input fd correspondence. */
2330 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2331 {
2332 if (bash_input_fd_changed)
2333 {
2334 bash_input_fd_changed = 0;
2335 if (default_buffered_input >= 0)
2336 {
2337 bash_input.location.buffered_fd = default_buffered_input;
2338 saver->bstream->b_fd = default_buffered_input;
2339 }
2340 }
2341 buffers[bash_input.location.buffered_fd] = saver->bstream;
2342 }
2343 #endif /* BUFFERED_INPUT */
2344
2345 line_number = saver->line;
2346
2347 FREE (saver->bash_input.name);
2348 free (saver);
2349 }
2350 }
2351
2352 /* Return 1 if a stream of type TYPE is saved on the stack. */
2353 int
2354 stream_on_stack (type)
2355 enum stream_type type;
2356 {
2357 register STREAM_SAVER *s;
2358
2359 for (s = stream_list; s; s = s->next)
2360 if (s->bash_input.type == type)
2361 return 1;
2362 return 0;
2363 }
2364
2365 /*
2366 * This is used to inhibit alias expansion and reserved word recognition
2367 * inside case statement pattern lists. A `case statement pattern list' is:
2368 *
2369 * everything between the `in' in a `case word in' and the next ')'
2370 * or `esac'
2371 * everything between a `;;' and the next `)' or `esac'
2372 */
2373
2374 #if defined (ALIAS)
2375
2376 #define END_OF_ALIAS 0
2377
2378 /*
2379 * Pseudo-global variables used in implementing token-wise alias expansion.
2380 */
2381
2382 /*
2383 * Pushing and popping strings. This works together with shell_getc to
2384 * implement alias expansion on a per-token basis.
2385 */
2386
2387 typedef struct string_saver {
2388 struct string_saver *next;
2389 int expand_alias; /* Value to set expand_alias to when string is popped. */
2390 char *saved_line;
2391 alias_t *expander; /* alias that caused this line to be pushed. */
2392 int saved_line_size, saved_line_index, saved_line_terminator;
2393 } STRING_SAVER;
2394
2395 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
2396
2397 /*
2398 * Push the current shell_input_line onto a stack of such lines and make S
2399 * the current input. Used when expanding aliases. EXPAND is used to set
2400 * the value of expand_next_token when the string is popped, so that the
2401 * word after the alias in the original line is handled correctly when the
2402 * alias expands to multiple words. TOKEN is the token that was expanded
2403 * into S; it is saved and used to prevent infinite recursive expansion.
2404 */
2405 static void
2406 push_string (s, expand, ap)
2407 char *s;
2408 int expand;
2409 alias_t *ap;
2410 {
2411 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
2412
2413 temp->expand_alias = expand;
2414 temp->saved_line = shell_input_line;
2415 temp->saved_line_size = shell_input_line_size;
2416 temp->saved_line_index = shell_input_line_index;
2417 temp->saved_line_terminator = shell_input_line_terminator;
2418 temp->expander = ap;
2419 temp->next = pushed_string_list;
2420 pushed_string_list = temp;
2421
2422 ap->flags |= AL_BEINGEXPANDED;
2423
2424 shell_input_line = s;
2425 shell_input_line_size = strlen (s);
2426 shell_input_line_index = 0;
2427 shell_input_line_terminator = '\0';
2428 parser_state &= ~PST_ALEXPNEXT;
2429 }
2430
2431 /*
2432 * Make the top of the pushed_string stack be the current shell input.
2433 * Only called when there is something on the stack. Called from shell_getc
2434 * when it thinks it has consumed the string generated by an alias expansion
2435 * and needs to return to the original input line.
2436 */
2437 static void
2438 pop_string ()
2439 {
2440 STRING_SAVER *t;
2441
2442 FREE (shell_input_line);
2443 shell_input_line = pushed_string_list->saved_line;
2444 shell_input_line_index = pushed_string_list->saved_line_index;
2445 shell_input_line_size = pushed_string_list->saved_line_size;
2446 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
2447
2448 if (pushed_string_list->expand_alias)
2449 parser_state |= PST_ALEXPNEXT;
2450 else
2451 parser_state &= ~PST_ALEXPNEXT;
2452
2453 t = pushed_string_list;
2454 pushed_string_list = pushed_string_list->next;
2455
2456 t->expander->flags &= ~AL_BEINGEXPANDED;
2457
2458 free ((char *)t);
2459 }
2460
2461 static void
2462 free_string_list ()
2463 {
2464 register STRING_SAVER *t, *t1;
2465
2466 for (t = pushed_string_list; t; )
2467 {
2468 t1 = t->next;
2469 FREE (t->saved_line);
2470 t->expander->flags &= ~AL_BEINGEXPANDED;
2471 free ((char *)t);
2472 t = t1;
2473 }
2474 pushed_string_list = (STRING_SAVER *)NULL;
2475 }
2476
2477 #endif /* ALIAS */
2478
2479 /* Return a line of text, taken from wherever yylex () reads input.
2480 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
2481 is non-zero, we remove unquoted \<newline> pairs. This is used by
2482 read_secondary_line to read here documents. */
2483 static char *
2484 read_a_line (remove_quoted_newline)
2485 int remove_quoted_newline;
2486 {
2487 static char *line_buffer = (char *)NULL;
2488 static int buffer_size = 0;
2489 int indx = 0, c, peekc, pass_next;
2490
2491 #if defined (READLINE)
2492 if (interactive && bash_input.type != st_string && no_line_editing)
2493 #else
2494 if (interactive && bash_input.type != st_string)
2495 #endif
2496 print_prompt ();
2497
2498 pass_next = 0;
2499 while (1)
2500 {
2501 c = yy_getc ();
2502
2503 /* Allow immediate exit if interrupted during input. */
2504 QUIT;
2505
2506 if (c == 0)
2507 continue;
2508
2509 /* If there is no more input, then we return NULL. */
2510 if (c == EOF)
2511 {
2512 if (interactive && bash_input.type == st_stream)
2513 clearerr (stdin);
2514 if (indx == 0)
2515 return ((char *)NULL);
2516 c = '\n';
2517 }
2518
2519 /* `+2' in case the final character in the buffer is a newline. */
2520 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
2521
2522 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
2523 here document with an unquoted delimiter. In this case,
2524 the line will be expanded as if it were in double quotes.
2525 We allow a backslash to escape the next character, but we
2526 need to treat the backslash specially only if a backslash
2527 quoting a backslash-newline pair appears in the line. */
2528 if (pass_next)
2529 {
2530 line_buffer[indx++] = c;
2531 pass_next = 0;
2532 }
2533 else if (c == '\\' && remove_quoted_newline)
2534 {
2535 peekc = yy_getc ();
2536 if (peekc == '\n')
2537 continue; /* Make the unquoted \<newline> pair disappear. */
2538 else
2539 {
2540 yy_ungetc (peekc);
2541 pass_next = 1;
2542 line_buffer[indx++] = c; /* Preserve the backslash. */
2543 }
2544 }
2545 else
2546 line_buffer[indx++] = c;
2547
2548 if (c == '\n')
2549 {
2550 line_buffer[indx] = '\0';
2551 return (line_buffer);
2552 }
2553 }
2554 }
2555
2556 /* Return a line as in read_a_line (), but insure that the prompt is
2557 the secondary prompt. This is used to read the lines of a here
2558 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2559 newlines quoted with backslashes while reading the line. It is
2560 non-zero unless the delimiter of the here document was quoted. */
2561 char *
2562 read_secondary_line (remove_quoted_newline)
2563 int remove_quoted_newline;
2564 {
2565 prompt_string_pointer = &ps2_prompt;
2566 prompt_again ();
2567 return (read_a_line (remove_quoted_newline));
2568 }
2569
2570 /* **************************************************************** */
2571 /* */
2572 /* YYLEX () */
2573 /* */
2574 /* **************************************************************** */
2575
2576 /* Reserved words. These are only recognized as the first word of a
2577 command. */
2578 STRING_INT_ALIST word_token_alist[] = {
2579 { "if", IF },
2580 { "then", THEN },
2581 { "else", ELSE },
2582 { "elif", ELIF },
2583 { "fi", FI },
2584 { "case", CASE },
2585 { "esac", ESAC },
2586 { "for", FOR },
2587 #if defined (SELECT_COMMAND)
2588 { "select", SELECT },
2589 #endif
2590 { "while", WHILE },
2591 { "until", UNTIL },
2592 { "do", DO },
2593 { "done", DONE },
2594 { "in", IN },
2595 { "function", FUNCTION },
2596 #if defined (COMMAND_TIMING)
2597 { "time", TIME },
2598 #endif
2599 { "{", '{' },
2600 { "}", '}' },
2601 { "!", BANG },
2602 { (char *)NULL, 0}
2603 };
2604
2605 /* These are used by read_token_word, but appear up here so that shell_getc
2606 can use them to decide when to add otherwise blank lines to the history. */
2607
2608 /* The primary delimiter stack. */
2609 struct dstack dstack = { (char *)NULL, 0, 0 };
2610
2611 /* A temporary delimiter stack to be used when decoding prompt strings.
2612 This is needed because command substitutions in prompt strings (e.g., PS2)
2613 can screw up the parser's quoting state. */
2614 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2615
2616 /* Macro for accessing the top delimiter on the stack. Returns the
2617 delimiter or zero if none. */
2618 #define current_delimiter(ds) \
2619 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2620
2621 #define push_delimiter(ds, character) \
2622 do \
2623 { \
2624 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2625 ds.delimiters = xrealloc \
2626 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2627 ds.delimiters[ds.delimiter_depth] = character; \
2628 ds.delimiter_depth++; \
2629 } \
2630 while (0)
2631
2632 #define pop_delimiter(ds) ds.delimiter_depth--
2633
2634 /* Return the next shell input character. This always reads characters
2635 from shell_input_line; when that line is exhausted, it is time to
2636 read the next line. This is called by read_token when the shell is
2637 processing normal command input. */
2638
2639 static int
2640 shell_getc (remove_quoted_newline)
2641 int remove_quoted_newline;
2642 {
2643 register int i;
2644 int c;
2645 static int mustpop = 0;
2646
2647 QUIT;
2648
2649 #if defined (ALIAS)
2650 /* If shell_input_line[shell_input_line_index] == 0, but there is
2651 something on the pushed list of strings, then we don't want to go
2652 off and get another line. We let the code down below handle it. */
2653
2654 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2655 (pushed_string_list == (STRING_SAVER *)NULL)))
2656 #else /* !ALIAS */
2657 if (!shell_input_line || !shell_input_line[shell_input_line_index])
2658 #endif /* !ALIAS */
2659 {
2660 line_number++;
2661
2662 restart_read:
2663
2664 /* Allow immediate exit if interrupted during input. */
2665 QUIT;
2666
2667 i = 0;
2668 shell_input_line_terminator = 0;
2669
2670 #if defined (JOB_CONTROL)
2671 /* This can cause a problem when reading a command as the result
2672 of a trap, when the trap is called from flush_child. This call
2673 had better not cause jobs to disappear from the job table in
2674 that case, or we will have big trouble. */
2675 notify_and_cleanup ();
2676 #else /* !JOB_CONTROL */
2677 cleanup_dead_jobs ();
2678 #endif /* !JOB_CONTROL */
2679
2680 #if defined (READLINE)
2681 if (interactive && bash_input.type != st_string && no_line_editing)
2682 #else
2683 if (interactive && bash_input.type != st_string)
2684 #endif
2685 print_prompt ();
2686
2687 if (bash_input.type == st_stream)
2688 clearerr (stdin);
2689
2690 while (c = yy_getc ())
2691 {
2692 /* Allow immediate exit if interrupted during input. */
2693 QUIT;
2694
2695 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2696
2697 if (c == EOF)
2698 {
2699 if (bash_input.type == st_stream)
2700 clearerr (stdin);
2701
2702 if (i == 0)
2703 shell_input_line_terminator = EOF;
2704
2705 shell_input_line[i] = '\0';
2706 break;
2707 }
2708
2709 shell_input_line[i++] = c;
2710
2711 if (c == '\n')
2712 {
2713 shell_input_line[--i] = '\0';
2714 current_command_line_count++;
2715 break;
2716 }
2717 }
2718 shell_input_line_index = 0;
2719 shell_input_line_len = i; /* == strlen (shell_input_line) */
2720
2721 #if defined (HISTORY)
2722 if (remember_on_history && shell_input_line && shell_input_line[0])
2723 {
2724 char *expansions;
2725 # if defined (BANG_HISTORY)
2726 int old_hist;
2727
2728 /* If the current delimiter is a single quote, we should not be
2729 performing history expansion, even if we're on a different
2730 line from the original single quote. */
2731 old_hist = history_expansion_inhibited;
2732 if (current_delimiter (dstack) == '\'')
2733 history_expansion_inhibited = 1;
2734 # endif
2735 expansions = pre_process_line (shell_input_line, 1, 1);
2736 # if defined (BANG_HISTORY)
2737 history_expansion_inhibited = old_hist;
2738 # endif
2739
2740 free (shell_input_line);
2741 shell_input_line = expansions;
2742 shell_input_line_len = shell_input_line ?
2743 strlen (shell_input_line) :
2744 0;
2745 if (!shell_input_line_len)
2746 current_command_line_count--;
2747
2748 /* We have to force the xrealloc below because we don't know the
2749 true allocated size of shell_input_line anymore. */
2750 shell_input_line_size = shell_input_line_len;
2751 }
2752 /* XXX - this is grotesque */
2753 else if (remember_on_history && shell_input_line &&
2754 shell_input_line[0] == '\0' &&
2755 current_command_line_count > 1 && current_delimiter (dstack))
2756 {
2757 /* We know shell_input_line[0] == 0 and we're reading some sort of
2758 quoted string. This means we've got a line consisting of only
2759 a newline in a quoted string. We want to make sure this line
2760 gets added to the history. */
2761 maybe_add_history (shell_input_line);
2762 }
2763
2764 #endif /* HISTORY */
2765
2766 if (shell_input_line)
2767 {
2768 /* Lines that signify the end of the shell's input should not be
2769 echoed. */
2770 if (echo_input_at_read && (shell_input_line[0] ||
2771 shell_input_line_terminator != EOF))
2772 fprintf (stderr, "%s\n", shell_input_line);
2773 }
2774 else
2775 {
2776 shell_input_line_size = 0;
2777 prompt_string_pointer = &current_prompt_string;
2778 prompt_again ();
2779 goto restart_read;
2780 }
2781
2782 /* Add the newline to the end of this string, iff the string does
2783 not already end in an EOF character. */
2784 if (shell_input_line_terminator != EOF)
2785 {
2786 if (shell_input_line_len + 3 > shell_input_line_size)
2787 shell_input_line = xrealloc (shell_input_line,
2788 1 + (shell_input_line_size += 2));
2789
2790 shell_input_line[shell_input_line_len] = '\n';
2791 shell_input_line[shell_input_line_len + 1] = '\0';
2792 }
2793 }
2794
2795 c = shell_input_line[shell_input_line_index];
2796
2797 if (c)
2798 shell_input_line_index++;
2799
2800 if (c == '\\' && remove_quoted_newline &&
2801 shell_input_line[shell_input_line_index] == '\n')
2802 {
2803 prompt_again ();
2804 line_number++;
2805 goto restart_read;
2806 }
2807
2808 #if defined (ALIAS)
2809 /* If C is NULL, we have reached the end of the current input string. If
2810 pushed_string_list is non-empty, it's time to pop to the previous string
2811 because we have fully consumed the result of the last alias expansion.
2812 Do it transparently; just return the next character of the string popped
2813 to. */
2814 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
2815 {
2816 if (mustpop)
2817 {
2818 pop_string ();
2819 c = shell_input_line[shell_input_line_index];
2820 if (c)
2821 shell_input_line_index++;
2822 mustpop--;
2823 }
2824 else
2825 {
2826 mustpop++;
2827 c = ' ';
2828 }
2829 }
2830 #endif /* ALIAS */
2831
2832 if (!c && shell_input_line_terminator == EOF)
2833 return ((shell_input_line_index != 0) ? '\n' : EOF);
2834
2835 return ((unsigned char)c);
2836 }
2837
2838 /* Put C back into the input for the shell. */
2839 static void
2840 shell_ungetc (c)
2841 int c;
2842 {
2843 if (shell_input_line && shell_input_line_index)
2844 shell_input_line[--shell_input_line_index] = c;
2845 }
2846
2847 static void
2848 shell_ungetchar ()
2849 {
2850 if (shell_input_line && shell_input_line_index)
2851 shell_input_line_index--;
2852 }
2853
2854 /* Discard input until CHARACTER is seen, then push that character back
2855 onto the input stream. */
2856 static void
2857 discard_until (character)
2858 int character;
2859 {
2860 int c;
2861
2862 while ((c = shell_getc (0)) != EOF && c != character)
2863 ;
2864
2865 if (c != EOF)
2866 shell_ungetc (c);
2867 }
2868
2869 void
2870 execute_prompt_command (command)
2871 char *command;
2872 {
2873 Function *temp_last, *temp_this;
2874 char *last_lastarg;
2875 int temp_exit_value, temp_eof_encountered;
2876
2877 temp_last = last_shell_builtin;
2878 temp_this = this_shell_builtin;
2879 temp_exit_value = last_command_exit_value;
2880 temp_eof_encountered = eof_encountered;
2881 last_lastarg = get_string_value ("_");
2882 if (last_lastarg)
2883 last_lastarg = savestring (last_lastarg);
2884
2885 parse_and_execute (savestring (command), "PROMPT_COMMAND", 0);
2886
2887 last_shell_builtin = temp_last;
2888 this_shell_builtin = temp_this;
2889 last_command_exit_value = temp_exit_value;
2890 eof_encountered = temp_eof_encountered;
2891
2892 bind_variable ("_", last_lastarg);
2893 FREE (last_lastarg);
2894
2895 if (token_to_read == '\n') /* reset_parser was called */
2896 token_to_read = 0;
2897 }
2898
2899 /* Place to remember the token. We try to keep the buffer
2900 at a reasonable size, but it can grow. */
2901 static char *token = (char *)NULL;
2902
2903 /* Current size of the token buffer. */
2904 static int token_buffer_size;
2905
2906 /* Command to read_token () explaining what we want it to do. */
2907 #define READ 0
2908 #define RESET 1
2909 #define prompt_is_ps1 \
2910 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2911
2912 /* Function for yyparse to call. yylex keeps track of
2913 the last two tokens read, and calls read_token. */
2914 static int
2915 yylex ()
2916 {
2917 if (interactive && (current_token == 0 || current_token == '\n'))
2918 {
2919 /* Before we print a prompt, we might have to check mailboxes.
2920 We do this only if it is time to do so. Notice that only here
2921 is the mail alarm reset; nothing takes place in check_mail ()
2922 except the checking of mail. Please don't change this. */
2923 if (prompt_is_ps1 && time_to_check_mail ())
2924 {
2925 check_mail ();
2926 reset_mail_timer ();
2927 }
2928
2929 /* Avoid printing a prompt if we're not going to read anything, e.g.
2930 after resetting the parser with read_token (RESET). */
2931 if (token_to_read == 0 && interactive)
2932 prompt_again ();
2933 }
2934
2935 two_tokens_ago = token_before_that;
2936 token_before_that = last_read_token;
2937 last_read_token = current_token;
2938 current_token = read_token (READ);
2939 return (current_token);
2940 }
2941
2942 /* When non-zero, we have read the required tokens
2943 which allow ESAC to be the next one read. */
2944 static int esacs_needed_count;
2945
2946 void
2947 gather_here_documents ()
2948 {
2949 int r = 0;
2950 while (need_here_doc)
2951 {
2952 make_here_document (redir_stack[r++]);
2953 need_here_doc--;
2954 }
2955 }
2956
2957 /* When non-zero, an open-brace used to create a group is awaiting a close
2958 brace partner. */
2959 static int open_brace_count;
2960
2961 #define command_token_position(token) \
2962 (((token) == ASSIGNMENT_WORD) || \
2963 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
2964
2965 #define assignment_acceptable(token) command_token_position(token) && \
2966 ((parser_state & PST_CASEPAT) == 0)
2967
2968 /* Check to see if TOKEN is a reserved word and return the token
2969 value if it is. */
2970 #define CHECK_FOR_RESERVED_WORD(tok) \
2971 do { \
2972 if (!dollar_present && !quoted && \
2973 reserved_word_acceptable (last_read_token)) \
2974 { \
2975 int i; \
2976 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2977 if (STREQ (tok, word_token_alist[i].word)) \
2978 { \
2979 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
2980 break; \
2981 if (word_token_alist[i].token == ESAC) \
2982 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2983 else if (word_token_alist[i].token == CASE) \
2984 parser_state |= PST_CASESTMT; \
2985 else if (word_token_alist[i].token == '{') \
2986 open_brace_count++; \
2987 else if (word_token_alist[i].token == '}' && open_brace_count) \
2988 open_brace_count--; \
2989 return (word_token_alist[i].token); \
2990 } \
2991 } \
2992 } while (0)
2993
2994 #if defined (ALIAS)
2995
2996 /* OK, we have a token. Let's try to alias expand it, if (and only if)
2997 it's eligible.
2998
2999 It is eligible for expansion if the shell is in interactive mode, and
3000 the token is unquoted and the last token read was a command
3001 separator (or expand_next_token is set), and we are currently
3002 processing an alias (pushed_string_list is non-empty) and this
3003 token is not the same as the current or any previously
3004 processed alias.
3005
3006 Special cases that disqualify:
3007 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
3008 static int
3009 alias_expand_token (token)
3010 char *token;
3011 {
3012 char *expanded;
3013 alias_t *ap;
3014
3015 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
3016 (parser_state & PST_CASEPAT) == 0)
3017 {
3018 ap = find_alias (token);
3019
3020 /* Currently expanding this token. */
3021 if (ap && (ap->flags & AL_BEINGEXPANDED))
3022 return (NO_EXPANSION);
3023
3024 expanded = ap ? savestring (ap->value) : (char *)NULL;
3025 if (expanded)
3026 {
3027 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
3028 return (RE_READ_TOKEN);
3029 }
3030 else
3031 /* This is an eligible token that does not have an expansion. */
3032 return (NO_EXPANSION);
3033 }
3034 return (NO_EXPANSION);
3035 }
3036 #endif /* ALIAS */
3037
3038 /* Handle special cases of token recognition:
3039 IN is recognized if the last token was WORD and the token
3040 before that was FOR or CASE or SELECT.
3041
3042 DO is recognized if the last token was WORD and the token
3043 before that was FOR or SELECT.
3044
3045 ESAC is recognized if the last token caused `esacs_needed_count'
3046 to be set
3047
3048 `{' is recognized if the last token as WORD and the token
3049 before that was FUNCTION.
3050
3051 `}' is recognized if there is an unclosed `{' prsent.
3052 */
3053
3054 static int
3055 special_case_tokens (token)
3056 char *token;
3057 {
3058 if ((last_read_token == WORD) &&
3059 #if defined (SELECT_COMMAND)
3060 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3061 #else
3062 ((token_before_that == FOR) || (token_before_that == CASE)) &&
3063 #endif
3064 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
3065 {
3066 if (token_before_that == CASE)
3067 {
3068 parser_state |= PST_CASEPAT;
3069 esacs_needed_count++;
3070 }
3071 return (IN);
3072 }
3073
3074 if (last_read_token == WORD &&
3075 #if defined (SELECT_COMMAND)
3076 (token_before_that == FOR || token_before_that == SELECT) &&
3077 #else
3078 (token_before_that == FOR) &&
3079 #endif
3080 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
3081 return (DO);
3082
3083 /* Ditto for ESAC in the CASE case.
3084 Specifically, this handles "case word in esac", which is a legal
3085 construct, certainly because someone will pass an empty arg to the
3086 case construct, and we don't want it to barf. Of course, we should
3087 insist that the case construct has at least one pattern in it, but
3088 the designers disagree. */
3089 if (esacs_needed_count)
3090 {
3091 esacs_needed_count--;
3092 if (STREQ (token, "esac"))
3093 {
3094 parser_state &= ~PST_CASEPAT;
3095 return (ESAC);
3096 }
3097 }
3098
3099 /* The start of a shell function definition. */
3100 if (parser_state & PST_ALLOWOPNBRC)
3101 {
3102 parser_state &= ~PST_ALLOWOPNBRC;
3103 if (token[0] == '{' && token[1] == '\0') /* } */
3104 {
3105 open_brace_count++;
3106 function_bstart = line_number;
3107 return ('{'); /* } */
3108 }
3109 }
3110
3111 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
3112 {
3113 open_brace_count--; /* { */
3114 return ('}');
3115 }
3116
3117 /* Handle -p after `time'. */
3118 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
3119 return (TIMEOPT);
3120
3121 return (-1);
3122 }
3123
3124 /* Called from shell.c when Control-C is typed at top level. Or
3125 by the error rule at top level. */
3126 void
3127 reset_parser ()
3128 {
3129 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3130 open_brace_count = 0;
3131
3132 parser_state = 0;
3133
3134 #if defined (ALIAS)
3135 if (pushed_string_list)
3136 {
3137 free_string_list ();
3138 pushed_string_list = (STRING_SAVER *)NULL;
3139 }
3140 #endif /* ALIAS */
3141
3142 if (shell_input_line)
3143 {
3144 free (shell_input_line);
3145 shell_input_line = (char *)NULL;
3146 shell_input_line_size = shell_input_line_index = 0;
3147 }
3148
3149 FREE (word_desc_to_read);
3150 word_desc_to_read = (WORD_DESC *)NULL;
3151
3152 last_read_token = '\n';
3153 token_to_read = '\n';
3154 }
3155
3156 /* Read the next token. Command can be READ (normal operation) or
3157 RESET (to normalize state). */
3158 static int
3159 read_token (command)
3160 int command;
3161 {
3162 int character; /* Current character. */
3163 int peek_char; /* Temporary look-ahead character. */
3164 int result; /* The thing to return. */
3165
3166 if (command == RESET)
3167 {
3168 reset_parser ();
3169 return ('\n');
3170 }
3171
3172 if (token_to_read)
3173 {
3174 result = token_to_read;
3175 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3176 yylval.word = word_desc_to_read;
3177 token_to_read = 0;
3178 return (result);
3179 }
3180
3181 #if defined (ALIAS)
3182 /* This is a place to jump back to once we have successfully expanded a
3183 token with an alias and pushed the string with push_string () */
3184 re_read_token:
3185 #endif /* ALIAS */
3186
3187 /* Read a single word from input. Start by skipping blanks. */
3188 while ((character = shell_getc (1)) != EOF && whitespace (character))
3189 ;
3190
3191 if (character == EOF)
3192 {
3193 EOF_Reached = 1;
3194 return (yacc_EOF);
3195 }
3196
3197 if (character == '#' && (!interactive || interactive_comments))
3198 {
3199 /* A comment. Discard until EOL or EOF, and then return a newline. */
3200 discard_until ('\n');
3201 shell_getc (0);
3202 character = '\n'; /* this will take the next if statement and return. */
3203 }
3204
3205 if (character == '\n')
3206 {
3207 /* If we're about to return an unquoted newline, we can go and collect
3208 the text of any pending here document. */
3209 if (need_here_doc)
3210 gather_here_documents ();
3211
3212 #if defined (ALIAS)
3213 parser_state &= ~PST_ALEXPNEXT;
3214 #endif /* ALIAS */
3215
3216 return (character);
3217 }
3218
3219 /* Shell meta-characters. */
3220 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3221 {
3222 #if defined (ALIAS)
3223 /* Turn off alias tokenization iff this character sequence would
3224 not leave us ready to read a command. */
3225 if (character == '<' || character == '>')
3226 parser_state &= ~PST_ALEXPNEXT;
3227 #endif /* ALIAS */
3228
3229 peek_char = shell_getc (1);
3230 if (character == peek_char)
3231 {
3232 switch (character)
3233 {
3234 case '<':
3235 /* If '<' then we could be at "<<" or at "<<-". We have to
3236 look ahead one more character. */
3237 peek_char = shell_getc (1);
3238 if (peek_char == '-')
3239 return (LESS_LESS_MINUS);
3240 else
3241 {
3242 shell_ungetc (peek_char);
3243 return (LESS_LESS);
3244 }
3245
3246 case '>':
3247 return (GREATER_GREATER);
3248
3249 case ';':
3250 parser_state |= PST_CASEPAT;
3251 #if defined (ALIAS)
3252 parser_state &= ~PST_ALEXPNEXT;
3253 #endif /* ALIAS */
3254 return (SEMI_SEMI);
3255
3256 case '&':
3257 return (AND_AND);
3258
3259 case '|':
3260 return (OR_OR);
3261
3262 #if defined (DPAREN_ARITHMETIC)
3263 case '(': /* ) */
3264 if (reserved_word_acceptable (last_read_token))
3265 {
3266 parser_state |= PST_DBLPAREN;
3267 yylval.word = make_word ("let");
3268 return (WORD);
3269 }
3270 break;
3271 #endif
3272 }
3273 }
3274 else if (character == '<' && peek_char == '&')
3275 return (LESS_AND);
3276 else if (character == '>' && peek_char == '&')
3277 return (GREATER_AND);
3278 else if (character == '<' && peek_char == '>')
3279 return (LESS_GREATER);
3280 else if (character == '>' && peek_char == '|')
3281 return (GREATER_BAR);
3282 else if (peek_char == '>' && character == '&')
3283 return (AND_GREATER);
3284
3285 shell_ungetc (peek_char);
3286
3287 /* If we look like we are reading the start of a function
3288 definition, then let the reader know about it so that
3289 we will do the right thing with `{'. */
3290 if (character == ')' && last_read_token == '(' && token_before_that == WORD)
3291 {
3292 parser_state |= PST_ALLOWOPNBRC;
3293 #if defined (ALIAS)
3294 parser_state &= ~PST_ALEXPNEXT;
3295 #endif /* ALIAS */
3296 function_dstart = line_number;
3297 }
3298
3299 /* case pattern lists may be preceded by an optional left paren. If
3300 we're not trying to parse a case pattern list, the left paren
3301 indicates a subshell. */
3302 if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3303 parser_state |= PST_SUBSHELL;
3304 /*(*/
3305 else if ((parser_state & PST_CASEPAT) && character == ')')
3306 parser_state &= ~PST_CASEPAT;
3307 /*(*/
3308 else if ((parser_state & PST_SUBSHELL) && character == ')')
3309 parser_state &= ~PST_SUBSHELL;
3310
3311 #if defined (PROCESS_SUBSTITUTION)
3312 /* Check for the constructs which introduce process substitution.
3313 Shells running in `posix mode' don't do process substitution. */
3314 if (posixly_correct ||
3315 ((character != '>' && character != '<') || peek_char != '('))
3316 #endif /* PROCESS_SUBSTITUTION */
3317 return (character);
3318 }
3319
3320 /* Hack <&- (close stdin) case. */
3321 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3322 return (character);
3323
3324 /* Okay, if we got this far, we have to read a word. Read one,
3325 and then check it against the known ones. */
3326 result = read_token_word (character);
3327 #if defined (ALIAS)
3328 if (result == RE_READ_TOKEN)
3329 goto re_read_token;
3330 #endif
3331 return result;
3332 }
3333
3334 /* Match a $(...) or other grouping construct. This has to handle embedded
3335 quoted strings ('', ``, "") and nested constructs. It also must handle
3336 reprompting the user, if necessary, after reading a newline, and returning
3337 correct error values if it reads EOF. */
3338 static char matched_pair_error;
3339 static char *
3340 parse_matched_pair (qc, open, close, lenp, flags)
3341 int qc; /* `"' if this construct is within double quotes */
3342 int open, close;
3343 int *lenp, flags;
3344 {
3345 int count, ch, was_dollar;
3346 int pass_next_character, nestlen, start_lineno;
3347 char *ret, *nestret;
3348 int retind, retsize;
3349
3350 count = 1;
3351 pass_next_character = was_dollar = 0;
3352
3353 ret = xmalloc (retsize = 64);
3354 retind = 0;
3355
3356 start_lineno = line_number;
3357 while (count)
3358 {
3359 ch = shell_getc (qc != '\'' && pass_next_character == 0);
3360 if (ch == EOF)
3361 {
3362 free (ret);
3363 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
3364 EOF_Reached = 1; /* XXX */
3365 return (&matched_pair_error);
3366 }
3367
3368 /* Possible reprompting. */
3369 if (ch == '\n' && interactive &&
3370 (bash_input.type == st_stdin || bash_input.type == st_stream))
3371 prompt_again ();
3372
3373 if (pass_next_character) /* last char was backslash */
3374 {
3375 pass_next_character = 0;
3376 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3377 {
3378 if (retind > 0) retind--; /* swallow previously-added backslash */
3379 continue;
3380 }
3381
3382 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3383 if (ch == CTLESC || ch == CTLNUL)
3384 ret[retind++] = CTLESC;
3385 ret[retind++] = ch;
3386 continue;
3387 }
3388 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3389 {
3390 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3391 ret[retind++] = CTLESC;
3392 ret[retind++] = ch;
3393 continue;
3394 }
3395 else if (ch == close) /* ending delimiter */
3396 count--;
3397 else if (ch == open) /* nested begin */
3398 count++;
3399
3400 /* Add this character. */
3401 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3402 ret[retind++] = ch;
3403
3404 if (open == '\'') /* '' inside grouping construct */
3405 continue;
3406
3407 if (ch == '\\') /* backslashes */
3408 pass_next_character++;
3409
3410 if (open != close) /* a grouping construct */
3411 {
3412 if (shellquote (ch))
3413 {
3414 /* '', ``, or "" inside $(...) or other grouping construct. */
3415 push_delimiter (dstack, ch);
3416 nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
3417 pop_delimiter (dstack);
3418 if (nestret == &matched_pair_error)
3419 {
3420 free (ret);
3421 return &matched_pair_error;
3422 }
3423 if (nestlen)
3424 {
3425 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3426 strcpy (ret + retind, nestret);
3427 retind += nestlen;
3428 }
3429 FREE (nestret);
3430 }
3431 }
3432 /* Parse an old-style command substitution within double quotes as a
3433 single word. */
3434 /* XXX - sh and ksh93 don't do this - XXX */
3435 else if (open == '"' && ch == '`')
3436 {
3437 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
3438 if (nestret == &matched_pair_error)
3439 {
3440 free (ret);
3441 return &matched_pair_error;
3442 }
3443 if (nestlen)
3444 {
3445 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3446 strcpy (ret + retind, nestret);
3447 retind += nestlen;
3448 }
3449 FREE (nestret);
3450 }
3451 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3452 /* check for $(), $[], or ${} inside quoted string. */
3453 {
3454 if (open == ch) /* undo previous increment */
3455 count--;
3456 if (ch == '(') /* ) */
3457 nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
3458 else if (ch == '{') /* } */
3459 nestret = parse_matched_pair (0, '{', '}', &nestlen, 0);
3460 else if (ch == '[') /* ] */
3461 nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
3462 if (nestret == &matched_pair_error)
3463 {
3464 free (ret);
3465 return &matched_pair_error;
3466 }
3467 if (nestlen)
3468 {
3469 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3470 strcpy (ret + retind, nestret);
3471 retind += nestlen;
3472 }
3473 FREE (nestret);
3474 }
3475 was_dollar = (ch == '$');
3476 }
3477
3478 ret[retind] = '\0';
3479 if (lenp)
3480 *lenp = retind;
3481 return ret;
3482 }
3483
3484 static int
3485 read_token_word (character)
3486 int character;
3487 {
3488 /* The value for YYLVAL when a WORD is read. */
3489 WORD_DESC *the_word;
3490
3491 /* Index into the token that we are building. */
3492 int token_index;
3493
3494 /* ALL_DIGITS becomes zero when we see a non-digit. */
3495 int all_digits;
3496
3497 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3498 int dollar_present;
3499
3500 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3501 int quoted;
3502
3503 /* Non-zero means to ignore the value of the next character, and just
3504 to add it no matter what. */
3505 int pass_next_character;
3506
3507 /* The current delimiting character. */
3508 int cd;
3509 int result, peek_char;
3510 char *ttok, *ttrans;
3511 int ttoklen, ttranslen;
3512
3513 if (token_buffer_size < TOKEN_DEFAULT_GROW_SIZE)
3514 {
3515 FREE (token);
3516 token = xmalloc (token_buffer_size = TOKEN_DEFAULT_GROW_SIZE);
3517 }
3518
3519 token_index = 0;
3520 all_digits = digit (character);
3521 dollar_present = quoted = pass_next_character = 0;
3522
3523 for (;;)
3524 {
3525 if (character == EOF)
3526 goto got_token;
3527
3528 if (pass_next_character)
3529 {
3530 pass_next_character = 0;
3531 goto got_character;
3532 }
3533
3534 cd = current_delimiter (dstack);
3535
3536 /* Handle backslashes. Quote lots of things when not inside of
3537 double-quotes, quote some things inside of double-quotes. */
3538 if (character == '\\')
3539 {
3540 peek_char = shell_getc (0);
3541
3542 /* Backslash-newline is ignored in all cases except
3543 when quoted with single quotes. */
3544 if (peek_char == '\n')
3545 {
3546 character = '\n';
3547 goto next_character;
3548 }
3549 else
3550 {
3551 shell_ungetc (peek_char);
3552
3553 /* If the next character is to be quoted, note it now. */
3554 if (cd == 0 || cd == '`' ||
3555 (cd == '"' && member (peek_char, slashify_in_quotes)))
3556 pass_next_character++;
3557
3558 quoted = 1;
3559 goto got_character;
3560 }
3561 }
3562
3563 #if defined (DPAREN_ARITHMETIC)
3564 /* Parse a ksh-style ((...)) expression. */
3565 if (parser_state & PST_DBLPAREN)
3566 {
3567 int exp_lineno;
3568
3569 /* If we've already consumed a right paren that should be part of
3570 the expression, push it back so the paren matching code won't
3571 return prematurely. */
3572 if (character == '(') /* ) */
3573 shell_ungetc (character);
3574 exp_lineno = line_number;
3575 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3576 parser_state &= ~PST_DBLPAREN;
3577 if (ttok == &matched_pair_error)
3578 return -1;
3579 /* Check that the next character is the closing right paren. If
3580 not, this is a syntax error. ( */
3581 if (shell_getc (0) != ')')
3582 {
3583 FREE (ttok); /* ( */
3584 parser_error (exp_lineno, "missing closing `)' for arithmetic expression");
3585 return -1;
3586 }
3587 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
3588 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3589 token[token_index++] = '"';
3590 if (character != '(') /* ) */
3591 token[token_index++] = character;
3592 strncpy (token + token_index, ttok, ttoklen - 1);
3593 token_index += ttoklen - 1;
3594 token[token_index++] = '"';
3595 FREE (ttok);
3596 dollar_present = all_digits = 0;
3597 quoted = 1;
3598 goto got_token;
3599 }
3600 #endif /* DPAREN_ARITHMETIC */
3601
3602 /* Parse a matched pair of quote characters. */
3603 if (shellquote (character))
3604 {
3605 push_delimiter (dstack, character);
3606 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
3607 pop_delimiter (dstack);
3608 if (ttok == &matched_pair_error)
3609 return -1; /* Bail immediately. */
3610 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3611 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3612 token[token_index++] = character;
3613 strcpy (token + token_index, ttok);
3614 token_index += ttoklen;
3615 all_digits = 0;
3616 quoted = 1;
3617 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3618 FREE (ttok);
3619 goto next_character;
3620 }
3621
3622 /* If the delimiter character is not single quote, parse some of
3623 the shell expansions that must be read as a single word. */
3624 #if defined (PROCESS_SUBSTITUTION)
3625 if (character == '$' || character == '<' || character == '>')
3626 #else
3627 if (character == '$')
3628 #endif /* !PROCESS_SUBSTITUTION */
3629 {
3630 peek_char = shell_getc (1);
3631 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
3632 if (peek_char == '(' ||
3633 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
3634 {
3635 if (peek_char == '{') /* } */
3636 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, 0);
3637 else if (peek_char == '(') /* ) */
3638 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3639 else
3640 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3641 if (ttok == &matched_pair_error)
3642 return -1; /* Bail immediately. */
3643 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3644 token_buffer_size,
3645 TOKEN_DEFAULT_GROW_SIZE);
3646 token[token_index++] = character;
3647 token[token_index++] = peek_char;
3648 strcpy (token + token_index, ttok);
3649 token_index += ttoklen;
3650 FREE (ttok);
3651 dollar_present = 1;
3652 all_digits = 0;
3653 goto next_character;
3654 }
3655 /* This handles $'...' and $"..." new-style quoted strings. */
3656 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
3657 {
3658 ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
3659 if (ttok == &matched_pair_error)
3660 return -1;
3661 if (peek_char == '\'')
3662 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
3663 else
3664 ttrans = localeexpand (ttok, 0, ttoklen - 1, &ttranslen);
3665 free (ttok);
3666 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
3667 token_buffer_size,
3668 TOKEN_DEFAULT_GROW_SIZE);
3669 token[token_index++] = peek_char;
3670 strcpy (token + token_index, ttrans);
3671 token_index += ttranslen;
3672 token[token_index++] = peek_char;
3673 FREE (ttrans);
3674 quoted = 1;
3675 all_digits = 0;
3676 goto next_character;
3677 }
3678 else
3679 shell_ungetc (peek_char);
3680 }
3681
3682 #if defined (ARRAY_VARS)
3683 /* Identify possible compound array variable assignment. */
3684 else if (character == '=')
3685 {
3686 peek_char = shell_getc (1);
3687 if (peek_char == '(') /* ) */
3688 {
3689 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3690 if (ttok == &matched_pair_error)
3691 return -1; /* Bail immediately. */
3692 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3693 token_buffer_size,
3694 TOKEN_DEFAULT_GROW_SIZE);
3695 token[token_index++] = character;
3696 token[token_index++] = peek_char;
3697 strcpy (token + token_index, ttok);
3698 token_index += ttoklen;
3699 FREE (ttok);
3700 all_digits = 0;
3701 goto next_character;
3702 }
3703 else
3704 shell_ungetc (peek_char);
3705 }
3706 #endif
3707
3708 /* When not parsing a multi-character word construct, shell meta-
3709 characters break words. */
3710 if (shellbreak (character))
3711 {
3712 shell_ungetc (character);
3713 goto got_token;
3714 }
3715
3716 got_character:
3717
3718 all_digits &= digit (character);
3719 dollar_present |= character == '$';
3720
3721 if (character == CTLESC || character == CTLNUL)
3722 token[token_index++] = CTLESC;
3723
3724 token[token_index++] = character;
3725
3726 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
3727 TOKEN_DEFAULT_GROW_SIZE);
3728
3729 next_character:
3730 if (character == '\n' && interactive &&
3731 (bash_input.type == st_stdin || bash_input.type == st_stream))
3732 prompt_again ();
3733
3734 /* We want to remove quoted newlines (that is, a \<newline> pair)
3735 unless we are within single quotes or pass_next_character is
3736 set (the shell equivalent of literal-next). */
3737 cd = current_delimiter (dstack);
3738 character = shell_getc (cd != '\'' && pass_next_character == 0);
3739 } /* end for (;;) */
3740
3741 got_token:
3742
3743 token[token_index] = '\0';
3744
3745 /* Check to see what thing we should return. If the last_read_token
3746 is a `<', or a `&', or the character which ended this token is
3747 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
3748 Otherwise, it is just a word, and should be returned as such. */
3749 if (all_digits && (character == '<' || character == '>' ||
3750 last_read_token == LESS_AND ||
3751 last_read_token == GREATER_AND))
3752 {
3753 yylval.number = atoi (token);
3754 return (NUMBER);
3755 }
3756
3757 /* Check for special case tokens. */
3758 result = special_case_tokens (token);
3759 if (result >= 0)
3760 return result;
3761
3762 #if defined (ALIAS)
3763 /* Posix.2 does not allow reserved words to be aliased, so check for all
3764 of them, including special cases, before expanding the current token
3765 as an alias. */
3766 if (posixly_correct)
3767 CHECK_FOR_RESERVED_WORD (token);
3768
3769 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
3770 inhibits alias expansion. */
3771 if (expand_aliases && quoted == 0)
3772 {
3773 result = alias_expand_token (token);
3774 if (result == RE_READ_TOKEN)
3775 return (RE_READ_TOKEN);
3776 else if (result == NO_EXPANSION)
3777 parser_state &= ~PST_ALEXPNEXT;
3778 }
3779
3780 /* If not in Posix.2 mode, check for reserved words after alias
3781 expansion. */
3782 if (posixly_correct == 0)
3783 #endif
3784 CHECK_FOR_RESERVED_WORD (token);
3785
3786 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
3787 the_word->word = xmalloc (1 + token_index);
3788 the_word->flags = 0;
3789 strcpy (the_word->word, token);
3790 if (dollar_present)
3791 the_word->flags |= W_HASDOLLAR;
3792 if (quoted)
3793 the_word->flags |= W_QUOTED;
3794 /* A word is an assignment if it appears at the beginning of a
3795 simple command, or after another assignment word. This is
3796 context-dependent, so it cannot be handled in the grammar. */
3797 if (assignment (token))
3798 {
3799 the_word->flags |= W_ASSIGNMENT;
3800 /* Don't perform word splitting on assignment statements. */
3801 if (assignment_acceptable (last_read_token))
3802 the_word->flags |= W_NOSPLIT;
3803 }
3804
3805 yylval.word = the_word;
3806
3807 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
3808 ? ASSIGNMENT_WORD : WORD;
3809
3810 if (last_read_token == FUNCTION)
3811 {
3812 parser_state |= PST_ALLOWOPNBRC;
3813 function_dstart = line_number;
3814 }
3815
3816 return (result);
3817 }
3818
3819 /* $'...' ANSI-C expand the portion of STRING between START and END and
3820 return the result. The result cannot be longer than the input string. */
3821 static char *
3822 ansiexpand (string, start, end, lenp)
3823 char *string;
3824 int start, end, *lenp;
3825 {
3826 char *temp, *t;
3827 int len, tlen;
3828
3829 temp = xmalloc (end - start + 1);
3830 for (tlen = 0, len = start; len < end; )
3831 temp[tlen++] = string[len++];
3832 temp[tlen] = '\0';
3833
3834 if (*temp)
3835 {
3836 t = ansicstr (temp, tlen, (int *)NULL);
3837 free (temp);
3838 if (lenp)
3839 *lenp = strlen (t);
3840 return (t);
3841 }
3842 else
3843 {
3844 if (lenp)
3845 *lenp = 0;
3846 return (temp);
3847 }
3848 }
3849
3850 /* $"..." -- Translate the portion of STRING between START and END
3851 according to current locale using gettext (if available) and return
3852 the result. The caller will take care of leaving the quotes intact.
3853 The string will be left without the leading `$' by the caller.
3854 If translation is performed, the translated string will be double-quoted
3855 by the caller. The length of the translated string is returned in LENP,
3856 if non-null. */
3857 static char *
3858 localeexpand (string, start, end, lenp)
3859 char *string;
3860 int start, end, *lenp;
3861 {
3862 int len, tlen;
3863 char *temp, *t;
3864
3865 temp = xmalloc (end - start + 1);
3866 for (tlen = 0, len = start; len < end; )
3867 temp[tlen++] = string[len++];
3868 temp[tlen] = '\0';
3869
3870 /* If we're just dumping translatable strings, don't do anything. */
3871 if (dump_translatable_strings)
3872 {
3873 printf ("\"%s\"\n", temp);
3874 if (lenp)
3875 *lenp = tlen;
3876 return (temp);
3877 }
3878 else if (*temp)
3879 {
3880 t = localetrans (temp, tlen, &len);
3881 free (temp);
3882 if (lenp)
3883 *lenp = len;
3884 return (t);
3885 }
3886 else
3887 {
3888 if (lenp)
3889 *lenp = 0;
3890 return (temp);
3891 }
3892 }
3893
3894 /* Return 1 if TOKEN is a token that after being read would allow
3895 a reserved word to be seen, else 0. */
3896 static int
3897 reserved_word_acceptable (token)
3898 int token;
3899 {
3900 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
3901 token == '|' || token == '&' || token == '{' ||
3902 token == '}' || /* XXX */
3903 token == AND_AND ||
3904 token == BANG ||
3905 token == TIME || token == TIMEOPT ||
3906 token == DO ||
3907 token == ELIF ||
3908 token == ELSE ||
3909 token == FI ||
3910 token == IF ||
3911 token == OR_OR ||
3912 token == SEMI_SEMI ||
3913 token == THEN ||
3914 token == UNTIL ||
3915 token == WHILE ||
3916 token == DONE || /* XXX these two are experimental */
3917 token == ESAC ||
3918 token == 0)
3919 return (1);
3920 else
3921 return (0);
3922 }
3923
3924 /* Return the index of TOKEN in the alist of reserved words, or -1 if
3925 TOKEN is not a shell reserved word. */
3926 int
3927 find_reserved_word (token)
3928 char *token;
3929 {
3930 int i;
3931 for (i = 0; word_token_alist[i].word; i++)
3932 if (STREQ (token, word_token_alist[i].word))
3933 return i;
3934 return -1;
3935 }
3936
3937 #if 0
3938 #if defined (READLINE)
3939 /* Called after each time readline is called. This insures that whatever
3940 the new prompt string is gets propagated to readline's local prompt
3941 variable. */
3942 static void
3943 reset_readline_prompt ()
3944 {
3945 char *temp_prompt;
3946
3947 if (prompt_string_pointer)
3948 {
3949 temp_prompt = (*prompt_string_pointer)
3950 ? decode_prompt_string (*prompt_string_pointer)
3951 : (char *)NULL;
3952
3953 if (temp_prompt == 0)
3954 {
3955 temp_prompt = xmalloc (1);
3956 temp_prompt[0] = '\0';
3957 }
3958
3959 FREE (current_readline_prompt);
3960 current_readline_prompt = temp_prompt;
3961 }
3962 }
3963 #endif /* READLINE */
3964 #endif /* 0 */
3965
3966 #if defined (HISTORY)
3967 /* A list of tokens which can be followed by newlines, but not by
3968 semi-colons. When concatenating multiple lines of history, the
3969 newline separator for such tokens is replaced with a space. */
3970 static int no_semi_successors[] = {
3971 '\n', '{', '(', ')', ';', '&', '|',
3972 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
3973 0
3974 };
3975
3976 /* If we are not within a delimited expression, try to be smart
3977 about which separators can be semi-colons and which must be
3978 newlines. Returns the string that should be added into the
3979 history entry. */
3980 char *
3981 history_delimiting_chars ()
3982 {
3983 register int i;
3984
3985 if (dstack.delimiter_depth != 0)
3986 return ("\n");
3987
3988 /* First, handle some special cases. */
3989 /*(*/
3990 /* If we just read `()', assume it's a function definition, and don't
3991 add a semicolon. If the token before the `)' was not `(', and we're
3992 not in the midst of parsing a case statement, assume it's a
3993 parenthesized command and add the semicolon. */
3994 /*)(*/
3995 if (token_before_that == ')')
3996 {
3997 if (two_tokens_ago == '(') /*)*/ /* function def */
3998 return " ";
3999 /* This does not work for subshells inside case statement
4000 command lists. It's a suboptimal solution. */
4001 else if (parser_state & PST_CASESTMT) /* case statement pattern */
4002 return " ";
4003 else
4004 return "; "; /* (...) subshell */
4005 }
4006
4007 for (i = 0; no_semi_successors[i]; i++)
4008 {
4009 if (token_before_that == no_semi_successors[i])
4010 return (" ");
4011 }
4012
4013 return ("; ");
4014 }
4015 #endif /* HISTORY */
4016
4017 /* Issue a prompt, or prepare to issue a prompt when the next character
4018 is read. */
4019 static void
4020 prompt_again ()
4021 {
4022 char *temp_prompt;
4023
4024 if (!interactive) /* XXX */
4025 return;
4026
4027 ps1_prompt = get_string_value ("PS1");
4028 ps2_prompt = get_string_value ("PS2");
4029
4030 if (!prompt_string_pointer)
4031 prompt_string_pointer = &ps1_prompt;
4032
4033 temp_prompt = *prompt_string_pointer
4034 ? decode_prompt_string (*prompt_string_pointer)
4035 : (char *)NULL;
4036
4037 if (temp_prompt == 0)
4038 {
4039 temp_prompt = xmalloc (1);
4040 temp_prompt[0] = '\0';
4041 }
4042
4043 current_prompt_string = *prompt_string_pointer;
4044 prompt_string_pointer = &ps2_prompt;
4045
4046 #if defined (READLINE)
4047 if (!no_line_editing)
4048 {
4049 FREE (current_readline_prompt);
4050 current_readline_prompt = temp_prompt;
4051 }
4052 else
4053 #endif /* READLINE */
4054 {
4055 FREE (current_decoded_prompt);
4056 current_decoded_prompt = temp_prompt;
4057 }
4058 }
4059
4060 static void
4061 print_prompt ()
4062 {
4063 fprintf (stderr, "%s", current_decoded_prompt);
4064 fflush (stderr);
4065 }
4066
4067 /* Return a string which will be printed as a prompt. The string
4068 may contain special characters which are decoded as follows:
4069
4070 \a bell (ascii 07)
4071 \e escape (ascii 033)
4072 \d the date in Day Mon Date format
4073 \h the hostname up to the first `.'
4074 \H the hostname
4075 \n CRLF
4076 \s the name of the shell
4077 \t the time in 24-hour hh:mm:ss format
4078 \T the time in 12-hour hh:mm:ss format
4079 \@ the time in 12-hour am/pm format
4080 \v the version of bash (e.g., 2.00)
4081 \V the release of bash, version + patchlevel (e.g., 2.00.0)
4082 \w the current working directory
4083 \W the last element of $PWD
4084 \u your username
4085 \# the command number of this command
4086 \! the history number of this command
4087 \$ a $ or a # if you are root
4088 \nnn character code nnn in octal
4089 \\ a backslash
4090 \[ begin a sequence of non-printing chars
4091 \] end a sequence of non-printing chars
4092 */
4093 #define PROMPT_GROWTH 50
4094 char *
4095 decode_prompt_string (string)
4096 char *string;
4097 {
4098 WORD_LIST *list;
4099 char *result, *t;
4100 struct dstack save_dstack;
4101 #if defined (PROMPT_STRING_DECODE)
4102 int result_size, result_index;
4103 int c, n;
4104 char *temp, octal_string[4];
4105 time_t the_time;
4106
4107 result = xmalloc (result_size = PROMPT_GROWTH);
4108 result[result_index = 0] = 0;
4109 temp = (char *)NULL;
4110
4111 while (c = *string++)
4112 {
4113 if (posixly_correct && c == '!')
4114 {
4115 if (*string == '!')
4116 {
4117 temp = savestring ("!");
4118 goto add_string;
4119 }
4120 else
4121 {
4122 #if !defined (HISTORY)
4123 temp = savestring ("1");
4124 #else /* HISTORY */
4125 temp = itos (history_number ());
4126 #endif /* HISTORY */
4127 string--; /* add_string increments string again. */
4128 goto add_string;
4129 }
4130 }
4131 if (c == '\\')
4132 {
4133 c = *string;
4134
4135 switch (c)
4136 {
4137 case '0':
4138 case '1':
4139 case '2':
4140 case '3':
4141 case '4':
4142 case '5':
4143 case '6':
4144 case '7':
4145 strncpy (octal_string, string, 3);
4146 octal_string[3] = '\0';
4147
4148 n = read_octal (octal_string);
4149 temp = xmalloc (3);
4150
4151 if (n == CTLESC || n == CTLNUL)
4152 {
4153 string += 3;
4154 temp[0] = CTLESC;
4155 temp[1] = n;
4156 temp[2] = '\0';
4157 }
4158 else if (n == -1)
4159 {
4160 temp[0] = '\\';
4161 temp[1] = '\0';
4162 }
4163 else
4164 {
4165 string += 3;
4166 temp[0] = n;
4167 temp[1] = '\0';
4168 }
4169
4170 c = 0;
4171 goto add_string;
4172
4173 case 't':
4174 case 'd':
4175 case 'T':
4176 case '@':
4177 /* Make the current time/date into a string. */
4178 the_time = time (0);
4179 temp = ctime (&the_time);
4180
4181 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
4182 temp[(c != 'd') ? 8 : 10] = '\0';
4183
4184 /* quick and dirty conversion to 12-hour time */
4185 if (c == 'T' || c == '@')
4186 {
4187 if (c == '@')
4188 {
4189 temp[5] = 'a'; /* am/pm format */
4190 temp[6] = 'm';
4191 temp[7] = '\0';
4192 }
4193 c = temp[2];
4194 temp[2] = '\0';
4195 n = atoi (temp);
4196 temp[2] = c;
4197 n -= 12;
4198 if (n > 0)
4199 {
4200 temp[0] = (n / 10) + '0';
4201 temp[1] = (n % 10) + '0';
4202 }
4203 if (n >= 0 && temp[5] == 'a')
4204 temp[5] = 'p';
4205 }
4206 goto add_string;
4207
4208 case 'n':
4209 temp = xmalloc (3);
4210 temp[0] = no_line_editing ? '\n' : '\r';
4211 temp[1] = no_line_editing ? '\0' : '\n';
4212 temp[2] = '\0';
4213 goto add_string;
4214
4215 case 's':
4216 temp = base_pathname (shell_name);
4217 temp = savestring (temp);
4218 goto add_string;
4219
4220 case 'v':
4221 case 'V':
4222 temp = xmalloc (8);
4223 if (c == 'v')
4224 strcpy (temp, dist_version);
4225 else
4226 sprintf (temp, "%s.%d", dist_version, patch_level);
4227 goto add_string;
4228
4229 case 'w':
4230 case 'W':
4231 {
4232 /* Use the value of PWD because it is much more efficient. */
4233 char t_string[PATH_MAX];
4234
4235 temp = get_string_value ("PWD");
4236
4237 if (temp == 0)
4238 {
4239 if (getcwd (t_string, sizeof(t_string)) == 0)
4240 {
4241 t_string[0] = '.';
4242 t_string[1] = '\0';
4243 }
4244 }
4245 else
4246 strcpy (t_string, temp);
4247
4248 if (c == 'W')
4249 {
4250 t = strrchr (t_string, '/');
4251 if (t && t != t_string)
4252 strcpy (t_string, t + 1);
4253 }
4254 else
4255 strcpy (t_string, polite_directory_format (t_string));
4256
4257 /* If we're going to be expanding the prompt string later,
4258 quote the directory name. */
4259 if (promptvars || posixly_correct)
4260 temp = backslash_quote (t_string);
4261 else
4262 temp = savestring (t_string);
4263
4264 goto add_string;
4265 }
4266
4267 case 'u':
4268 temp = savestring (current_user.user_name);
4269 goto add_string;
4270
4271 case 'h':
4272 case 'H':
4273 temp = savestring (current_host_name);
4274 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4275 *t = '\0';
4276 goto add_string;
4277
4278 case '#':
4279 temp = itos (current_command_number);
4280 goto add_string;
4281
4282 case '!':
4283 #if !defined (HISTORY)
4284 temp = savestring ("1");
4285 #else /* HISTORY */
4286 temp = itos (history_number ());
4287 #endif /* HISTORY */
4288 goto add_string;
4289
4290 case '$':
4291 temp = xmalloc (2);
4292 temp[0] = current_user.euid == 0 ? '#' : '$';
4293 temp[1] = '\0';
4294 goto add_string;
4295
4296 #if defined (READLINE)
4297 case '[':
4298 case ']':
4299 temp = xmalloc (3);
4300 temp[0] = '\001';
4301 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4302 temp[2] = '\0';
4303 goto add_string;
4304 #endif /* READLINE */
4305
4306 case '\\':
4307 temp = xmalloc (2);
4308 temp[0] = c;
4309 temp[1] = '\0';
4310 goto add_string;
4311
4312 case 'a':
4313 case 'e':
4314 temp = xmalloc (2);
4315 temp[0] = (c == 'a') ? '\07' : '\033';
4316 temp[1] = '\0';
4317 goto add_string;
4318
4319 default:
4320 temp = xmalloc (3);
4321 temp[0] = '\\';
4322 temp[1] = c;
4323 temp[2] = '\0';
4324
4325 add_string:
4326 if (c)
4327 string++;
4328 result =
4329 sub_append_string (temp, result, &result_index, &result_size);
4330 temp = (char *)NULL; /* Freed in sub_append_string (). */
4331 result[result_index] = '\0';
4332 break;
4333 }
4334 }
4335 else
4336 {
4337 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
4338 result[result_index++] = c;
4339 result[result_index] = '\0';
4340 }
4341 }
4342 #else /* !PROMPT_STRING_DECODE */
4343 result = savestring (string);
4344 #endif /* !PROMPT_STRING_DECODE */
4345
4346 /* Save the delimiter stack and point `dstack' to temp space so any
4347 command substitutions in the prompt string won't result in screwing
4348 up the parser's quoting state. */
4349 save_dstack = dstack;
4350 dstack = temp_dstack;
4351 dstack.delimiter_depth = 0;
4352
4353 /* Perform variable and parameter expansion and command substitution on
4354 the prompt string. */
4355 if (promptvars || posixly_correct)
4356 {
4357 list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
4358 free (result);
4359 result = string_list (list);
4360 dispose_words (list);
4361 }
4362 else
4363 {
4364 t = dequote_string (result);
4365 free (result);
4366 result = t;
4367 }
4368
4369 dstack = save_dstack;
4370
4371 return (result);
4372 }
4373
4374 /* Report a syntax error, and restart the parser. Call here for fatal
4375 errors. */
4376 int
4377 yyerror ()
4378 {
4379 report_syntax_error ((char *)NULL);
4380 reset_parser ();
4381 return (0);
4382 }
4383
4384 /* Report a syntax error with line numbers, etc.
4385 Call here for recoverable errors. If you have a message to print,
4386 then place it in MESSAGE, otherwise pass NULL and this will figure
4387 out an appropriate message for you. */
4388 static void
4389 report_syntax_error (message)
4390 char *message;
4391 {
4392 char *msg, *t;
4393 int token_end, i;
4394 char msg2[2];
4395
4396 if (message)
4397 {
4398 parser_error (line_number, "%s", message);
4399 if (interactive && EOF_Reached)
4400 EOF_Reached = 0;
4401 last_command_exit_value = EX_USAGE;
4402 return;
4403 }
4404
4405 /* If the line of input we're reading is not null, try to find the
4406 objectionable token. */
4407 if (shell_input_line && *shell_input_line)
4408 {
4409 t = shell_input_line;
4410 i = shell_input_line_index;
4411 token_end = 0;
4412
4413 if (i && t[i] == '\0')
4414 i--;
4415
4416 while (i && (whitespace (t[i]) || t[i] == '\n'))
4417 i--;
4418
4419 if (i)
4420 token_end = i + 1;
4421
4422 while (i && (member (t[i], " \n\t;|&") == 0))
4423 i--;
4424
4425 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4426 i++;
4427
4428 /* Print the offending token. */
4429 if (token_end || (i == 0 && token_end == 0))
4430 {
4431 if (token_end)
4432 {
4433 msg = xmalloc (1 + (token_end - i));
4434 strncpy (msg, t + i, token_end - i);
4435 msg[token_end - i] = '\0';
4436 }
4437 else /* one-character token */
4438 {
4439 msg2[0] = t[i];
4440 msg2[1] = '\0';
4441 msg = msg2;
4442 }
4443
4444 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
4445
4446 if (msg != msg2)
4447 free (msg);
4448 }
4449
4450 /* If not interactive, print the line containing the error. */
4451 if (interactive == 0)
4452 {
4453 msg = savestring (shell_input_line);
4454 token_end = strlen (msg);
4455 while (token_end && msg[token_end - 1] == '\n')
4456 msg[--token_end] = '\0';
4457
4458 parser_error (line_number, "`%s'", msg);
4459 free (msg);
4460 }
4461 }
4462 else
4463 {
4464 msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
4465 parser_error (line_number, "%s", msg);
4466 /* When the shell is interactive, this file uses EOF_Reached
4467 only for error reporting. Other mechanisms are used to
4468 decide whether or not to exit. */
4469 if (interactive && EOF_Reached)
4470 EOF_Reached = 0;
4471 }
4472 last_command_exit_value = EX_USAGE;
4473 }
4474
4475 /* ??? Needed function. ??? We have to be able to discard the constructs
4476 created during parsing. In the case of error, we want to return
4477 allocated objects to the memory pool. In the case of no error, we want
4478 to throw away the information about where the allocated objects live.
4479 (dispose_command () will actually free the command. */
4480 static void
4481 discard_parser_constructs (error_p)
4482 int error_p;
4483 {
4484 }
4485
4486 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4487
4488 /* A flag denoting whether or not ignoreeof is set. */
4489 int ignoreeof = 0;
4490
4491 /* The number of times that we have encountered an EOF character without
4492 another character intervening. When this gets above the limit, the
4493 shell terminates. */
4494 int eof_encountered = 0;
4495
4496 /* The limit for eof_encountered. */
4497 int eof_encountered_limit = 10;
4498
4499 /* If we have EOF as the only input unit, this user wants to leave
4500 the shell. If the shell is not interactive, then just leave.
4501 Otherwise, if ignoreeof is set, and we haven't done this the
4502 required number of times in a row, print a message. */
4503 static void
4504 handle_eof_input_unit ()
4505 {
4506 if (interactive)
4507 {
4508 /* shell.c may use this to decide whether or not to write out the
4509 history, among other things. We use it only for error reporting
4510 in this file. */
4511 if (EOF_Reached)
4512 EOF_Reached = 0;
4513
4514 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4515 if (ignoreeof)
4516 {
4517 if (eof_encountered < eof_encountered_limit)
4518 {
4519 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
4520 login_shell ? "logout" : "exit");
4521 eof_encountered++;
4522 /* Reset the prompt string to be $PS1. */
4523 prompt_string_pointer = (char **)NULL;
4524 prompt_again ();
4525 last_read_token = current_token = '\n';
4526 return;
4527 }
4528 }
4529
4530 /* In this case EOF should exit the shell. Do it now. */
4531 reset_parser ();
4532 exit_builtin ((WORD_LIST *)NULL);
4533 }
4534 else
4535 {
4536 /* We don't write history files, etc., for non-interactive shells. */
4537 EOF_Reached = 1;
4538 }
4539 }