2 /* A Bison parser, made from /usr/homes/chet/src/bash/src/parse.y
3 by GNU Bison version 1.25
6 #define YYBISON 1 /* Identify Bison output. */
22 #define COND_START 272
24 #define COND_ERROR 274
30 #define ASSIGNMENT_WORD 280
33 #define ARITH_FOR_EXPRS 283
37 #define GREATER_GREATER 287
40 #define GREATER_AND 290
42 #define LESS_LESS_MINUS 292
43 #define AND_GREATER 293
44 #define LESS_GREATER 294
45 #define GREATER_BAR 295
48 #line 21 "/usr/homes/chet/src/bash/src/parse.y"
52 #include "bashtypes.h"
55 #if defined (HAVE_UNISTD_H)
59 #if defined (HAVE_LOCALE_H)
72 #include "mailcheck.h"
73 #include "builtins/common.h"
74 #include "builtins/builtext.h"
76 #if defined (READLINE)
77 # include "bashline.h"
78 # include <readline/readline.h>
82 # include "bashhist.h"
83 # include <readline/history.h>
86 #if defined (JOB_CONTROL)
88 #endif /* JOB_CONTROL */
94 #if defined (PROMPT_STRING_DECODE)
96 # include <sys/param.h>
100 #endif /* PROMPT_STRING_DECODE */
102 #define RE_READ_TOKEN -99
103 #define NO_EXPANSION -100
107 #if defined (EXTENDED_GLOB)
108 #define PATTERN_CHAR(c) \
109 ((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!')
111 extern int extended_glob;
114 extern int eof_encountered;
115 extern int no_line_editing, running_under_emacs;
116 extern int current_command_number;
117 extern int interactive, interactive_shell, login_shell;
118 extern int sourcelevel;
119 extern int posixly_correct;
120 extern int last_command_exit_value;
121 extern int interrupt_immediately;
122 extern char *shell_name, *current_host_name;
123 extern char *dist_version;
124 extern int patch_level;
125 extern int dump_translatable_strings, dump_po_strings;
126 extern Function *last_shell_builtin, *this_shell_builtin;
127 #if defined (BUFFERED_INPUT)
128 extern int bash_input_fd_changed;
132 /* **************************************************************** */
134 /* "Forward" declarations */
136 /* **************************************************************** */
138 static char *ansiexpand ();
139 static char *localeexpand ();
140 static int reserved_word_acceptable ();
141 static int read_token ();
143 static int parse_arith_cmd ();
144 #if defined (COND_COMMAND)
145 static COMMAND *parse_cond_command ();
147 static int read_token_word ();
148 static void discard_parser_constructs ();
150 static void report_syntax_error ();
151 static void handle_eof_input_unit ();
152 static void prompt_again ();
154 static void reset_readline_prompt ();
156 static void print_prompt ();
158 extern int yyerror ();
160 /* Default prompt strings */
161 char *primary_prompt = PPROMPT;
162 char *secondary_prompt = SPROMPT;
164 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
165 char *ps1_prompt, *ps2_prompt;
167 /* Handle on the current prompt string. Indirectly points through
168 ps1_ or ps2_prompt. */
169 char **prompt_string_pointer = (char **)NULL;
170 char *current_prompt_string;
172 /* Non-zero means we expand aliases in commands. */
173 int expand_aliases = 0;
175 /* If non-zero, the decoded prompt string undergoes parameter and
176 variable substitution, command substitution, arithmetic substitution,
177 string expansion, process substitution, and quote removal in
178 decode_prompt_string. */
181 /* The decoded prompt string. Used if READLINE is not defined or if
182 editing is turned off. Analogous to current_readline_prompt. */
183 static char *current_decoded_prompt;
185 /* The number of lines read from input while creating the current command. */
186 int current_command_line_count;
188 /* Variables to manage the task of reading here documents, because we need to
189 defer the reading until after a complete command has been collected. */
190 static REDIRECT *redir_stack[10];
193 /* Where shell input comes from. History expansion is performed on each
194 line when the shell is interactive. */
195 static char *shell_input_line = (char *)NULL;
196 static int shell_input_line_index;
197 static int shell_input_line_size; /* Amount allocated for shell_input_line. */
198 static int shell_input_line_len; /* strlen (shell_input_line) */
200 /* Either zero or EOF. */
201 static int shell_input_line_terminator;
203 /* The line number in a script on which a function definition starts. */
204 static int function_dstart;
206 /* The line number in a script on which a function body starts. */
207 static int function_bstart;
209 /* The line number in a script at which an arithmetic for command starts. */
210 static int arith_for_lineno;
212 static REDIRECTEE redir;
214 #line 187 "/usr/homes/chet/src/bash/src/parse.y"
216 WORD_DESC *word; /* the word that we read. */
217 int number; /* the number that we read. */
218 WORD_LIST *word_list;
222 PATTERN_LIST *pattern;
235 #define YYFLAG -32768
238 #define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 87)
240 static const char yytranslate[] = { 0,
241 2, 2, 2, 2, 2, 2, 2, 2, 2, 43,
242 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
243 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
244 2, 2, 2, 2, 2, 2, 2, 41, 2, 51,
245 52, 2, 2, 2, 48, 2, 2, 2, 2, 2,
246 2, 2, 2, 2, 2, 2, 2, 2, 42, 47,
247 2, 46, 2, 2, 2, 2, 2, 2, 2, 2,
248 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
249 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
250 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
251 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
252 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
253 2, 2, 49, 45, 50, 2, 2, 2, 2, 2,
254 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
255 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
256 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
257 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
258 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
259 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
260 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
261 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
262 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
263 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
264 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
265 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
266 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
267 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
268 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
269 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
270 36, 37, 38, 39, 40, 44
274 static const short yyprhs[] = { 0,
275 0, 3, 5, 8, 10, 12, 15, 18, 21, 25,
276 29, 32, 36, 39, 43, 46, 50, 53, 57, 60,
277 64, 67, 71, 74, 78, 81, 85, 88, 92, 95,
278 99, 102, 105, 109, 111, 113, 115, 117, 120, 122,
279 125, 127, 129, 132, 134, 136, 142, 148, 150, 152,
280 154, 156, 158, 160, 162, 164, 171, 178, 186, 194,
281 205, 216, 224, 232, 239, 246, 254, 262, 273, 284,
282 291, 299, 306, 312, 319, 324, 328, 334, 342, 349,
283 353, 355, 359, 364, 371, 377, 379, 382, 387, 392,
284 398, 404, 407, 411, 413, 417, 420, 422, 425, 429,
285 433, 437, 442, 447, 452, 457, 462, 464, 466, 468,
286 470, 471, 474, 476, 479, 482, 487, 492, 496, 500,
287 502, 504, 507, 510, 514, 518, 523, 525, 527
290 static const short yyrhs[] = { 82,
291 43, 0, 43, 0, 1, 43, 0, 44, 0, 24,
292 0, 54, 24, 0, 46, 24, 0, 47, 24, 0,
293 26, 46, 24, 0, 26, 47, 24, 0, 32, 24,
294 0, 26, 32, 24, 0, 33, 24, 0, 26, 33,
295 24, 0, 34, 26, 0, 26, 34, 26, 0, 35,
296 26, 0, 26, 35, 26, 0, 34, 24, 0, 26,
297 34, 24, 0, 35, 24, 0, 26, 35, 24, 0,
298 37, 24, 0, 26, 37, 24, 0, 35, 48, 0,
299 26, 35, 48, 0, 34, 48, 0, 26, 34, 48,
300 0, 38, 24, 0, 26, 39, 24, 0, 39, 24,
301 0, 40, 24, 0, 26, 40, 24, 0, 24, 0,
302 25, 0, 55, 0, 55, 0, 57, 55, 0, 56,
303 0, 58, 56, 0, 58, 0, 60, 0, 60, 57,
304 0, 61, 0, 64, 0, 12, 77, 14, 77, 15,
305 0, 13, 77, 14, 77, 15, 0, 63, 0, 67,
306 0, 66, 0, 68, 0, 69, 0, 70, 0, 62,
307 0, 65, 0, 10, 24, 81, 14, 77, 15, 0,
308 10, 24, 81, 49, 77, 50, 0, 10, 24, 42,
309 81, 14, 77, 15, 0, 10, 24, 42, 81, 49,
310 77, 50, 0, 10, 24, 81, 20, 54, 80, 81,
311 14, 77, 15, 0, 10, 24, 81, 20, 54, 80,
312 81, 49, 77, 50, 0, 10, 28, 80, 81, 14,
313 77, 15, 0, 10, 28, 80, 81, 49, 77, 50,
314 0, 11, 24, 81, 14, 76, 15, 0, 11, 24,
315 81, 49, 76, 50, 0, 11, 24, 42, 81, 14,
316 76, 15, 0, 11, 24, 42, 81, 49, 76, 50,
317 0, 11, 24, 81, 20, 54, 80, 81, 14, 76,
318 15, 0, 11, 24, 81, 20, 54, 80, 81, 49,
319 76, 50, 0, 8, 24, 81, 20, 81, 9, 0,
320 8, 24, 81, 20, 74, 81, 9, 0, 8, 24,
321 81, 20, 72, 9, 0, 24, 51, 52, 81, 68,
322 0, 16, 24, 51, 52, 81, 68, 0, 16, 24,
323 81, 68, 0, 51, 77, 52, 0, 3, 77, 4,
324 77, 7, 0, 3, 77, 4, 77, 5, 77, 7,
325 0, 3, 77, 4, 77, 71, 7, 0, 49, 76,
326 50, 0, 27, 0, 17, 29, 18, 0, 6, 77,
327 4, 77, 0, 6, 77, 4, 77, 5, 77, 0,
328 6, 77, 4, 77, 71, 0, 73, 0, 74, 73,
329 0, 81, 75, 52, 77, 0, 81, 75, 52, 81,
330 0, 81, 51, 75, 52, 77, 0, 81, 51, 75,
331 52, 81, 0, 73, 36, 0, 74, 73, 36, 0,
332 24, 0, 75, 45, 24, 0, 81, 78, 0, 76,
333 0, 81, 79, 0, 79, 43, 81, 0, 79, 41,
334 81, 0, 79, 42, 81, 0, 79, 30, 81, 79,
335 0, 79, 31, 81, 79, 0, 79, 41, 81, 79,
336 0, 79, 42, 81, 79, 0, 79, 43, 81, 79,
337 0, 84, 0, 43, 0, 42, 0, 44, 0, 0,
338 81, 43, 0, 83, 0, 83, 41, 0, 83, 42,
339 0, 83, 30, 81, 83, 0, 83, 31, 81, 83,
340 0, 83, 41, 83, 0, 83, 42, 83, 0, 84,
341 0, 85, 0, 21, 85, 0, 86, 85, 0, 86,
342 21, 85, 0, 21, 86, 85, 0, 85, 45, 81,
343 85, 0, 59, 0, 22, 0, 22, 23, 0
349 static const short yyrline[] = { 0,
350 237, 246, 253, 268, 278, 280, 284, 289, 294, 299,
351 304, 309, 314, 320, 326, 331, 336, 341, 346, 351,
352 356, 361, 366, 373, 380, 385, 390, 395, 400, 405,
353 410, 415, 420, 427, 429, 431, 435, 439, 450, 452,
354 456, 458, 460, 497, 499, 501, 503, 505, 507, 509,
355 511, 513, 515, 517, 519, 523, 525, 527, 529, 531,
356 533, 537, 539, 542, 546, 550, 554, 558, 562, 568,
357 570, 572, 576, 580, 583, 587, 594, 596, 598, 603,
358 607, 611, 615, 617, 619, 623, 624, 628, 630, 632,
359 634, 638, 639, 643, 645, 654, 662, 663, 669, 670,
360 677, 681, 683, 685, 692, 694, 696, 700, 701, 702,
361 705, 706, 715, 721, 730, 738, 740, 742, 749, 752,
362 756, 758, 763, 768, 773, 780, 783, 787, 789
367 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
369 static const char * const yytname[] = { "$","error","$undefined.","IF","THEN",
370 "ELSE","ELIF","FI","CASE","ESAC","FOR","SELECT","WHILE","UNTIL","DO","DONE",
371 "FUNCTION","COND_START","COND_END","COND_ERROR","IN","BANG","TIME","TIMEOPT",
372 "WORD","ASSIGNMENT_WORD","NUMBER","ARITH_CMD","ARITH_FOR_EXPRS","COND_CMD","AND_AND",
373 "OR_OR","GREATER_GREATER","LESS_LESS","LESS_AND","GREATER_AND","SEMI_SEMI","LESS_LESS_MINUS",
374 "AND_GREATER","LESS_GREATER","GREATER_BAR","'&'","';'","'\\n'","yacc_EOF","'|'",
375 "'>'","'<'","'-'","'{'","'}'","'('","')'","inputunit","word_list","redirection",
376 "simple_command_element","redirection_list","simple_command","command","shell_command",
377 "for_command","arith_for_command","select_command","case_command","function_def",
378 "subshell","if_command","group_command","arith_command","cond_command","elif_clause",
379 "case_clause","pattern_list","case_clause_sequence","pattern","list","compound_list",
380 "list0","list1","list_terminator","newline_list","simple_list","simple_list1",
381 "pipeline_command","pipeline","timespec", NULL
385 static const short yyr1[] = { 0,
386 53, 53, 53, 53, 54, 54, 55, 55, 55, 55,
387 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
388 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
389 55, 55, 55, 56, 56, 56, 57, 57, 58, 58,
390 59, 59, 59, 60, 60, 60, 60, 60, 60, 60,
391 60, 60, 60, 60, 60, 61, 61, 61, 61, 61,
392 61, 62, 62, 63, 63, 63, 63, 63, 63, 64,
393 64, 64, 65, 65, 65, 66, 67, 67, 67, 68,
394 69, 70, 71, 71, 71, 72, 72, 73, 73, 73,
395 73, 74, 74, 75, 75, 76, 77, 77, 78, 78,
396 78, 79, 79, 79, 79, 79, 79, 80, 80, 80,
397 81, 81, 82, 82, 82, 83, 83, 83, 83, 83,
398 84, 84, 84, 84, 84, 85, 85, 86, 86
401 static const short yyr2[] = { 0,
402 2, 1, 2, 1, 1, 2, 2, 2, 3, 3,
403 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
404 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
405 2, 2, 3, 1, 1, 1, 1, 2, 1, 2,
406 1, 1, 2, 1, 1, 5, 5, 1, 1, 1,
407 1, 1, 1, 1, 1, 6, 6, 7, 7, 10,
408 10, 7, 7, 6, 6, 7, 7, 10, 10, 6,
409 7, 6, 5, 6, 4, 3, 5, 7, 6, 3,
410 1, 3, 4, 6, 5, 1, 2, 4, 4, 5,
411 5, 2, 3, 1, 3, 2, 1, 2, 3, 3,
412 3, 4, 4, 4, 4, 4, 1, 1, 1, 1,
413 0, 2, 1, 2, 2, 4, 4, 3, 3, 1,
414 1, 2, 2, 3, 3, 4, 1, 1, 2
417 static const short yydefact[] = { 0,
418 0, 111, 0, 0, 0, 111, 111, 0, 0, 0,
419 128, 34, 35, 0, 81, 0, 0, 0, 0, 0,
420 0, 0, 0, 2, 4, 0, 0, 111, 111, 36,
421 39, 41, 127, 42, 44, 54, 48, 45, 55, 50,
422 49, 51, 52, 53, 0, 113, 120, 121, 0, 3,
423 97, 0, 0, 111, 111, 0, 111, 0, 0, 111,
424 0, 122, 0, 129, 0, 0, 0, 0, 0, 0,
425 0, 0, 0, 0, 11, 13, 19, 15, 27, 21,
426 17, 25, 23, 29, 31, 32, 7, 8, 0, 0,
427 0, 34, 40, 37, 43, 1, 111, 111, 114, 115,
428 111, 0, 123, 111, 112, 96, 98, 107, 0, 111,
429 0, 109, 108, 110, 111, 111, 0, 111, 111, 0,
430 0, 82, 125, 111, 12, 14, 20, 16, 28, 22,
431 18, 26, 24, 30, 33, 9, 10, 80, 0, 76,
432 38, 0, 0, 118, 119, 0, 124, 0, 111, 111,
433 111, 111, 111, 111, 0, 111, 0, 111, 0, 0,
434 111, 0, 111, 0, 0, 111, 75, 0, 116, 117,
435 0, 0, 126, 111, 111, 77, 0, 0, 0, 100,
436 101, 99, 0, 86, 111, 0, 111, 111, 0, 5,
437 0, 0, 111, 111, 111, 111, 0, 0, 0, 46,
438 47, 0, 73, 0, 0, 79, 102, 103, 104, 105,
439 106, 72, 92, 87, 0, 70, 94, 0, 0, 0,
440 0, 56, 6, 111, 57, 0, 0, 0, 0, 64,
441 111, 65, 74, 78, 111, 111, 111, 111, 93, 71,
442 0, 0, 111, 58, 59, 0, 62, 63, 66, 67,
443 0, 83, 0, 0, 0, 111, 95, 88, 89, 111,
444 111, 111, 111, 111, 85, 90, 91, 0, 0, 0,
445 0, 84, 60, 61, 68, 69, 0, 0, 0
448 static const short yydefgoto[] = { 277,
449 191, 30, 31, 95, 32, 33, 34, 35, 36, 37,
450 38, 39, 40, 41, 42, 43, 44, 177, 183, 184,
451 185, 219, 51, 52, 106, 107, 115, 53, 45, 144,
455 static const short yypact[] = { 256,
456 -9,-32768, 28, 54, 31,-32768,-32768, 38, -14, 382,
457 49, 24,-32768, 188,-32768, 41, 56, 35, 42, 61,
458 73, 75, 100,-32768,-32768, 111, 112,-32768,-32768,-32768,
459 -32768, 171,-32768, 530,-32768,-32768,-32768,-32768,-32768,-32768,
460 -32768,-32768,-32768,-32768, 95, 124,-32768, 59, 424,-32768,
461 -32768, 136, 298,-32768, 104, 64, 107, 137, 142, 106,
462 140, 59, 508,-32768, 108, 135, 138, 45, 55, 139,
463 143, 146, 154, 155,-32768,-32768,-32768,-32768,-32768,-32768,
464 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 114, 298,
465 131,-32768,-32768,-32768, 530,-32768,-32768,-32768, 340, 340,
466 -32768, 508, 59,-32768,-32768,-32768, 80,-32768, -8,-32768,
467 -4,-32768,-32768,-32768,-32768,-32768, -1,-32768,-32768, 132,
468 -11,-32768, 59,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
469 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 80,-32768,
470 -32768, 298, 298, 89, 89, 466, 59, 82,-32768,-32768,
471 -32768,-32768,-32768,-32768, -3,-32768, 156,-32768, 4, 11,
472 -32768, 156,-32768, 170, 177,-32768,-32768, -11,-32768,-32768,
473 340, 340, 59,-32768,-32768,-32768, 179, 298, 298, 298,
474 298, 298, 184, 158,-32768, -2,-32768,-32768, 183,-32768,
475 52, 149,-32768,-32768,-32768,-32768, 186, 52, 152,-32768,
476 -32768, -11,-32768, 208, 212,-32768,-32768,-32768, 101, 101,
477 101,-32768,-32768, 190, 0,-32768,-32768, 200, -31, 215,
478 181,-32768,-32768,-32768,-32768, 218, 191, 221, 194,-32768,
479 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
480 -25, 216,-32768,-32768,-32768, 14,-32768,-32768,-32768,-32768,
481 15, 128, 298, 298, 298,-32768,-32768,-32768, 298,-32768,
482 -32768,-32768,-32768,-32768,-32768,-32768, 298, 230, 196, 232,
483 198,-32768,-32768,-32768,-32768,-32768, 249, 251,-32768
486 static const short yypgoto[] = {-32768,
487 90, -28, 224,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
488 -32768,-32768,-32768,-32768, -118,-32768,-32768, 1,-32768, 76,
489 -32768, 44, -20, -6,-32768, -64, -154, -24,-32768, 5,
497 static const short yytable[] = { 58,
498 59, 47, 167, 90, 46, 94, 216, 89, 240, 156,
499 187, 154, 161, 242, 61, 157, 62, 193, 162, 242,
500 243, 217, 91, 217, 195, 139, 256, 260, 262, 109,
501 111, 105, 117, 50, 105, 121, 224, 28, 105, 105,
502 105, 105, 105, 231, 158, 188, 105, 163, 218, 203,
503 218, 54, 194, 105, 57, 103, 105, 105, 77, 196,
504 78, 60, 261, 263, 75, 80, 141, 81, 127, 123,
505 128, 64, 142, 143, 65, 223, 146, 55, 130, 76,
506 131, 56, 79, 233, 83, 155, 174, 175, 176, 82,
507 159, 160, 129, 112, 113, 114, 84, 148, 85, 168,
508 47, 47, 132, 101, 145, 112, 113, 114, 147, 149,
509 150, 164, 165, 207, 208, 209, 210, 211, 97, 98,
510 151, 152, 153, 86, 178, 179, 180, 181, 182, 186,
511 149, 150, 264, 175, 87, 88, 90, 96, 90, 104,
512 197, 202, 199, 47, 47, 110, 169, 170, 116, 189,
513 118, 192, 173, 97, 98, 119, 120, 122, 125, 124,
514 215, 126, 133, 138, 99, 100, 134, 204, 205, 135,
515 90, 90, 47, 47, 228, 229, 145, 136, 137, 190,
516 220, 221, 140, 166, 200, 206, 226, 227, 209, 210,
517 211, 201, 212, 213, 92, 13, 14, 222, 225, 246,
518 230, 232, 16, 17, 18, 19, 251, 20, 21, 22,
519 23, 253, 254, 255, 234, 235, 26, 27, 259, 66,
520 67, 68, 69, 217, 70, 239, 71, 72, 252, 244,
521 245, 267, 247, 73, 74, 249, 258, 90, 90, 257,
522 248, 270, 271, 250, 273, 274, 275, 276, 278, 266,
523 279, 198, 265, 268, 269, 93, 1, 272, 2, 63,
524 214, 241, 0, 3, 0, 4, 5, 6, 7, 0,
525 0, 8, 9, 0, 0, 0, 10, 11, 0, 12,
526 13, 14, 15, 0, 0, 0, 0, 16, 17, 18,
527 19, 0, 20, 21, 22, 23, 0, 0, 24, 25,
528 2, 26, 27, 0, 28, 3, 29, 4, 5, 6,
529 7, 0, 0, 8, 9, 0, 0, 0, 10, 11,
530 0, 12, 13, 14, 15, 0, 0, 0, 0, 16,
531 17, 18, 19, 0, 20, 21, 22, 23, 0, 0,
532 105, 0, 2, 26, 27, 0, 28, 3, 29, 4,
533 5, 6, 7, 0, 0, 8, 9, 0, 0, 0,
534 10, 11, 0, 12, 13, 14, 15, 0, 0, 0,
535 0, 16, 17, 18, 19, 0, 20, 21, 22, 23,
536 0, 0, 0, 0, 2, 26, 27, 0, 28, 3,
537 29, 4, 5, 6, 7, 0, 0, 8, 9, 0,
538 0, 0, 0, 11, 0, 12, 13, 14, 15, 0,
539 0, 0, 0, 16, 17, 18, 19, 0, 20, 21,
540 22, 23, 0, 0, 0, 0, 2, 26, 27, 0,
541 28, 3, 29, 4, 5, 6, 7, 0, 0, 8,
542 9, 0, 0, 0, 102, 0, 0, 12, 13, 14,
543 15, 0, 0, 0, 0, 16, 17, 18, 19, 0,
544 20, 21, 22, 23, 0, 0, 0, 0, 2, 26,
545 27, 0, 28, 3, 29, 4, 5, 6, 7, 0,
546 0, 8, 9, 0, 0, 0, 0, 0, 0, 12,
547 13, 14, 15, 0, 0, 0, 0, 16, 17, 18,
548 19, 0, 20, 21, 22, 23, 0, 0, 105, 0,
549 2, 26, 27, 0, 28, 3, 29, 4, 5, 6,
550 7, 0, 0, 8, 9, 0, 0, 0, 0, 0,
551 0, 12, 13, 14, 15, 0, 0, 0, 0, 16,
552 17, 18, 19, 0, 20, 21, 22, 23, 0, 0,
553 0, 0, 0, 26, 27, 14, 28, 0, 29, 0,
554 0, 16, 17, 18, 19, 0, 20, 21, 22, 23,
555 0, 0, 0, 0, 0, 26, 27
558 static const short yycheck[] = { 6,
559 7, 0, 121, 28, 0, 34, 9, 28, 9, 14,
560 14, 20, 14, 45, 29, 20, 10, 14, 20, 45,
561 52, 24, 29, 24, 14, 90, 52, 14, 14, 54,
562 55, 43, 57, 43, 43, 60, 191, 49, 43, 43,
563 43, 43, 43, 198, 49, 49, 43, 49, 51, 168,
564 51, 24, 49, 43, 24, 49, 43, 43, 24, 49,
565 26, 24, 49, 49, 24, 24, 95, 26, 24, 63,
566 26, 23, 97, 98, 51, 24, 101, 24, 24, 24,
567 26, 28, 48, 202, 24, 110, 5, 6, 7, 48,
568 115, 116, 48, 42, 43, 44, 24, 104, 24, 124,
569 99, 100, 48, 45, 100, 42, 43, 44, 102, 30,
570 31, 118, 119, 178, 179, 180, 181, 182, 30, 31,
571 41, 42, 43, 24, 149, 150, 151, 152, 153, 154,
572 30, 31, 5, 6, 24, 24, 161, 43, 163, 4,
573 161, 166, 163, 142, 143, 42, 142, 143, 42, 156,
574 14, 158, 146, 30, 31, 14, 51, 18, 24, 52,
575 185, 24, 24, 50, 41, 42, 24, 174, 175, 24,
576 195, 196, 171, 172, 195, 196, 172, 24, 24, 24,
577 187, 188, 52, 52, 15, 7, 193, 194, 253, 254,
578 255, 15, 9, 36, 24, 25, 26, 15, 50, 224,
579 15, 50, 32, 33, 34, 35, 231, 37, 38, 39,
580 40, 236, 237, 238, 7, 4, 46, 47, 243, 32,
581 33, 34, 35, 24, 37, 36, 39, 40, 235, 15,
582 50, 256, 15, 46, 47, 15, 243, 262, 263, 24,
583 50, 262, 263, 50, 15, 50, 15, 50, 0, 256,
584 0, 162, 252, 260, 261, 32, 1, 264, 3, 10,
585 185, 218, -1, 8, -1, 10, 11, 12, 13, -1,
586 -1, 16, 17, -1, -1, -1, 21, 22, -1, 24,
587 25, 26, 27, -1, -1, -1, -1, 32, 33, 34,
588 35, -1, 37, 38, 39, 40, -1, -1, 43, 44,
589 3, 46, 47, -1, 49, 8, 51, 10, 11, 12,
590 13, -1, -1, 16, 17, -1, -1, -1, 21, 22,
591 -1, 24, 25, 26, 27, -1, -1, -1, -1, 32,
592 33, 34, 35, -1, 37, 38, 39, 40, -1, -1,
593 43, -1, 3, 46, 47, -1, 49, 8, 51, 10,
594 11, 12, 13, -1, -1, 16, 17, -1, -1, -1,
595 21, 22, -1, 24, 25, 26, 27, -1, -1, -1,
596 -1, 32, 33, 34, 35, -1, 37, 38, 39, 40,
597 -1, -1, -1, -1, 3, 46, 47, -1, 49, 8,
598 51, 10, 11, 12, 13, -1, -1, 16, 17, -1,
599 -1, -1, -1, 22, -1, 24, 25, 26, 27, -1,
600 -1, -1, -1, 32, 33, 34, 35, -1, 37, 38,
601 39, 40, -1, -1, -1, -1, 3, 46, 47, -1,
602 49, 8, 51, 10, 11, 12, 13, -1, -1, 16,
603 17, -1, -1, -1, 21, -1, -1, 24, 25, 26,
604 27, -1, -1, -1, -1, 32, 33, 34, 35, -1,
605 37, 38, 39, 40, -1, -1, -1, -1, 3, 46,
606 47, -1, 49, 8, 51, 10, 11, 12, 13, -1,
607 -1, 16, 17, -1, -1, -1, -1, -1, -1, 24,
608 25, 26, 27, -1, -1, -1, -1, 32, 33, 34,
609 35, -1, 37, 38, 39, 40, -1, -1, 43, -1,
610 3, 46, 47, -1, 49, 8, 51, 10, 11, 12,
611 13, -1, -1, 16, 17, -1, -1, -1, -1, -1,
612 -1, 24, 25, 26, 27, -1, -1, -1, -1, 32,
613 33, 34, 35, -1, 37, 38, 39, 40, -1, -1,
614 -1, -1, -1, 46, 47, 26, 49, -1, 51, -1,
615 -1, 32, 33, 34, 35, -1, 37, 38, 39, 40,
616 -1, -1, -1, -1, -1, 46, 47
618 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
619 #line 3 "/usr/share/misc/bison.simple"
621 /* Skeleton output parser for bison,
622 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
624 This program is free software; you can redistribute it and/or modify
625 it under the terms of the GNU General Public License as published by
626 the Free Software Foundation; either version 2, or (at your option)
629 This program is distributed in the hope that it will be useful,
630 but WITHOUT ANY WARRANTY; without even the implied warranty of
631 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
632 GNU General Public License for more details.
634 You should have received a copy of the GNU General Public License
635 along with this program; if not, write to the Free Software
636 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
638 /* As a special exception, when this file is copied by Bison into a
639 Bison output file, you may use that output file without restriction.
640 This special exception was added by the Free Software Foundation
641 in version 1.24 of Bison. */
645 #define alloca __builtin_alloca
646 #else /* not GNU C. */
647 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
649 #else /* not sparc */
650 #if defined (MSDOS) && !defined (__TURBOC__)
652 #else /* not MSDOS, or __TURBOC__ */
656 #else /* not MSDOS, __TURBOC__, or _AIX */
660 void *alloca (unsigned int);
662 #else /* not __cplusplus */
664 #endif /* not __cplusplus */
666 #endif /* not _AIX */
667 #endif /* not MSDOS, or __TURBOC__ */
668 #endif /* not sparc. */
669 #endif /* not GNU C. */
670 #endif /* alloca not defined. */
672 /* This is the parser code that is written into each bison parser
673 when the %semantic_parser declaration is not specified in the grammar.
674 It was written by Richard Stallman by simplifying the hairy parser
675 used when %semantic_parser is specified. */
677 /* Note: there must be only one dollar sign in this file.
678 It is replaced by the list of actions, each action
679 as one case of the switch. */
681 #define yyerrok (yyerrstatus = 0)
682 #define yyclearin (yychar = YYEMPTY)
685 #define YYACCEPT return(0)
686 #define YYABORT return(1)
687 #define YYERROR goto yyerrlab1
688 /* Like YYERROR except do call yyerror.
689 This remains here temporarily to ease the
690 transition to the new meaning of YYERROR, for GCC.
691 Once GCC version 2 has supplanted version 1, this can go. */
692 #define YYFAIL goto yyerrlab
693 #define YYRECOVERING() (!!yyerrstatus)
694 #define YYBACKUP(token, value) \
696 if (yychar == YYEMPTY && yylen == 1) \
697 { yychar = (token), yylval = (value); \
698 yychar1 = YYTRANSLATE (yychar); \
703 { yyerror ("syntax error: cannot back up"); YYERROR; } \
707 #define YYERRCODE 256
710 #define YYLEX yylex()
716 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
718 #define YYLEX yylex(&yylval, &yylloc)
720 #else /* not YYLSP_NEEDED */
722 #define YYLEX yylex(&yylval, YYLEX_PARAM)
724 #define YYLEX yylex(&yylval)
726 #endif /* not YYLSP_NEEDED */
729 /* If nonreentrant, generate the variables here */
733 int yychar; /* the lookahead symbol */
734 YYSTYPE yylval; /* the semantic value of the */
735 /* lookahead symbol */
738 YYLTYPE yylloc; /* location data for the lookahead */
742 int yynerrs; /* number of parse errors so far */
743 #endif /* not YYPURE */
746 int yydebug; /* nonzero means print parse trace */
747 /* Since this is uninitialized, it does not stop multiple parsers
751 /* YYINITDEPTH indicates the initial size of the parser's stacks */
754 #define YYINITDEPTH 200
757 /* YYMAXDEPTH is the maximum size the stacks can grow to
758 (effective only if the built-in stack extension method is used). */
765 #define YYMAXDEPTH 10000
768 /* Prevent warning if -Wstrict-prototypes. */
773 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
774 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
775 #else /* not GNU C or C++ */
778 /* This is the most reliable way to avoid incompatibilities
779 in available built-in functions on various systems. */
781 __yy_memcpy (to, from, count)
786 register char *f = from;
787 register char *t = to;
788 register int i = count;
794 #else /* __cplusplus */
796 /* This is the most reliable way to avoid incompatibilities
797 in available built-in functions on various systems. */
799 __yy_memcpy (char *to, char *from, int count)
801 register char *f = from;
802 register char *t = to;
803 register int i = count;
812 #line 196 "/usr/share/misc/bison.simple"
814 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
815 into yyparse. The argument should have type void *.
816 It should actually point to an object.
817 Grammar actions can access the variable by casting it
818 to the proper pointer type. */
822 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
823 #define YYPARSE_PARAM_DECL
824 #else /* not __cplusplus */
825 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
826 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
827 #endif /* not __cplusplus */
828 #else /* not YYPARSE_PARAM */
829 #define YYPARSE_PARAM_ARG
830 #define YYPARSE_PARAM_DECL
831 #endif /* not YYPARSE_PARAM */
834 yyparse(YYPARSE_PARAM_ARG)
837 register int yystate;
839 register short *yyssp;
840 register YYSTYPE *yyvsp;
841 int yyerrstatus; /* number of tokens to shift before error messages enabled */
842 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
844 short yyssa[YYINITDEPTH]; /* the state stack */
845 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
847 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
848 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
851 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
852 YYLTYPE *yyls = yylsa;
855 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
857 #define YYPOPSTACK (yyvsp--, yyssp--)
860 int yystacksize = YYINITDEPTH;
871 YYSTYPE yyval; /* the variable used to return */
872 /* semantic values from the action */
879 fprintf(stderr, "Starting parse\n");
885 yychar = YYEMPTY; /* Cause a token to be read. */
887 /* Initialize stack pointers.
888 Waste one element of value and location stack
889 so that they stay on the same level as the state stack.
890 The wasted elements are never initialized. */
898 /* Push a new state, which is found in yystate . */
899 /* In all cases, when you get here, the value and location stacks
900 have just been pushed. so pushing a state here evens the stacks. */
905 if (yyssp >= yyss + yystacksize - 1)
907 /* Give user a chance to reallocate the stack */
908 /* Use copies of these so that the &'s don't force the real ones into memory. */
909 YYSTYPE *yyvs1 = yyvs;
912 YYLTYPE *yyls1 = yyls;
915 /* Get the current used size of the three stacks, in elements. */
916 int size = yyssp - yyss + 1;
919 /* Each stack pointer address is followed by the size of
920 the data in use in that stack, in bytes. */
922 /* This used to be a conditional around just the two extra args,
923 but that might be undefined if yyoverflow is a macro. */
924 yyoverflow("parser stack overflow",
925 &yyss1, size * sizeof (*yyssp),
926 &yyvs1, size * sizeof (*yyvsp),
927 &yyls1, size * sizeof (*yylsp),
930 yyoverflow("parser stack overflow",
931 &yyss1, size * sizeof (*yyssp),
932 &yyvs1, size * sizeof (*yyvsp),
936 yyss = yyss1; yyvs = yyvs1;
940 #else /* no yyoverflow */
941 /* Extend the stack our own way. */
942 if (yystacksize >= YYMAXDEPTH)
944 yyerror("parser stack overflow");
948 if (yystacksize > YYMAXDEPTH)
949 yystacksize = YYMAXDEPTH;
950 yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
951 __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
952 yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
953 __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
955 yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
956 __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
958 #endif /* no yyoverflow */
960 yyssp = yyss + size - 1;
961 yyvsp = yyvs + size - 1;
963 yylsp = yyls + size - 1;
968 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
971 if (yyssp >= yyss + yystacksize - 1)
977 fprintf(stderr, "Entering state %d\n", yystate);
983 /* Do appropriate processing given the current state. */
984 /* Read a lookahead token if we need one and don't already have one. */
987 /* First try to decide what to do without reference to lookahead token. */
989 yyn = yypact[yystate];
993 /* Not known => get a lookahead token if don't already have one. */
995 /* yychar is either YYEMPTY or YYEOF
996 or a valid token in external form. */
998 if (yychar == YYEMPTY)
1002 fprintf(stderr, "Reading a token: ");
1007 /* Convert token to internal form (in yychar1) for indexing tables with */
1009 if (yychar <= 0) /* This means end of input. */
1012 yychar = YYEOF; /* Don't call YYLEX any more */
1016 fprintf(stderr, "Now at end of input.\n");
1021 yychar1 = YYTRANSLATE(yychar);
1026 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
1027 /* Give the individual parser a way to print the precise meaning
1028 of a token, for further debugging info. */
1030 YYPRINT (stderr, yychar, yylval);
1032 fprintf (stderr, ")\n");
1038 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
1043 /* yyn is what to do for this token type in this state.
1044 Negative => reduce, -yyn is rule number.
1045 Positive => shift, yyn is new state.
1046 New state is final state => don't bother to shift,
1047 just return success.
1048 0, or most negative number => error. */
1063 /* Shift the lookahead token. */
1067 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
1070 /* Discard the token being shifted unless it is eof. */
1071 if (yychar != YYEOF)
1079 /* count tokens shifted since error; after three, turn off error status. */
1080 if (yyerrstatus) yyerrstatus--;
1085 /* Do the default action for the current state. */
1088 yyn = yydefact[yystate];
1092 /* Do a reduction. yyn is the number of a rule to reduce with. */
1096 yyval = yyvsp[1-yylen]; /* implement default value of the action */
1103 fprintf (stderr, "Reducing via rule %d (line %d), ",
1106 /* Print the symbols being reduced, and their result. */
1107 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
1108 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
1109 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
1117 #line 238 "/usr/homes/chet/src/bash/src/parse.y"
1119 /* Case of regular command. Discard the error
1120 safety net,and return the command just parsed. */
1121 global_command = yyvsp[-1].command;
1122 eof_encountered = 0;
1123 discard_parser_constructs (0);
1128 #line 247 "/usr/homes/chet/src/bash/src/parse.y"
1130 /* Case of regular command, but not a very
1131 interesting one. Return a NULL command. */
1132 global_command = (COMMAND *)NULL;
1137 #line 254 "/usr/homes/chet/src/bash/src/parse.y"
1139 /* Error during parsing. Return NULL command. */
1140 global_command = (COMMAND *)NULL;
1141 eof_encountered = 0;
1142 discard_parser_constructs (1);
1154 #line 269 "/usr/homes/chet/src/bash/src/parse.y"
1156 /* Case of EOF seen by itself. Do ignoreeof or
1158 global_command = (COMMAND *)NULL;
1159 handle_eof_input_unit ();
1164 #line 279 "/usr/homes/chet/src/bash/src/parse.y"
1165 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1168 #line 281 "/usr/homes/chet/src/bash/src/parse.y"
1169 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); ;
1172 #line 285 "/usr/homes/chet/src/bash/src/parse.y"
1174 redir.filename = yyvsp[0].word;
1175 yyval.redirect = make_redirection (1, r_output_direction, redir);
1179 #line 290 "/usr/homes/chet/src/bash/src/parse.y"
1181 redir.filename = yyvsp[0].word;
1182 yyval.redirect = make_redirection (0, r_input_direction, redir);
1186 #line 295 "/usr/homes/chet/src/bash/src/parse.y"
1188 redir.filename = yyvsp[0].word;
1189 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
1193 #line 300 "/usr/homes/chet/src/bash/src/parse.y"
1195 redir.filename = yyvsp[0].word;
1196 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
1200 #line 305 "/usr/homes/chet/src/bash/src/parse.y"
1202 redir.filename = yyvsp[0].word;
1203 yyval.redirect = make_redirection (1, r_appending_to, redir);
1207 #line 310 "/usr/homes/chet/src/bash/src/parse.y"
1209 redir.filename = yyvsp[0].word;
1210 yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
1214 #line 315 "/usr/homes/chet/src/bash/src/parse.y"
1216 redir.filename = yyvsp[0].word;
1217 yyval.redirect = make_redirection (0, r_reading_until, redir);
1218 redir_stack[need_here_doc++] = yyval.redirect;
1222 #line 321 "/usr/homes/chet/src/bash/src/parse.y"
1224 redir.filename = yyvsp[0].word;
1225 yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, redir);
1226 redir_stack[need_here_doc++] = yyval.redirect;
1230 #line 327 "/usr/homes/chet/src/bash/src/parse.y"
1232 redir.dest = yyvsp[0].number;
1233 yyval.redirect = make_redirection (0, r_duplicating_input, redir);
1237 #line 332 "/usr/homes/chet/src/bash/src/parse.y"
1239 redir.dest = yyvsp[0].number;
1240 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
1244 #line 337 "/usr/homes/chet/src/bash/src/parse.y"
1246 redir.dest = yyvsp[0].number;
1247 yyval.redirect = make_redirection (1, r_duplicating_output, redir);
1251 #line 342 "/usr/homes/chet/src/bash/src/parse.y"
1253 redir.dest = yyvsp[0].number;
1254 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
1258 #line 347 "/usr/homes/chet/src/bash/src/parse.y"
1260 redir.filename = yyvsp[0].word;
1261 yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
1265 #line 352 "/usr/homes/chet/src/bash/src/parse.y"
1267 redir.filename = yyvsp[0].word;
1268 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
1272 #line 357 "/usr/homes/chet/src/bash/src/parse.y"
1274 redir.filename = yyvsp[0].word;
1275 yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
1279 #line 362 "/usr/homes/chet/src/bash/src/parse.y"
1281 redir.filename = yyvsp[0].word;
1282 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
1286 #line 367 "/usr/homes/chet/src/bash/src/parse.y"
1288 redir.filename = yyvsp[0].word;
1289 yyval.redirect = make_redirection
1290 (0, r_deblank_reading_until, redir);
1291 redir_stack[need_here_doc++] = yyval.redirect;
1295 #line 374 "/usr/homes/chet/src/bash/src/parse.y"
1297 redir.filename = yyvsp[0].word;
1298 yyval.redirect = make_redirection
1299 (yyvsp[-2].number, r_deblank_reading_until, redir);
1300 redir_stack[need_here_doc++] = yyval.redirect;
1304 #line 381 "/usr/homes/chet/src/bash/src/parse.y"
1307 yyval.redirect = make_redirection (1, r_close_this, redir);
1311 #line 386 "/usr/homes/chet/src/bash/src/parse.y"
1314 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1318 #line 391 "/usr/homes/chet/src/bash/src/parse.y"
1321 yyval.redirect = make_redirection (0, r_close_this, redir);
1325 #line 396 "/usr/homes/chet/src/bash/src/parse.y"
1328 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1332 #line 401 "/usr/homes/chet/src/bash/src/parse.y"
1334 redir.filename = yyvsp[0].word;
1335 yyval.redirect = make_redirection (1, r_err_and_out, redir);
1339 #line 406 "/usr/homes/chet/src/bash/src/parse.y"
1341 redir.filename = yyvsp[0].word;
1342 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
1346 #line 411 "/usr/homes/chet/src/bash/src/parse.y"
1348 redir.filename = yyvsp[0].word;
1349 yyval.redirect = make_redirection (0, r_input_output, redir);
1353 #line 416 "/usr/homes/chet/src/bash/src/parse.y"
1355 redir.filename = yyvsp[0].word;
1356 yyval.redirect = make_redirection (1, r_output_force, redir);
1360 #line 421 "/usr/homes/chet/src/bash/src/parse.y"
1362 redir.filename = yyvsp[0].word;
1363 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
1367 #line 428 "/usr/homes/chet/src/bash/src/parse.y"
1368 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1371 #line 430 "/usr/homes/chet/src/bash/src/parse.y"
1372 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1375 #line 432 "/usr/homes/chet/src/bash/src/parse.y"
1376 { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; ;
1379 #line 436 "/usr/homes/chet/src/bash/src/parse.y"
1381 yyval.redirect = yyvsp[0].redirect;
1385 #line 440 "/usr/homes/chet/src/bash/src/parse.y"
1387 register REDIRECT *t;
1389 for (t = yyvsp[-1].redirect; t->next; t = t->next)
1391 t->next = yyvsp[0].redirect;
1392 yyval.redirect = yyvsp[-1].redirect;
1396 #line 451 "/usr/homes/chet/src/bash/src/parse.y"
1397 { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); ;
1400 #line 453 "/usr/homes/chet/src/bash/src/parse.y"
1401 { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); ;
1404 #line 457 "/usr/homes/chet/src/bash/src/parse.y"
1405 { yyval.command = clean_simple_command (yyvsp[0].command); ;
1408 #line 459 "/usr/homes/chet/src/bash/src/parse.y"
1409 { yyval.command = yyvsp[0].command; ;
1412 #line 461 "/usr/homes/chet/src/bash/src/parse.y"
1416 tc = yyvsp[-1].command;
1417 /* According to Posix.2 3.9.5, redirections
1418 specified after the body of a function should
1419 be attached to the function and performed when
1420 the function is executed, not as part of the
1421 function definition command. */
1422 /* XXX - I don't think it matters, but we might
1423 want to change this in the future to avoid
1424 problems differentiating between a function
1425 definition with a redirection and a function
1426 definition containing a single command with a
1427 redirection. The two are semantically equivalent,
1428 though -- the only difference is in how the
1429 command printing code displays the redirections. */
1430 if (tc->type == cm_function_def)
1432 tc = tc->value.Function_def->command;
1433 if (tc->type == cm_group)
1434 tc = tc->value.Group->command;
1438 register REDIRECT *t;
1439 for (t = tc->redirects; t->next; t = t->next)
1441 t->next = yyvsp[0].redirect;
1444 tc->redirects = yyvsp[0].redirect;
1445 yyval.command = yyvsp[-1].command;
1449 #line 498 "/usr/homes/chet/src/bash/src/parse.y"
1450 { yyval.command = yyvsp[0].command; ;
1453 #line 500 "/usr/homes/chet/src/bash/src/parse.y"
1454 { yyval.command = yyvsp[0].command; ;
1457 #line 502 "/usr/homes/chet/src/bash/src/parse.y"
1458 { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); ;
1461 #line 504 "/usr/homes/chet/src/bash/src/parse.y"
1462 { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); ;
1465 #line 506 "/usr/homes/chet/src/bash/src/parse.y"
1466 { yyval.command = yyvsp[0].command; ;
1469 #line 508 "/usr/homes/chet/src/bash/src/parse.y"
1470 { yyval.command = yyvsp[0].command; ;
1473 #line 510 "/usr/homes/chet/src/bash/src/parse.y"
1474 { yyval.command = yyvsp[0].command; ;
1477 #line 512 "/usr/homes/chet/src/bash/src/parse.y"
1478 { yyval.command = yyvsp[0].command; ;
1481 #line 514 "/usr/homes/chet/src/bash/src/parse.y"
1482 { yyval.command = yyvsp[0].command; ;
1485 #line 516 "/usr/homes/chet/src/bash/src/parse.y"
1486 { yyval.command = yyvsp[0].command; ;
1489 #line 518 "/usr/homes/chet/src/bash/src/parse.y"
1490 { yyval.command = yyvsp[0].command; ;
1493 #line 520 "/usr/homes/chet/src/bash/src/parse.y"
1494 { yyval.command = yyvsp[0].command; ;
1497 #line 524 "/usr/homes/chet/src/bash/src/parse.y"
1498 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1501 #line 526 "/usr/homes/chet/src/bash/src/parse.y"
1502 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1505 #line 528 "/usr/homes/chet/src/bash/src/parse.y"
1506 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1509 #line 530 "/usr/homes/chet/src/bash/src/parse.y"
1510 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1513 #line 532 "/usr/homes/chet/src/bash/src/parse.y"
1514 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1517 #line 534 "/usr/homes/chet/src/bash/src/parse.y"
1518 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1521 #line 538 "/usr/homes/chet/src/bash/src/parse.y"
1522 { yyval.command = make_arith_for_command (yyvsp[-5].word_list, yyvsp[-1].command, arith_for_lineno); ;
1525 #line 540 "/usr/homes/chet/src/bash/src/parse.y"
1526 { yyval.command = make_arith_for_command (yyvsp[-5].word_list, yyvsp[-1].command, arith_for_lineno); ;
1529 #line 543 "/usr/homes/chet/src/bash/src/parse.y"
1531 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1535 #line 547 "/usr/homes/chet/src/bash/src/parse.y"
1537 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command);
1541 #line 551 "/usr/homes/chet/src/bash/src/parse.y"
1543 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1547 #line 555 "/usr/homes/chet/src/bash/src/parse.y"
1549 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1553 #line 559 "/usr/homes/chet/src/bash/src/parse.y"
1555 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1559 #line 563 "/usr/homes/chet/src/bash/src/parse.y"
1561 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1565 #line 569 "/usr/homes/chet/src/bash/src/parse.y"
1566 { yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL); ;
1569 #line 571 "/usr/homes/chet/src/bash/src/parse.y"
1570 { yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern); ;
1573 #line 573 "/usr/homes/chet/src/bash/src/parse.y"
1574 { yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern); ;
1577 #line 577 "/usr/homes/chet/src/bash/src/parse.y"
1578 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1581 #line 581 "/usr/homes/chet/src/bash/src/parse.y"
1582 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1585 #line 584 "/usr/homes/chet/src/bash/src/parse.y"
1586 { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command, function_dstart, function_bstart); ;
1589 #line 588 "/usr/homes/chet/src/bash/src/parse.y"
1591 yyval.command = make_subshell_command (yyvsp[-1].command);
1592 yyval.command->flags |= CMD_WANT_SUBSHELL;
1596 #line 595 "/usr/homes/chet/src/bash/src/parse.y"
1597 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); ;
1600 #line 597 "/usr/homes/chet/src/bash/src/parse.y"
1601 { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); ;
1604 #line 599 "/usr/homes/chet/src/bash/src/parse.y"
1605 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); ;
1608 #line 604 "/usr/homes/chet/src/bash/src/parse.y"
1609 { yyval.command = make_group_command (yyvsp[-1].command); ;
1612 #line 608 "/usr/homes/chet/src/bash/src/parse.y"
1613 { yyval.command = make_arith_command (yyvsp[0].word_list); ;
1616 #line 612 "/usr/homes/chet/src/bash/src/parse.y"
1617 { yyval.command = yyvsp[-1].command; ;
1620 #line 616 "/usr/homes/chet/src/bash/src/parse.y"
1621 { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); ;
1624 #line 618 "/usr/homes/chet/src/bash/src/parse.y"
1625 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); ;
1628 #line 620 "/usr/homes/chet/src/bash/src/parse.y"
1629 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); ;
1632 #line 625 "/usr/homes/chet/src/bash/src/parse.y"
1633 { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
1636 #line 629 "/usr/homes/chet/src/bash/src/parse.y"
1637 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1640 #line 631 "/usr/homes/chet/src/bash/src/parse.y"
1641 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1644 #line 633 "/usr/homes/chet/src/bash/src/parse.y"
1645 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1648 #line 635 "/usr/homes/chet/src/bash/src/parse.y"
1649 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1652 #line 640 "/usr/homes/chet/src/bash/src/parse.y"
1653 { yyvsp[-1].pattern->next = yyvsp[-2].pattern; yyval.pattern = yyvsp[-1].pattern; ;
1656 #line 644 "/usr/homes/chet/src/bash/src/parse.y"
1657 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1660 #line 646 "/usr/homes/chet/src/bash/src/parse.y"
1661 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); ;
1664 #line 655 "/usr/homes/chet/src/bash/src/parse.y"
1666 yyval.command = yyvsp[0].command;
1668 gather_here_documents ();
1672 #line 664 "/usr/homes/chet/src/bash/src/parse.y"
1674 yyval.command = yyvsp[0].command;
1678 #line 671 "/usr/homes/chet/src/bash/src/parse.y"
1680 if (yyvsp[-2].command->type == cm_connection)
1681 yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
1683 yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
1687 #line 682 "/usr/homes/chet/src/bash/src/parse.y"
1688 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1691 #line 684 "/usr/homes/chet/src/bash/src/parse.y"
1692 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1695 #line 686 "/usr/homes/chet/src/bash/src/parse.y"
1697 if (yyvsp[-3].command->type == cm_connection)
1698 yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
1700 yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
1704 #line 693 "/usr/homes/chet/src/bash/src/parse.y"
1705 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1708 #line 695 "/usr/homes/chet/src/bash/src/parse.y"
1709 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1712 #line 697 "/usr/homes/chet/src/bash/src/parse.y"
1713 { yyval.command = yyvsp[0].command; ;
1716 #line 716 "/usr/homes/chet/src/bash/src/parse.y"
1718 yyval.command = yyvsp[0].command;
1720 gather_here_documents ();
1724 #line 722 "/usr/homes/chet/src/bash/src/parse.y"
1726 if (yyvsp[-1].command->type == cm_connection)
1727 yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
1729 yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
1731 gather_here_documents ();
1735 #line 731 "/usr/homes/chet/src/bash/src/parse.y"
1737 yyval.command = yyvsp[-1].command;
1739 gather_here_documents ();
1743 #line 739 "/usr/homes/chet/src/bash/src/parse.y"
1744 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1747 #line 741 "/usr/homes/chet/src/bash/src/parse.y"
1748 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1751 #line 743 "/usr/homes/chet/src/bash/src/parse.y"
1753 if (yyvsp[-2].command->type == cm_connection)
1754 yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
1756 yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
1760 #line 750 "/usr/homes/chet/src/bash/src/parse.y"
1761 { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); ;
1764 #line 753 "/usr/homes/chet/src/bash/src/parse.y"
1765 { yyval.command = yyvsp[0].command; ;
1768 #line 757 "/usr/homes/chet/src/bash/src/parse.y"
1769 { yyval.command = yyvsp[0].command; ;
1772 #line 759 "/usr/homes/chet/src/bash/src/parse.y"
1774 yyvsp[0].command->flags |= CMD_INVERT_RETURN;
1775 yyval.command = yyvsp[0].command;
1779 #line 764 "/usr/homes/chet/src/bash/src/parse.y"
1781 yyvsp[0].command->flags |= yyvsp[-1].number;
1782 yyval.command = yyvsp[0].command;
1786 #line 769 "/usr/homes/chet/src/bash/src/parse.y"
1788 yyvsp[0].command->flags |= yyvsp[-2].number|CMD_INVERT_RETURN;
1789 yyval.command = yyvsp[0].command;
1793 #line 774 "/usr/homes/chet/src/bash/src/parse.y"
1795 yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
1796 yyval.command = yyvsp[0].command;
1800 #line 782 "/usr/homes/chet/src/bash/src/parse.y"
1801 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); ;
1804 #line 784 "/usr/homes/chet/src/bash/src/parse.y"
1805 { yyval.command = yyvsp[0].command; ;
1808 #line 788 "/usr/homes/chet/src/bash/src/parse.y"
1809 { yyval.number = CMD_TIME_PIPELINE; ;
1812 #line 790 "/usr/homes/chet/src/bash/src/parse.y"
1813 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; ;
1816 /* the action file gets copied in in place of this dollarsign */
1817 #line 498 "/usr/share/misc/bison.simple"
1828 short *ssp1 = yyss - 1;
1829 fprintf (stderr, "state stack now");
1830 while (ssp1 != yyssp)
1831 fprintf (stderr, " %d", *++ssp1);
1832 fprintf (stderr, "\n");
1842 yylsp->first_line = yylloc.first_line;
1843 yylsp->first_column = yylloc.first_column;
1844 yylsp->last_line = (yylsp-1)->last_line;
1845 yylsp->last_column = (yylsp-1)->last_column;
1850 yylsp->last_line = (yylsp+yylen-1)->last_line;
1851 yylsp->last_column = (yylsp+yylen-1)->last_column;
1855 /* Now "shift" the result of the reduction.
1856 Determine what state that goes to,
1857 based on the state we popped back to
1858 and the rule number reduced by. */
1862 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1863 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1864 yystate = yytable[yystate];
1866 yystate = yydefgoto[yyn - YYNTBASE];
1870 yyerrlab: /* here on detecting error */
1873 /* If not already recovering from an error, report this error. */
1877 #ifdef YYERROR_VERBOSE
1878 yyn = yypact[yystate];
1880 if (yyn > YYFLAG && yyn < YYLAST)
1887 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1888 for (x = (yyn < 0 ? -yyn : 0);
1889 x < (sizeof(yytname) / sizeof(char *)); x++)
1890 if (yycheck[x + yyn] == x)
1891 size += strlen(yytname[x]) + 15, count++;
1892 msg = (char *) malloc(size + 15);
1895 strcpy(msg, "parse error");
1900 for (x = (yyn < 0 ? -yyn : 0);
1901 x < (sizeof(yytname) / sizeof(char *)); x++)
1902 if (yycheck[x + yyn] == x)
1904 strcat(msg, count == 0 ? ", expecting `" : " or `");
1905 strcat(msg, yytname[x]);
1914 yyerror ("parse error; also virtual memory exceeded");
1917 #endif /* YYERROR_VERBOSE */
1918 yyerror("parse error");
1922 yyerrlab1: /* here on error raised explicitly by an action */
1924 if (yyerrstatus == 3)
1926 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1928 /* return failure if at end of input */
1929 if (yychar == YYEOF)
1934 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1940 /* Else will try to reuse lookahead token
1941 after shifting the error token. */
1943 yyerrstatus = 3; /* Each real token shifted decrements this */
1947 yyerrdefault: /* current state does not do anything special for the error token. */
1950 /* This is wrong; only states that explicitly want error tokens
1951 should shift them. */
1952 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1953 if (yyn) goto yydefault;
1956 yyerrpop: /* pop the current state because it cannot handle the error token */
1958 if (yyssp == yyss) YYABORT;
1968 short *ssp1 = yyss - 1;
1969 fprintf (stderr, "Error: state stack now");
1970 while (ssp1 != yyssp)
1971 fprintf (stderr, " %d", *++ssp1);
1972 fprintf (stderr, "\n");
1978 yyn = yypact[yystate];
1983 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
2002 fprintf(stderr, "Shifting error token, ");
2013 #line 792 "/usr/homes/chet/src/bash/src/parse.y"
2016 /* Possible states for the parser that require it to do special things. */
2017 #define PST_CASEPAT 0x001 /* in a case pattern list */
2018 #define PST_ALEXPNEXT 0x002 /* expand next word for aliases */
2019 #define PST_ALLOWOPNBRC 0x004 /* allow open brace for function def */
2020 #define PST_NEEDCLOSBRC 0x008 /* need close brace */
2021 #define PST_DBLPAREN 0x010 /* double-paren parsing */
2022 #define PST_SUBSHELL 0x020 /* ( ... ) subshell */
2023 #define PST_CMDSUBST 0x040 /* $( ... ) command substitution */
2024 #define PST_CASESTMT 0x080 /* parsing a case statement */
2025 #define PST_CONDCMD 0x100 /* parsing a [[...]] command */
2026 #define PST_CONDEXPR 0x200 /* parsing the guts of [[...]] */
2027 #define PST_ARITHFOR 0x400 /* parsing an arithmetic for command */
2029 /* Initial size to allocate for tokens, and the
2030 amount to grow them by. */
2031 #define TOKEN_DEFAULT_INITIAL_SIZE 496
2032 #define TOKEN_DEFAULT_GROW_SIZE 512
2034 /* Shell meta-characters that, when unquoted, separate words. */
2035 #define shellmeta(c) (strchr (shell_meta_chars, (c)) != 0)
2036 #define shellbreak(c) (strchr (shell_break_chars, (c)) != 0)
2037 #define shellquote(c) ((c) == '"' || (c) == '`' || (c) == '\'')
2038 #define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>')
2040 char *shell_meta_chars = "()<>;&|";
2041 char *shell_break_chars = "()<>;&| \t\n";
2043 /* The token currently being read. */
2044 static int current_token;
2046 /* The last read token, or NULL. read_token () uses this for context
2048 static int last_read_token;
2050 /* The token read prior to last_read_token. */
2051 static int token_before_that;
2053 /* The token read prior to token_before_that. */
2054 static int two_tokens_ago;
2056 /* If non-zero, it is the token that we want read_token to return
2057 regardless of what text is (or isn't) present to be read. This
2058 is reset by read_token. If token_to_read == WORD or
2059 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
2060 static int token_to_read;
2061 static WORD_DESC *word_desc_to_read;
2063 /* The current parser state. */
2064 static int parser_state;
2066 /* Global var is non-zero when end of file has been reached. */
2067 int EOF_Reached = 0;
2078 /* yy_getc () returns the next available character from input or EOF.
2079 yy_ungetc (c) makes `c' the next character to read.
2080 init_yy_io (get, unget, type, location) makes the function GET the
2081 installed function for getting the next character, makes UNGET the
2082 installed function for un-getting a character, sets the type of stream
2083 (either string or file) from TYPE, and makes LOCATION point to where
2084 the input is coming from. */
2086 /* Unconditionally returns end-of-file. */
2093 /* Variable containing the current get and unget functions.
2094 See ./input.h for a clearer description. */
2095 BASH_INPUT bash_input;
2097 /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
2098 is non-null, avoiding a memory leak. */
2100 initialize_bash_input ()
2102 bash_input.type = st_none;
2103 FREE (bash_input.name);
2104 bash_input.name = (char *)NULL;
2105 bash_input.location.file = (FILE *)NULL;
2106 bash_input.location.string = (char *)NULL;
2107 bash_input.getter = (Function *)NULL;
2108 bash_input.ungetter = (Function *)NULL;
2111 /* Set the contents of the current bash input stream from
2112 GET, UNGET, TYPE, NAME, and LOCATION. */
2114 init_yy_io (get, unget, type, name, location)
2115 Function *get, *unget;
2116 enum stream_type type;
2118 INPUT_STREAM location;
2120 bash_input.type = type;
2121 FREE (bash_input.name);
2122 bash_input.name = name ? savestring (name) : (char *)NULL;
2126 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
2128 bash_input.location = location;
2130 bash_input.getter = get;
2131 bash_input.ungetter = unget;
2134 /* Call this to get the next character of input. */
2138 return (*(bash_input.getter)) ();
2141 /* Call this to unget C. That is, to make C the next character
2147 return (*(bash_input.ungetter)) (c);
2150 #if defined (BUFFERED_INPUT)
2152 input_file_descriptor ()
2154 switch (bash_input.type)
2157 return (fileno (bash_input.location.file));
2159 return (bash_input.location.buffered_fd);
2162 return (fileno (stdin));
2165 #endif /* BUFFERED_INPUT */
2167 /* **************************************************************** */
2169 /* Let input be read from readline (). */
2171 /* **************************************************************** */
2173 #if defined (READLINE)
2174 char *current_readline_prompt = (char *)NULL;
2175 char *current_readline_line = (char *)NULL;
2176 int current_readline_line_index = 0;
2181 SigHandler *old_sigint;
2184 if (!current_readline_line)
2186 if (!bash_readline_initialized)
2187 initialize_readline ();
2189 #if defined (JOB_CONTROL)
2191 give_terminal_to (shell_pgrp);
2192 #endif /* JOB_CONTROL */
2194 if (signal_is_ignored (SIGINT) == 0)
2196 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
2197 interrupt_immediately++;
2200 current_readline_line = readline (current_readline_prompt ?
2201 current_readline_prompt : "");
2203 if (signal_is_ignored (SIGINT) == 0)
2205 interrupt_immediately--;
2206 set_signal_handler (SIGINT, old_sigint);
2210 /* Reset the prompt to the decoded value of prompt_string_pointer. */
2211 reset_readline_prompt ();
2214 if (current_readline_line == 0)
2217 current_readline_line_index = 0;
2218 line_len = strlen (current_readline_line);
2220 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
2221 current_readline_line[line_len++] = '\n';
2222 current_readline_line[line_len] = '\0';
2225 if (current_readline_line[current_readline_line_index] == 0)
2227 free (current_readline_line);
2228 current_readline_line = (char *)NULL;
2229 return (yy_readline_get ());
2233 c = (unsigned char)current_readline_line[current_readline_line_index++];
2239 yy_readline_unget (c)
2242 if (current_readline_line_index && current_readline_line)
2243 current_readline_line[--current_readline_line_index] = c;
2248 with_input_from_stdin ()
2250 INPUT_STREAM location;
2252 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
2254 location.string = current_readline_line;
2255 init_yy_io (yy_readline_get, yy_readline_unget,
2256 st_stdin, "readline stdin", location);
2260 #else /* !READLINE */
2263 with_input_from_stdin ()
2265 with_input_from_stream (stdin, "stdin");
2267 #endif /* !READLINE */
2269 /* **************************************************************** */
2271 /* Let input come from STRING. STRING is zero terminated. */
2273 /* **************************************************************** */
2278 register char *string;
2281 string = bash_input.location.string;
2284 /* If the string doesn't exist, or is empty, EOF found. */
2285 if (string && *string)
2287 c = *(unsigned char *)string++;
2288 bash_input.location.string = string;
2297 *(--bash_input.location.string) = c;
2302 with_input_from_string (string, name)
2303 char *string, *name;
2305 INPUT_STREAM location;
2307 location.string = string;
2308 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
2311 /* **************************************************************** */
2313 /* Let input come from STREAM. */
2315 /* **************************************************************** */
2317 /* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
2318 define, and just use getc/ungetc if it was defined, but since bash
2319 installs its signal handlers without the SA_RESTART flag, some signals
2320 (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
2321 the read to be restarted. We need to restart it ourselves. */
2329 if (bash_input.location.file)
2330 result = getc_with_restart (bash_input.location.file);
2339 return (ungetc_with_restart (c, bash_input.location.file));
2343 with_input_from_stream (stream, name)
2347 INPUT_STREAM location;
2349 location.file = stream;
2350 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
2353 typedef struct stream_saver {
2354 struct stream_saver *next;
2355 BASH_INPUT bash_input;
2357 #if defined (BUFFERED_INPUT)
2358 BUFFERED_STREAM *bstream;
2359 #endif /* BUFFERED_INPUT */
2362 /* The globally known line number. */
2363 int line_number = 0;
2365 #if defined (COND_COMMAND)
2366 static int cond_lineno;
2367 static int cond_token;
2370 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
2373 push_stream (reset_lineno)
2376 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
2378 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
2380 #if defined (BUFFERED_INPUT)
2381 saver->bstream = (BUFFERED_STREAM *)NULL;
2382 /* If we have a buffered stream, clear out buffers[fd]. */
2383 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2384 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
2385 (BUFFERED_STREAM *)NULL);
2386 #endif /* BUFFERED_INPUT */
2388 saver->line = line_number;
2389 bash_input.name = (char *)NULL;
2390 saver->next = stream_list;
2391 stream_list = saver;
2404 STREAM_SAVER *saver = stream_list;
2407 stream_list = stream_list->next;
2409 init_yy_io (saver->bash_input.getter,
2410 saver->bash_input.ungetter,
2411 saver->bash_input.type,
2412 saver->bash_input.name,
2413 saver->bash_input.location);
2415 #if defined (BUFFERED_INPUT)
2416 /* If we have a buffered stream, restore buffers[fd]. */
2417 /* If the input file descriptor was changed while this was on the
2418 save stack, update the buffered fd to the new file descriptor and
2419 re-establish the buffer <-> bash_input fd correspondence. */
2420 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2422 if (bash_input_fd_changed)
2424 bash_input_fd_changed = 0;
2425 if (default_buffered_input >= 0)
2427 bash_input.location.buffered_fd = default_buffered_input;
2428 saver->bstream->b_fd = default_buffered_input;
2431 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
2433 #endif /* BUFFERED_INPUT */
2435 line_number = saver->line;
2437 FREE (saver->bash_input.name);
2442 /* Return 1 if a stream of type TYPE is saved on the stack. */
2444 stream_on_stack (type)
2445 enum stream_type type;
2447 register STREAM_SAVER *s;
2449 for (s = stream_list; s; s = s->next)
2450 if (s->bash_input.type == type)
2455 /* Save the current token state and return it in a malloced array. */
2461 ret = (int *)xmalloc (3 * sizeof (int));
2462 ret[0] = last_read_token;
2463 ret[1] = token_before_that;
2464 ret[2] = two_tokens_ago;
2469 restore_token_state (ts)
2474 last_read_token = ts[0];
2475 token_before_that = ts[1];
2476 two_tokens_ago = ts[2];
2480 * This is used to inhibit alias expansion and reserved word recognition
2481 * inside case statement pattern lists. A `case statement pattern list' is:
2483 * everything between the `in' in a `case word in' and the next ')'
2485 * everything between a `;;' and the next `)' or `esac'
2488 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2490 #if !defined (ALIAS)
2491 typedef void *alias_t;
2494 #define END_OF_ALIAS 0
2497 * Pseudo-global variables used in implementing token-wise alias expansion.
2501 * Pushing and popping strings. This works together with shell_getc to
2502 * implement alias expansion on a per-token basis.
2505 typedef struct string_saver {
2506 struct string_saver *next;
2507 int expand_alias; /* Value to set expand_alias to when string is popped. */
2510 alias_t *expander; /* alias that caused this line to be pushed. */
2512 int saved_line_size, saved_line_index, saved_line_terminator;
2515 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
2518 * Push the current shell_input_line onto a stack of such lines and make S
2519 * the current input. Used when expanding aliases. EXPAND is used to set
2520 * the value of expand_next_token when the string is popped, so that the
2521 * word after the alias in the original line is handled correctly when the
2522 * alias expands to multiple words. TOKEN is the token that was expanded
2523 * into S; it is saved and used to prevent infinite recursive expansion.
2526 push_string (s, expand, ap)
2531 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
2533 temp->expand_alias = expand;
2534 temp->saved_line = shell_input_line;
2535 temp->saved_line_size = shell_input_line_size;
2536 temp->saved_line_index = shell_input_line_index;
2537 temp->saved_line_terminator = shell_input_line_terminator;
2539 temp->expander = ap;
2541 temp->next = pushed_string_list;
2542 pushed_string_list = temp;
2546 ap->flags |= AL_BEINGEXPANDED;
2549 shell_input_line = s;
2550 shell_input_line_size = strlen (s);
2551 shell_input_line_index = 0;
2552 shell_input_line_terminator = '\0';
2553 parser_state &= ~PST_ALEXPNEXT;
2557 * Make the top of the pushed_string stack be the current shell input.
2558 * Only called when there is something on the stack. Called from shell_getc
2559 * when it thinks it has consumed the string generated by an alias expansion
2560 * and needs to return to the original input line.
2567 FREE (shell_input_line);
2568 shell_input_line = pushed_string_list->saved_line;
2569 shell_input_line_index = pushed_string_list->saved_line_index;
2570 shell_input_line_size = pushed_string_list->saved_line_size;
2571 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
2573 if (pushed_string_list->expand_alias)
2574 parser_state |= PST_ALEXPNEXT;
2576 parser_state &= ~PST_ALEXPNEXT;
2578 t = pushed_string_list;
2579 pushed_string_list = pushed_string_list->next;
2583 t->expander->flags &= ~AL_BEINGEXPANDED;
2592 register STRING_SAVER *t, *t1;
2594 for (t = pushed_string_list; t; )
2597 FREE (t->saved_line);
2600 t->expander->flags &= ~AL_BEINGEXPANDED;
2605 pushed_string_list = (STRING_SAVER *)NULL;
2608 #endif /* ALIAS || DPAREN_ARITHMETIC */
2610 /* Return a line of text, taken from wherever yylex () reads input.
2611 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
2612 is non-zero, we remove unquoted \<newline> pairs. This is used by
2613 read_secondary_line to read here documents. */
2615 read_a_line (remove_quoted_newline)
2616 int remove_quoted_newline;
2618 static char *line_buffer = (char *)NULL;
2619 static int buffer_size = 0;
2620 int indx = 0, c, peekc, pass_next;
2622 #if defined (READLINE)
2623 if (interactive && bash_input.type != st_string && no_line_editing)
2625 if (interactive && bash_input.type != st_string)
2634 /* Allow immediate exit if interrupted during input. */
2640 /* If there is no more input, then we return NULL. */
2643 if (interactive && bash_input.type == st_stream)
2646 return ((char *)NULL);
2650 /* `+2' in case the final character in the buffer is a newline. */
2651 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
2653 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
2654 here document with an unquoted delimiter. In this case,
2655 the line will be expanded as if it were in double quotes.
2656 We allow a backslash to escape the next character, but we
2657 need to treat the backslash specially only if a backslash
2658 quoting a backslash-newline pair appears in the line. */
2661 line_buffer[indx++] = c;
2664 else if (c == '\\' && remove_quoted_newline)
2668 continue; /* Make the unquoted \<newline> pair disappear. */
2673 line_buffer[indx++] = c; /* Preserve the backslash. */
2677 line_buffer[indx++] = c;
2681 line_buffer[indx] = '\0';
2682 return (line_buffer);
2687 /* Return a line as in read_a_line (), but insure that the prompt is
2688 the secondary prompt. This is used to read the lines of a here
2689 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2690 newlines quoted with backslashes while reading the line. It is
2691 non-zero unless the delimiter of the here document was quoted. */
2693 read_secondary_line (remove_quoted_newline)
2694 int remove_quoted_newline;
2696 prompt_string_pointer = &ps2_prompt;
2698 return (read_a_line (remove_quoted_newline));
2701 /* **************************************************************** */
2705 /* **************************************************************** */
2707 /* Reserved words. These are only recognized as the first word of a
2709 STRING_INT_ALIST word_token_alist[] = {
2718 #if defined (SELECT_COMMAND)
2719 { "select", SELECT },
2726 { "function", FUNCTION },
2727 #if defined (COMMAND_TIMING)
2733 #if defined (COND_COMMAND)
2734 { "[[", COND_START },
2740 /* XXX - we should also have an alist with strings for other tokens, so we
2741 can give more descriptive error messages. Look at y.tab.h for the
2744 /* These are used by read_token_word, but appear up here so that shell_getc
2745 can use them to decide when to add otherwise blank lines to the history. */
2747 /* The primary delimiter stack. */
2748 struct dstack dstack = { (char *)NULL, 0, 0 };
2750 /* A temporary delimiter stack to be used when decoding prompt strings.
2751 This is needed because command substitutions in prompt strings (e.g., PS2)
2752 can screw up the parser's quoting state. */
2753 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2755 /* Macro for accessing the top delimiter on the stack. Returns the
2756 delimiter or zero if none. */
2757 #define current_delimiter(ds) \
2758 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2760 #define push_delimiter(ds, character) \
2763 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2764 ds.delimiters = xrealloc \
2765 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2766 ds.delimiters[ds.delimiter_depth] = character; \
2767 ds.delimiter_depth++; \
2771 #define pop_delimiter(ds) ds.delimiter_depth--
2773 /* Return the next shell input character. This always reads characters
2774 from shell_input_line; when that line is exhausted, it is time to
2775 read the next line. This is called by read_token when the shell is
2776 processing normal command input. */
2779 shell_getc (remove_quoted_newline)
2780 int remove_quoted_newline;
2784 static int mustpop = 0;
2788 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2789 /* If shell_input_line[shell_input_line_index] == 0, but there is
2790 something on the pushed list of strings, then we don't want to go
2791 off and get another line. We let the code down below handle it. */
2793 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2794 (pushed_string_list == (STRING_SAVER *)NULL)))
2795 #else /* !ALIAS && !DPAREN_ARITHMETIC */
2796 if (!shell_input_line || !shell_input_line[shell_input_line_index])
2797 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
2803 /* Allow immediate exit if interrupted during input. */
2807 shell_input_line_terminator = 0;
2809 #if defined (JOB_CONTROL)
2810 /* This can cause a problem when reading a command as the result
2811 of a trap, when the trap is called from flush_child. This call
2812 had better not cause jobs to disappear from the job table in
2813 that case, or we will have big trouble. */
2814 notify_and_cleanup ();
2815 #else /* !JOB_CONTROL */
2816 cleanup_dead_jobs ();
2817 #endif /* !JOB_CONTROL */
2819 #if defined (READLINE)
2820 if (interactive && bash_input.type != st_string && no_line_editing)
2822 if (interactive && bash_input.type != st_string)
2826 if (bash_input.type == st_stream)
2829 while (c = yy_getc ())
2831 /* Allow immediate exit if interrupted during input. */
2834 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2838 if (bash_input.type == st_stream)
2842 shell_input_line_terminator = EOF;
2844 shell_input_line[i] = '\0';
2848 shell_input_line[i++] = c;
2852 shell_input_line[--i] = '\0';
2853 current_command_line_count++;
2857 shell_input_line_index = 0;
2858 shell_input_line_len = i; /* == strlen (shell_input_line) */
2860 #if defined (HISTORY)
2861 if (remember_on_history && shell_input_line && shell_input_line[0])
2864 # if defined (BANG_HISTORY)
2867 /* If the current delimiter is a single quote, we should not be
2868 performing history expansion, even if we're on a different
2869 line from the original single quote. */
2870 old_hist = history_expansion_inhibited;
2871 if (current_delimiter (dstack) == '\'')
2872 history_expansion_inhibited = 1;
2874 expansions = pre_process_line (shell_input_line, 1, 1);
2875 # if defined (BANG_HISTORY)
2876 history_expansion_inhibited = old_hist;
2878 if (expansions != shell_input_line)
2880 free (shell_input_line);
2881 shell_input_line = expansions;
2882 shell_input_line_len = shell_input_line ?
2883 strlen (shell_input_line) : 0;
2884 if (!shell_input_line_len)
2885 current_command_line_count--;
2887 /* We have to force the xrealloc below because we don't know
2888 the true allocated size of shell_input_line anymore. */
2889 shell_input_line_size = shell_input_line_len;
2892 /* XXX - this is grotesque */
2893 else if (remember_on_history && shell_input_line &&
2894 shell_input_line[0] == '\0' &&
2895 current_command_line_count > 1 && current_delimiter (dstack))
2897 /* We know shell_input_line[0] == 0 and we're reading some sort of
2898 quoted string. This means we've got a line consisting of only
2899 a newline in a quoted string. We want to make sure this line
2900 gets added to the history. */
2901 maybe_add_history (shell_input_line);
2904 #endif /* HISTORY */
2906 if (shell_input_line)
2908 /* Lines that signify the end of the shell's input should not be
2910 if (echo_input_at_read && (shell_input_line[0] ||
2911 shell_input_line_terminator != EOF))
2912 fprintf (stderr, "%s\n", shell_input_line);
2916 shell_input_line_size = 0;
2917 prompt_string_pointer = ¤t_prompt_string;
2922 /* Add the newline to the end of this string, iff the string does
2923 not already end in an EOF character. */
2924 if (shell_input_line_terminator != EOF)
2926 if (shell_input_line_len + 3 > shell_input_line_size)
2927 shell_input_line = xrealloc (shell_input_line,
2928 1 + (shell_input_line_size += 2));
2930 shell_input_line[shell_input_line_len] = '\n';
2931 shell_input_line[shell_input_line_len + 1] = '\0';
2935 c = shell_input_line[shell_input_line_index];
2938 shell_input_line_index++;
2940 if (c == '\\' && remove_quoted_newline &&
2941 shell_input_line[shell_input_line_index] == '\n')
2948 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2949 /* If C is NULL, we have reached the end of the current input string. If
2950 pushed_string_list is non-empty, it's time to pop to the previous string
2951 because we have fully consumed the result of the last alias expansion.
2952 Do it transparently; just return the next character of the string popped
2954 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
2959 c = shell_input_line[shell_input_line_index];
2961 shell_input_line_index++;
2970 #endif /* ALIAS || DPAREN_ARITHMETIC */
2972 if (!c && shell_input_line_terminator == EOF)
2973 return ((shell_input_line_index != 0) ? '\n' : EOF);
2975 return ((unsigned char)c);
2978 /* Put C back into the input for the shell. */
2983 if (shell_input_line && shell_input_line_index)
2984 shell_input_line[--shell_input_line_index] = c;
2990 if (shell_input_line && shell_input_line_index)
2991 shell_input_line_index--;
2994 /* Discard input until CHARACTER is seen, then push that character back
2995 onto the input stream. */
2997 discard_until (character)
3002 while ((c = shell_getc (0)) != EOF && c != character)
3010 execute_prompt_command (command)
3013 Function *temp_last, *temp_this;
3015 int temp_exit_value, temp_eof_encountered;
3017 temp_last = last_shell_builtin;
3018 temp_this = this_shell_builtin;
3019 temp_exit_value = last_command_exit_value;
3020 temp_eof_encountered = eof_encountered;
3021 last_lastarg = get_string_value ("_");
3023 last_lastarg = savestring (last_lastarg);
3025 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
3027 last_shell_builtin = temp_last;
3028 this_shell_builtin = temp_this;
3029 last_command_exit_value = temp_exit_value;
3030 eof_encountered = temp_eof_encountered;
3032 bind_variable ("_", last_lastarg);
3033 FREE (last_lastarg);
3035 if (token_to_read == '\n') /* reset_parser was called */
3039 /* Place to remember the token. We try to keep the buffer
3040 at a reasonable size, but it can grow. */
3041 static char *token = (char *)NULL;
3043 /* Current size of the token buffer. */
3044 static int token_buffer_size;
3046 /* Command to read_token () explaining what we want it to do. */
3049 #define prompt_is_ps1 \
3050 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
3052 /* Function for yyparse to call. yylex keeps track of
3053 the last two tokens read, and calls read_token. */
3057 if (interactive && (current_token == 0 || current_token == '\n'))
3059 /* Before we print a prompt, we might have to check mailboxes.
3060 We do this only if it is time to do so. Notice that only here
3061 is the mail alarm reset; nothing takes place in check_mail ()
3062 except the checking of mail. Please don't change this. */
3063 if (prompt_is_ps1 && time_to_check_mail ())
3066 reset_mail_timer ();
3069 /* Avoid printing a prompt if we're not going to read anything, e.g.
3070 after resetting the parser with read_token (RESET). */
3071 if (token_to_read == 0 && interactive)
3075 two_tokens_ago = token_before_that;
3076 token_before_that = last_read_token;
3077 last_read_token = current_token;
3078 current_token = read_token (READ);
3079 return (current_token);
3082 /* When non-zero, we have read the required tokens
3083 which allow ESAC to be the next one read. */
3084 static int esacs_needed_count;
3087 gather_here_documents ()
3090 while (need_here_doc)
3092 make_here_document (redir_stack[r++]);
3097 /* When non-zero, an open-brace used to create a group is awaiting a close
3099 static int open_brace_count;
3101 #define command_token_position(token) \
3102 (((token) == ASSIGNMENT_WORD) || \
3103 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
3105 #define assignment_acceptable(token) command_token_position(token) && \
3106 ((parser_state & PST_CASEPAT) == 0)
3108 /* Check to see if TOKEN is a reserved word and return the token
3110 #define CHECK_FOR_RESERVED_WORD(tok) \
3112 if (!dollar_present && !quoted && \
3113 reserved_word_acceptable (last_read_token)) \
3116 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
3117 if (STREQ (tok, word_token_alist[i].word)) \
3119 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
3121 if (word_token_alist[i].token == TIME) \
3123 if (word_token_alist[i].token == ESAC) \
3124 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
3125 else if (word_token_alist[i].token == CASE) \
3126 parser_state |= PST_CASESTMT; \
3127 else if (word_token_alist[i].token == COND_END) \
3128 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
3129 else if (word_token_alist[i].token == COND_START) \
3130 parser_state |= PST_CONDCMD; \
3131 else if (word_token_alist[i].token == '{') \
3132 open_brace_count++; \
3133 else if (word_token_alist[i].token == '}' && open_brace_count) \
3134 open_brace_count--; \
3135 return (word_token_alist[i].token); \
3142 /* OK, we have a token. Let's try to alias expand it, if (and only if)
3145 It is eligible for expansion if the shell is in interactive mode, and
3146 the token is unquoted and the last token read was a command
3147 separator (or expand_next_token is set), and we are currently
3148 processing an alias (pushed_string_list is non-empty) and this
3149 token is not the same as the current or any previously
3152 Special cases that disqualify:
3153 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
3155 alias_expand_token (token)
3161 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
3162 (parser_state & PST_CASEPAT) == 0)
3164 ap = find_alias (token);
3166 /* Currently expanding this token. */
3167 if (ap && (ap->flags & AL_BEINGEXPANDED))
3168 return (NO_EXPANSION);
3170 expanded = ap ? savestring (ap->value) : (char *)NULL;
3173 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
3174 return (RE_READ_TOKEN);
3177 /* This is an eligible token that does not have an expansion. */
3178 return (NO_EXPANSION);
3180 return (NO_EXPANSION);
3185 time_command_acceptable ()
3187 #if defined (COMMAND_TIMING)
3188 switch (last_read_token)
3207 #endif /* COMMAND_TIMING */
3210 /* Handle special cases of token recognition:
3211 IN is recognized if the last token was WORD and the token
3212 before that was FOR or CASE or SELECT.
3214 DO is recognized if the last token was WORD and the token
3215 before that was FOR or SELECT.
3217 ESAC is recognized if the last token caused `esacs_needed_count'
3220 `{' is recognized if the last token as WORD and the token
3221 before that was FUNCTION.
3223 `}' is recognized if there is an unclosed `{' prsent.
3225 `-p' is returned as TIMEOPT if the last read token was TIME.
3227 ']]' is returned as COND_END if the parser is currently parsing
3228 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
3230 `time' is returned as TIME if and only if it is immediately
3231 preceded by one of `;', `\n', `||', `&&', or `&'.
3235 special_case_tokens (token)
3238 if ((last_read_token == WORD) &&
3239 #if defined (SELECT_COMMAND)
3240 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3242 ((token_before_that == FOR) || (token_before_that == CASE)) &&
3244 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
3246 if (token_before_that == CASE)
3248 parser_state |= PST_CASEPAT;
3249 esacs_needed_count++;
3254 if (last_read_token == WORD &&
3255 #if defined (SELECT_COMMAND)
3256 (token_before_that == FOR || token_before_that == SELECT) &&
3258 (token_before_that == FOR) &&
3260 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
3263 /* Ditto for ESAC in the CASE case.
3264 Specifically, this handles "case word in esac", which is a legal
3265 construct, certainly because someone will pass an empty arg to the
3266 case construct, and we don't want it to barf. Of course, we should
3267 insist that the case construct has at least one pattern in it, but
3268 the designers disagree. */
3269 if (esacs_needed_count)
3271 esacs_needed_count--;
3272 if (STREQ (token, "esac"))
3274 parser_state &= ~PST_CASEPAT;
3279 /* The start of a shell function definition. */
3280 if (parser_state & PST_ALLOWOPNBRC)
3282 parser_state &= ~PST_ALLOWOPNBRC;
3283 if (token[0] == '{' && token[1] == '\0') /* } */
3286 function_bstart = line_number;
3287 return ('{'); /* } */
3291 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
3293 open_brace_count--; /* { */
3297 #if defined (COMMAND_TIMING)
3298 /* Handle -p after `time'. */
3299 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
3303 #if defined (COMMAND_TIMING)
3304 if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
3306 #endif /* COMMAND_TIMING */
3308 #if defined (COND_COMMAND) /* [[ */
3309 if ((parser_state & PST_CONDEXPR) && token[0] == ']' && token[1] == ']' && token[2] == '\0')
3316 /* Called from shell.c when Control-C is typed at top level. Or
3317 by the error rule at top level. */
3321 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3322 open_brace_count = 0;
3326 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
3327 if (pushed_string_list)
3328 free_string_list ();
3329 #endif /* ALIAS || DPAREN_ARITHMETIC */
3331 if (shell_input_line)
3333 free (shell_input_line);
3334 shell_input_line = (char *)NULL;
3335 shell_input_line_size = shell_input_line_index = 0;
3338 FREE (word_desc_to_read);
3339 word_desc_to_read = (WORD_DESC *)NULL;
3341 last_read_token = '\n';
3342 token_to_read = '\n';
3345 /* Read the next token. Command can be READ (normal operation) or
3346 RESET (to normalize state). */
3348 read_token (command)
3351 int character; /* Current character. */
3352 int peek_char; /* Temporary look-ahead character. */
3353 int result; /* The thing to return. */
3355 if (command == RESET)
3363 result = token_to_read;
3364 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3366 yylval.word = word_desc_to_read;
3367 word_desc_to_read = (WORD_DESC *)NULL;
3373 #if defined (COND_COMMAND)
3374 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
3376 cond_lineno = line_number;
3377 parser_state |= PST_CONDEXPR;
3378 yylval.command = parse_cond_command ();
3379 if (cond_token != COND_END)
3381 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
3382 parser_error (cond_lineno, "unexpected EOF while looking for `]]'");
3383 else if (cond_token != COND_ERROR)
3384 parser_error (cond_lineno, "syntax error in conditional expression");
3387 token_to_read = COND_END;
3388 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
3394 /* This is a place to jump back to once we have successfully expanded a
3395 token with an alias and pushed the string with push_string () */
3399 /* Read a single word from input. Start by skipping blanks. */
3400 while ((character = shell_getc (1)) != EOF && whitespace (character))
3403 if (character == EOF)
3409 if (character == '#' && (!interactive || interactive_comments))
3411 /* A comment. Discard until EOL or EOF, and then return a newline. */
3412 discard_until ('\n');
3414 character = '\n'; /* this will take the next if statement and return. */
3417 if (character == '\n')
3419 /* If we're about to return an unquoted newline, we can go and collect
3420 the text of any pending here document. */
3422 gather_here_documents ();
3425 parser_state &= ~PST_ALEXPNEXT;
3431 /* Shell meta-characters. */
3432 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3435 /* Turn off alias tokenization iff this character sequence would
3436 not leave us ready to read a command. */
3437 if (character == '<' || character == '>')
3438 parser_state &= ~PST_ALEXPNEXT;
3441 peek_char = shell_getc (1);
3442 if (character == peek_char)
3447 /* If '<' then we could be at "<<" or at "<<-". We have to
3448 look ahead one more character. */
3449 peek_char = shell_getc (1);
3450 if (peek_char == '-')
3451 return (LESS_LESS_MINUS);
3454 shell_ungetc (peek_char);
3459 return (GREATER_GREATER);
3462 parser_state |= PST_CASEPAT;
3464 parser_state &= ~PST_ALEXPNEXT;
3474 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3476 # if defined (ARITH_FOR_COMMAND)
3477 if (last_read_token == FOR)
3483 arith_for_lineno = line_number;
3484 cmdtyp = parse_arith_cmd (&wval);
3487 /* parse_arith_cmd adds quotes at the beginning and end
3488 of the string it returns; we need to take those out. */
3489 len = strlen (wval);
3490 wv2 = xmalloc (len);
3491 strncpy (wv2, wval + 1, len - 2);
3492 wv2[len - 2] = '\0';
3493 wd = make_word (wv2);
3494 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3497 return (ARITH_FOR_EXPRS);
3500 return -1; /* ERROR */
3503 # if defined (DPAREN_ARITHMETIC)
3504 if (reserved_word_acceptable (last_read_token))
3510 sline = line_number;
3511 cmdtyp = parse_arith_cmd (&wval);
3512 if (cmdtyp == 1) /* arithmetic command */
3514 wd = make_word (wval);
3515 wd->flags = W_QUOTED;
3516 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3517 free (wval); /* make_word copies it */
3520 else if (cmdtyp == 0) /* nested subshell */
3522 push_string (wval, 0, (alias_t *)NULL);
3523 if ((parser_state & PST_CASEPAT) == 0)
3524 parser_state |= PST_SUBSHELL;
3535 else if (character == '<' && peek_char == '&')
3537 else if (character == '>' && peek_char == '&')
3538 return (GREATER_AND);
3539 else if (character == '<' && peek_char == '>')
3540 return (LESS_GREATER);
3541 else if (character == '>' && peek_char == '|')
3542 return (GREATER_BAR);
3543 else if (peek_char == '>' && character == '&')
3544 return (AND_GREATER);
3546 shell_ungetc (peek_char);
3548 /* If we look like we are reading the start of a function
3549 definition, then let the reader know about it so that
3550 we will do the right thing with `{'. */
3551 if (character == ')' && last_read_token == '(' && token_before_that == WORD)
3553 parser_state |= PST_ALLOWOPNBRC;
3555 parser_state &= ~PST_ALEXPNEXT;
3557 function_dstart = line_number;
3560 /* case pattern lists may be preceded by an optional left paren. If
3561 we're not trying to parse a case pattern list, the left paren
3562 indicates a subshell. */
3563 if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3564 parser_state |= PST_SUBSHELL;
3566 else if ((parser_state & PST_CASEPAT) && character == ')')
3567 parser_state &= ~PST_CASEPAT;
3569 else if ((parser_state & PST_SUBSHELL) && character == ')')
3570 parser_state &= ~PST_SUBSHELL;
3572 #if defined (PROCESS_SUBSTITUTION)
3573 /* Check for the constructs which introduce process substitution.
3574 Shells running in `posix mode' don't do process substitution. */
3575 if (posixly_correct ||
3576 ((character != '>' && character != '<') || peek_char != '('))
3577 #endif /* PROCESS_SUBSTITUTION */
3581 /* Hack <&- (close stdin) case. */
3582 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3585 /* Okay, if we got this far, we have to read a word. Read one,
3586 and then check it against the known ones. */
3587 result = read_token_word (character);
3589 if (result == RE_READ_TOKEN)
3595 /* Match a $(...) or other grouping construct. This has to handle embedded
3596 quoted strings ('', ``, "") and nested constructs. It also must handle
3597 reprompting the user, if necessary, after reading a newline, and returning
3598 correct error values if it reads EOF. */
3600 #define P_FIRSTCLOSE 0x01
3601 #define P_ALLOWESC 0x02
3603 static char matched_pair_error;
3605 parse_matched_pair (qc, open, close, lenp, flags)
3606 int qc; /* `"' if this construct is within double quotes */
3610 int count, ch, was_dollar;
3611 int pass_next_character, nestlen, start_lineno;
3612 char *ret, *nestret;
3613 int retind, retsize;
3616 pass_next_character = was_dollar = 0;
3618 ret = xmalloc (retsize = 64);
3621 start_lineno = line_number;
3624 ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
3628 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
3629 EOF_Reached = 1; /* XXX */
3630 return (&matched_pair_error);
3633 /* Possible reprompting. */
3634 if (ch == '\n' && interactive &&
3635 (bash_input.type == st_stdin || bash_input.type == st_stream))
3638 if (pass_next_character) /* last char was backslash */
3640 pass_next_character = 0;
3641 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3643 if (retind > 0) retind--; /* swallow previously-added backslash */
3647 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3648 if (ch == CTLESC || ch == CTLNUL)
3649 ret[retind++] = CTLESC;
3653 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3655 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3656 ret[retind++] = CTLESC;
3660 else if (ch == close) /* ending delimiter */
3663 /* handle nested ${...} specially. */
3664 else if (open != close && was_dollar && open == '{' && ch == open) /* } */
3667 else if (((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
3670 /* Add this character. */
3671 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3674 if (open == '\'') /* '' inside grouping construct */
3676 if ((flags & P_ALLOWESC) && ch == '\\')
3677 pass_next_character++;
3681 if (ch == '\\') /* backslashes */
3682 pass_next_character++;
3684 if (open != close) /* a grouping construct */
3686 if (shellquote (ch))
3688 /* '', ``, or "" inside $(...) or other grouping construct. */
3689 push_delimiter (dstack, ch);
3690 nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
3691 pop_delimiter (dstack);
3692 if (nestret == &matched_pair_error)
3695 return &matched_pair_error;
3699 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3700 strcpy (ret + retind, nestret);
3706 /* Parse an old-style command substitution within double quotes as a
3708 /* XXX - sh and ksh93 don't do this - XXX */
3709 else if (open == '"' && ch == '`')
3711 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
3712 if (nestret == &matched_pair_error)
3715 return &matched_pair_error;
3719 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3720 strcpy (ret + retind, nestret);
3725 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3726 /* check for $(), $[], or ${} inside quoted string. */
3728 if (open == ch) /* undo previous increment */
3730 if (ch == '(') /* ) */
3731 nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
3732 else if (ch == '{') /* } */
3733 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE);
3734 else if (ch == '[') /* ] */
3735 nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
3736 if (nestret == &matched_pair_error)
3739 return &matched_pair_error;
3743 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3744 strcpy (ret + retind, nestret);
3749 was_dollar = (ch == '$');
3758 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3759 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
3760 If not, assume it's a nested subshell for backwards compatibility and
3761 return 0. In any case, put the characters we've consumed into a locally-
3762 allocated buffer and make *ep point to that buffer. Return -1 on an
3763 error, for example EOF. */
3765 parse_arith_cmd (ep)
3768 int exp_lineno, rval, c;
3772 exp_lineno = line_number;
3773 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3775 if (ttok == &matched_pair_error)
3777 /* Check that the next character is the closing right paren. If
3778 not, this is a syntax error. ( */
3779 if ((c = shell_getc (0)) != ')')
3782 token = xmalloc (ttoklen + 4);
3784 /* (( ... )) -> "..." */
3785 token[0] = (rval == 1) ? '"' : '(';
3786 strncpy (token + 1, ttok, ttoklen - 1); /* don't copy the final `)' */
3789 token[ttoklen] = '"';
3790 token[ttoklen+1] = '\0';
3794 token[ttoklen] = ')';
3795 token[ttoklen+1] = c;
3796 token[ttoklen+2] = '\0';
3802 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
3804 #if defined (COND_COMMAND)
3805 static COND_COM *cond_term ();
3806 static COND_COM *cond_and ();
3807 static COND_COM *cond_or ();
3808 static COND_COM *cond_expr ();
3813 return (cond_or ());
3822 if (cond_token == OR_OR)
3825 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
3836 if (cond_token == AND_AND)
3839 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
3845 cond_skip_newlines ()
3847 while ((cond_token = read_token (READ)) == '\n')
3849 if (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
3852 return (cond_token);
3855 #define COND_RETURN_ERROR() \
3856 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
3862 COND_COM *term, *tleft, *tright;
3865 /* Read a token. It can be a left paren, a `!', a unary operator, or a
3866 word that should be the first argument of a binary operator. Start by
3867 skipping newlines, since this is a compound command. */
3868 tok = cond_skip_newlines ();
3869 lineno = line_number;
3870 if (tok == COND_END)
3872 COND_RETURN_ERROR ();
3874 else if (tok == '(')
3876 term = cond_expr ();
3877 if (cond_token != ')')
3880 dispose_cond_node (term); /* ( */
3881 parser_error (lineno, "expected `)'");
3882 COND_RETURN_ERROR ();
3884 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
3885 (void)cond_skip_newlines ();
3887 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
3890 dispose_word (yylval.word); /* not needed */
3891 term = cond_term ();
3893 term->flags |= CMD_INVERT_RETURN;
3895 else if (tok == WORD && test_unop (yylval.word->word))
3898 tok = read_token (READ);
3901 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3902 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3907 parser_error (line_number, "unexpected argument to conditional unary operator");
3908 COND_RETURN_ERROR ();
3911 (void)cond_skip_newlines ();
3913 else if (tok == WORD) /* left argument to binary operator */
3916 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3919 tok = read_token (READ);
3920 if (tok == WORD && test_binop (yylval.word->word))
3922 else if (tok == '<' || tok == '>')
3923 op = make_word_from_token (tok);
3924 else if (tok == COND_END || tok == AND_AND || tok == OR_OR)
3926 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
3927 the test command. Similarly for [[ x && expr ]] or
3929 op = make_word ("-n");
3930 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3936 parser_error (line_number, "conditional binary operator expected");
3937 dispose_cond_node (tleft);
3938 COND_RETURN_ERROR ();
3942 tok = read_token (READ);
3945 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3946 term = make_cond_node (COND_BINARY, op, tleft, tright);
3950 parser_error (line_number, "unexpected argument to conditional binary operator");
3951 dispose_cond_node (tleft);
3953 COND_RETURN_ERROR ();
3956 (void)cond_skip_newlines ();
3961 parser_error (line_number, "unexpected token `%c' in conditional command", tok);
3963 parser_error (line_number, "unexpected token %d in conditional command", tok);
3964 COND_RETURN_ERROR ();
3969 /* This is kind of bogus -- we slip a mini recursive-descent parser in
3970 here to handle the conditional statement syntax. */
3972 parse_cond_command ()
3976 cexp = cond_expr ();
3977 return (make_cond_command (cexp));
3982 read_token_word (character)
3985 /* The value for YYLVAL when a WORD is read. */
3986 WORD_DESC *the_word;
3988 /* Index into the token that we are building. */
3991 /* ALL_DIGITS becomes zero when we see a non-digit. */
3994 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3997 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
4000 /* Non-zero means to ignore the value of the next character, and just
4001 to add it no matter what. */
4002 int pass_next_character;
4004 /* The current delimiting character. */
4006 int result, peek_char;
4007 char *ttok, *ttrans;
4008 int ttoklen, ttranslen;
4010 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
4011 token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
4014 all_digits = digit (character);
4015 dollar_present = quoted = pass_next_character = 0;
4019 if (character == EOF)
4022 if (pass_next_character)
4024 pass_next_character = 0;
4028 cd = current_delimiter (dstack);
4030 /* Handle backslashes. Quote lots of things when not inside of
4031 double-quotes, quote some things inside of double-quotes. */
4032 if (character == '\\')
4034 peek_char = shell_getc (0);
4036 /* Backslash-newline is ignored in all cases except
4037 when quoted with single quotes. */
4038 if (peek_char == '\n')
4041 goto next_character;
4045 shell_ungetc (peek_char);
4047 /* If the next character is to be quoted, note it now. */
4048 if (cd == 0 || cd == '`' ||
4049 (cd == '"' && member (peek_char, slashify_in_quotes)))
4050 pass_next_character++;
4057 /* Parse a matched pair of quote characters. */
4058 if (shellquote (character))
4060 push_delimiter (dstack, character);
4061 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
4062 pop_delimiter (dstack);
4063 if (ttok == &matched_pair_error)
4064 return -1; /* Bail immediately. */
4065 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4066 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4067 token[token_index++] = character;
4068 strcpy (token + token_index, ttok);
4069 token_index += ttoklen;
4072 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
4074 goto next_character;
4077 #ifdef EXTENDED_GLOB
4078 /* Parse a ksh-style extended pattern matching specification. */
4079 if (extended_glob && PATTERN_CHAR(character))
4081 peek_char = shell_getc (1);
4082 if (peek_char == '(') /* ) */
4084 push_delimiter (dstack, peek_char);
4085 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4086 pop_delimiter (dstack);
4087 if (ttok == &matched_pair_error)
4088 return -1; /* Bail immediately. */
4089 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4091 TOKEN_DEFAULT_GROW_SIZE);
4092 token[token_index++] = character;
4093 token[token_index++] = peek_char;
4094 strcpy (token + token_index, ttok);
4095 token_index += ttoklen;
4097 dollar_present = all_digits = 0;
4098 goto next_character;
4101 shell_ungetc (peek_char);
4103 #endif /* EXTENDED_GLOB */
4105 /* If the delimiter character is not single quote, parse some of
4106 the shell expansions that must be read as a single word. */
4107 #if defined (PROCESS_SUBSTITUTION)
4108 if (character == '$' || character == '<' || character == '>')
4110 if (character == '$')
4111 #endif /* !PROCESS_SUBSTITUTION */
4113 peek_char = shell_getc (1);
4114 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
4115 if (peek_char == '(' ||
4116 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
4118 if (peek_char == '{') /* } */
4119 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
4120 else if (peek_char == '(') /* ) */
4122 /* XXX - push and pop the `(' as a delimiter for use by
4123 the command-oriented-history code. This way newlines
4124 appearing in the $(...) string get added to the
4125 history literally rather than causing a possibly-
4126 incorrect `;' to be added. ) */
4127 push_delimiter (dstack, peek_char);
4128 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4129 pop_delimiter (dstack);
4132 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4133 if (ttok == &matched_pair_error)
4134 return -1; /* Bail immediately. */
4135 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4137 TOKEN_DEFAULT_GROW_SIZE);
4138 token[token_index++] = character;
4139 token[token_index++] = peek_char;
4140 strcpy (token + token_index, ttok);
4141 token_index += ttoklen;
4145 goto next_character;
4147 /* This handles $'...' and $"..." new-style quoted strings. */
4148 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
4152 first_line = line_number;
4153 push_delimiter (dstack, peek_char);
4154 ttok = parse_matched_pair (peek_char, peek_char, peek_char,
4156 (peek_char == '\'') ? P_ALLOWESC : 0);
4157 pop_delimiter (dstack);
4158 if (ttok == &matched_pair_error)
4160 if (peek_char == '\'')
4162 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4164 /* Insert the single quotes and correctly quote any
4165 embedded single quotes (allowed because P_ALLOWESC was
4166 passed to parse_matched_pair). */
4167 ttok = single_quote (ttrans);
4170 ttranslen = strlen (ttrans);
4174 /* Try to locale-expand the converted string. */
4175 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4178 /* Add the double quotes back */
4179 ttok = xmalloc (ttranslen + 3);
4181 strcpy (ttok + 1, ttrans);
4182 ttok[ttranslen + 1] = '"';
4183 ttok[ttranslen += 2] = '\0';
4188 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
4190 TOKEN_DEFAULT_GROW_SIZE);
4191 strcpy (token + token_index, ttrans);
4192 token_index += ttranslen;
4196 goto next_character;
4198 /* This could eventually be extended to recognize all of the
4199 shell's single-character parameter expansions, and set flags.*/
4200 else if (character == '$' && peek_char == '$')
4203 ttok[0] = ttok[1] = '$';
4205 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
4207 TOKEN_DEFAULT_GROW_SIZE);
4208 strcpy (token + token_index, ttok);
4213 goto next_character;
4216 shell_ungetc (peek_char);
4219 #if defined (ARRAY_VARS)
4220 /* Identify possible compound array variable assignment. */
4221 else if (character == '=' && token_index > 0)
4223 peek_char = shell_getc (1);
4224 if (peek_char == '(') /* ) */
4226 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4227 if (ttok == &matched_pair_error)
4228 return -1; /* Bail immediately. */
4229 if (ttok[0] == '(') /* ) */
4234 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4236 TOKEN_DEFAULT_GROW_SIZE);
4237 token[token_index++] = character;
4238 token[token_index++] = peek_char;
4239 strcpy (token + token_index, ttok);
4240 token_index += ttoklen;
4243 goto next_character;
4246 shell_ungetc (peek_char);
4250 /* When not parsing a multi-character word construct, shell meta-
4251 characters break words. */
4252 if (shellbreak (character))
4254 shell_ungetc (character);
4260 all_digits &= digit (character);
4261 dollar_present |= character == '$';
4263 if (character == CTLESC || character == CTLNUL)
4264 token[token_index++] = CTLESC;
4266 token[token_index++] = character;
4268 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
4269 TOKEN_DEFAULT_GROW_SIZE);
4272 if (character == '\n' && interactive &&
4273 (bash_input.type == st_stdin || bash_input.type == st_stream))
4276 /* We want to remove quoted newlines (that is, a \<newline> pair)
4277 unless we are within single quotes or pass_next_character is
4278 set (the shell equivalent of literal-next). */
4279 cd = current_delimiter (dstack);
4280 character = shell_getc (cd != '\'' && pass_next_character == 0);
4281 } /* end for (;;) */
4285 token[token_index] = '\0';
4287 /* Check to see what thing we should return. If the last_read_token
4288 is a `<', or a `&', or the character which ended this token is
4289 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
4290 Otherwise, it is just a word, and should be returned as such. */
4291 if (all_digits && (character == '<' || character == '>' ||
4292 last_read_token == LESS_AND ||
4293 last_read_token == GREATER_AND))
4295 yylval.number = atoi (token);
4299 /* Check for special case tokens. */
4300 result = special_case_tokens (token);
4305 /* Posix.2 does not allow reserved words to be aliased, so check for all
4306 of them, including special cases, before expanding the current token
4308 if (posixly_correct)
4309 CHECK_FOR_RESERVED_WORD (token);
4311 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
4312 inhibits alias expansion. */
4313 if (expand_aliases && quoted == 0)
4315 result = alias_expand_token (token);
4316 if (result == RE_READ_TOKEN)
4317 return (RE_READ_TOKEN);
4318 else if (result == NO_EXPANSION)
4319 parser_state &= ~PST_ALEXPNEXT;
4322 /* If not in Posix.2 mode, check for reserved words after alias
4324 if (posixly_correct == 0)
4326 CHECK_FOR_RESERVED_WORD (token);
4328 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
4329 the_word->word = xmalloc (1 + token_index);
4330 the_word->flags = 0;
4331 strcpy (the_word->word, token);
4333 the_word->flags |= W_HASDOLLAR;
4335 the_word->flags |= W_QUOTED;
4336 /* A word is an assignment if it appears at the beginning of a
4337 simple command, or after another assignment word. This is
4338 context-dependent, so it cannot be handled in the grammar. */
4339 if (assignment (token))
4341 the_word->flags |= W_ASSIGNMENT;
4342 /* Don't perform word splitting on assignment statements. */
4343 if (assignment_acceptable (last_read_token))
4344 the_word->flags |= W_NOSPLIT;
4347 yylval.word = the_word;
4349 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
4350 ? ASSIGNMENT_WORD : WORD;
4352 if (last_read_token == FUNCTION)
4354 parser_state |= PST_ALLOWOPNBRC;
4355 function_dstart = line_number;
4361 /* $'...' ANSI-C expand the portion of STRING between START and END and
4362 return the result. The result cannot be longer than the input string. */
4364 ansiexpand (string, start, end, lenp)
4366 int start, end, *lenp;
4371 temp = xmalloc (end - start + 1);
4372 for (tlen = 0, len = start; len < end; )
4373 temp[tlen++] = string[len++];
4378 t = ansicstr (temp, tlen, 0, (int *)NULL, lenp);
4390 /* Change a bash string into a string suitable for inclusion in a `po' file.
4391 This backslash-escapes `"' and `\' and changes newlines into \\\n"\n". */
4393 mk_msgstr (string, foundnlp)
4397 register int c, len;
4398 char *result, *r, *s;
4400 for (len = 0, s = string; s && *s; s++)
4403 if (*s == '"' || *s == '\\')
4405 else if (*s == '\n')
4409 r = result = xmalloc (len + 3);
4412 for (s = string; s && (c = *s); s++)
4414 if (c == '\n') /* <NL> -> \n"<NL>" */
4425 if (c == '"' || c == '\\')
4436 /* $"..." -- Translate the portion of STRING between START and END
4437 according to current locale using gettext (if available) and return
4438 the result. The caller will take care of leaving the quotes intact.
4439 The string will be left without the leading `$' by the caller.
4440 If translation is performed, the translated string will be double-quoted
4441 by the caller. The length of the translated string is returned in LENP,
4444 localeexpand (string, start, end, lineno, lenp)
4446 int start, end, lineno, *lenp;
4448 int len, tlen, foundnl;
4449 char *temp, *t, *t2;
4451 temp = xmalloc (end - start + 1);
4452 for (tlen = 0, len = start; len < end; )
4453 temp[tlen++] = string[len++];
4456 /* If we're just dumping translatable strings, don't do anything with the
4457 string itself, but if we're dumping in `po' file format, convert it into a form more palatable to gettext(3)
4458 and friends by quoting `"' and `\' with backslashes and converting <NL>
4459 into `\n"<NL>"'. If we find a newline in TEMP, we first output a
4460 `msgid ""' line and then the translated string; otherwise we output the
4461 `msgid' and translated string all on one line. */
4462 if (dump_translatable_strings)
4464 if (dump_po_strings)
4467 t = mk_msgstr (temp, &foundnl);
4468 t2 = foundnl ? "\"\"\n" : "";
4470 printf ("#: %s:%d\nmsgid %s%s\nmsgstr \"\"\n",
4471 (bash_input.name ? bash_input.name : "stdin"), lineno, t2, t);
4475 printf ("\"%s\"\n", temp);
4483 t = localetrans (temp, tlen, &len);
4497 /* Return 1 if TOKEN is a token that after being read would allow
4498 a reserved word to be seen, else 0. */
4500 reserved_word_acceptable (token)
4503 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
4504 token == '|' || token == '&' || token == '{' ||
4505 token == '}' || /* XXX */
4508 token == TIME || token == TIMEOPT ||
4515 token == SEMI_SEMI ||
4519 token == DONE || /* XXX these two are experimental */
4527 /* Return the index of TOKEN in the alist of reserved words, or -1 if
4528 TOKEN is not a shell reserved word. */
4530 find_reserved_word (token)
4534 for (i = 0; word_token_alist[i].word; i++)
4535 if (STREQ (token, word_token_alist[i].word))
4541 #if defined (READLINE)
4542 /* Called after each time readline is called. This insures that whatever
4543 the new prompt string is gets propagated to readline's local prompt
4546 reset_readline_prompt ()
4550 if (prompt_string_pointer)
4552 temp_prompt = (*prompt_string_pointer)
4553 ? decode_prompt_string (*prompt_string_pointer)
4556 if (temp_prompt == 0)
4558 temp_prompt = xmalloc (1);
4559 temp_prompt[0] = '\0';
4562 FREE (current_readline_prompt);
4563 current_readline_prompt = temp_prompt;
4566 #endif /* READLINE */
4569 #if defined (HISTORY)
4570 /* A list of tokens which can be followed by newlines, but not by
4571 semi-colons. When concatenating multiple lines of history, the
4572 newline separator for such tokens is replaced with a space. */
4573 static int no_semi_successors[] = {
4574 '\n', '{', '(', ')', ';', '&', '|',
4575 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
4579 /* If we are not within a delimited expression, try to be smart
4580 about which separators can be semi-colons and which must be
4581 newlines. Returns the string that should be added into the
4584 history_delimiting_chars ()
4588 if (dstack.delimiter_depth != 0)
4591 /* First, handle some special cases. */
4593 /* If we just read `()', assume it's a function definition, and don't
4594 add a semicolon. If the token before the `)' was not `(', and we're
4595 not in the midst of parsing a case statement, assume it's a
4596 parenthesized command and add the semicolon. */
4598 if (token_before_that == ')')
4600 if (two_tokens_ago == '(') /*)*/ /* function def */
4602 /* This does not work for subshells inside case statement
4603 command lists. It's a suboptimal solution. */
4604 else if (parser_state & PST_CASESTMT) /* case statement pattern */
4607 return "; "; /* (...) subshell */
4609 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
4610 return " "; /* function def using `function name' without `()' */
4612 else if (token_before_that == WORD && two_tokens_ago == FOR)
4614 /* Tricky. `for i\nin ...' should not have a semicolon, but
4615 `for i\ndo ...' should. We do what we can. */
4616 for (i = shell_input_line_index; whitespace(shell_input_line[i]); i++)
4618 if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
4623 for (i = 0; no_semi_successors[i]; i++)
4625 if (token_before_that == no_semi_successors[i])
4631 #endif /* HISTORY */
4633 /* Issue a prompt, or prepare to issue a prompt when the next character
4640 if (!interactive) /* XXX */
4643 ps1_prompt = get_string_value ("PS1");
4644 ps2_prompt = get_string_value ("PS2");
4646 if (!prompt_string_pointer)
4647 prompt_string_pointer = &ps1_prompt;
4649 temp_prompt = *prompt_string_pointer
4650 ? decode_prompt_string (*prompt_string_pointer)
4653 if (temp_prompt == 0)
4655 temp_prompt = xmalloc (1);
4656 temp_prompt[0] = '\0';
4659 current_prompt_string = *prompt_string_pointer;
4660 prompt_string_pointer = &ps2_prompt;
4662 #if defined (READLINE)
4663 if (!no_line_editing)
4665 FREE (current_readline_prompt);
4666 current_readline_prompt = temp_prompt;
4669 #endif /* READLINE */
4671 FREE (current_decoded_prompt);
4672 current_decoded_prompt = temp_prompt;
4677 get_current_prompt_level ()
4679 return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
4683 set_current_prompt_level (x)
4686 prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
4687 current_prompt_string = *prompt_string_pointer;
4693 fprintf (stderr, "%s", current_decoded_prompt);
4697 /* Return a string which will be printed as a prompt. The string
4698 may contain special characters which are decoded as follows:
4701 \e escape (ascii 033)
4702 \d the date in Day Mon Date format
4703 \h the hostname up to the first `.'
4705 \j the number of active jobs
4706 \l the basename of the shell's tty device name
4708 \s the name of the shell
4709 \t the time in 24-hour hh:mm:ss format
4710 \T the time in 12-hour hh:mm:ss format
4711 \@ the time in 12-hour am/pm format
4712 \v the version of bash (e.g., 2.00)
4713 \V the release of bash, version + patchlevel (e.g., 2.00.0)
4714 \w the current working directory
4715 \W the last element of $PWD
4717 \# the command number of this command
4718 \! the history number of this command
4719 \$ a $ or a # if you are root
4720 \nnn character code nnn in octal
4722 \[ begin a sequence of non-printing chars
4723 \] end a sequence of non-printing chars
4725 #define PROMPT_GROWTH 48
4727 decode_prompt_string (string)
4732 struct dstack save_dstack;
4733 #if defined (PROMPT_STRING_DECODE)
4734 int result_size, result_index;
4736 char *temp, octal_string[4];
4739 result = xmalloc (result_size = PROMPT_GROWTH);
4740 result[result_index = 0] = 0;
4741 temp = (char *)NULL;
4743 while (c = *string++)
4745 if (posixly_correct && c == '!')
4749 temp = savestring ("!");
4754 #if !defined (HISTORY)
4755 temp = savestring ("1");
4757 temp = itos (history_number ());
4758 #endif /* HISTORY */
4759 string--; /* add_string increments string again. */
4777 strncpy (octal_string, string, 3);
4778 octal_string[3] = '\0';
4780 n = read_octal (octal_string);
4783 if (n == CTLESC || n == CTLNUL)
4809 /* Make the current time/date into a string. */
4810 the_time = time (0);
4811 temp = ctime (&the_time);
4813 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
4814 temp[(c != 'd') ? 8 : 10] = '\0';
4816 /* quick and dirty conversion to 12-hour time */
4817 if (c == 'T' || c == '@')
4821 temp[5] = 'a'; /* am/pm format */
4832 temp[0] = (n / 10) + '0';
4833 temp[1] = (n % 10) + '0';
4835 if (n >= 0 && temp[5] == 'a')
4848 temp[0] = no_line_editing ? '\n' : '\r';
4849 temp[1] = no_line_editing ? '\0' : '\n';
4854 temp = base_pathname (shell_name);
4855 temp = savestring (temp);
4862 strcpy (temp, dist_version);
4864 sprintf (temp, "%s.%d", dist_version, patch_level);
4870 /* Use the value of PWD because it is much more efficient. */
4871 char t_string[PATH_MAX];
4874 temp = get_string_value ("PWD");
4878 if (getcwd (t_string, sizeof(t_string)) == 0)
4884 tlen = strlen (t_string);
4888 tlen = sizeof (t_string) - 1;
4889 strncpy (t_string, temp, tlen);
4891 t_string[tlen] = '\0';
4895 t = strrchr (t_string, '/');
4896 if (t && t != t_string)
4897 strcpy (t_string, t + 1);
4900 /* polite_directory_format is guaranteed to return a string
4901 no longer than PATH_MAX - 1 characters. */
4902 strcpy (t_string, polite_directory_format (t_string));
4904 /* If we're going to be expanding the prompt string later,
4905 quote the directory name. */
4906 if (promptvars || posixly_correct)
4908 temp = backslash_quote (t_string);
4910 /* Make sure that expand_prompt_string is called with a
4911 second argument of Q_DOUBLE_QUOTE if we use this
4913 temp = backslash_quote_for_double_quotes (t_string);
4916 temp = savestring (t_string);
4922 if (current_user.user_name == 0)
4923 get_current_user_info ();
4924 temp = savestring (current_user.user_name);
4929 temp = savestring (current_host_name);
4930 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4935 temp = itos (current_command_number);
4939 #if !defined (HISTORY)
4940 temp = savestring ("1");
4942 temp = itos (history_number ());
4943 #endif /* HISTORY */
4947 t = temp = xmalloc (3);
4948 if ((promptvars || posixly_correct) && (current_user.euid != 0))
4950 *t++ = current_user.euid == 0 ? '#' : '$';
4955 temp = itos (count_all_jobs ());
4959 #if defined (HAVE_TTYNAME)
4960 temp = (char *)ttyname (fileno (stdin));
4961 t = temp ? base_pathname (temp) : "tty";
4962 temp = savestring (t);
4964 temp = savestring ("tty");
4965 #endif /* !HAVE_TTYNAME */
4968 #if defined (READLINE)
4973 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4976 #endif /* READLINE */
4987 temp[0] = (c == 'a') ? '\07' : '\033';
5001 sub_append_string (temp, result, &result_index, &result_size);
5002 temp = (char *)NULL; /* Freed in sub_append_string (). */
5003 result[result_index] = '\0';
5009 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
5010 result[result_index++] = c;
5011 result[result_index] = '\0';
5014 #else /* !PROMPT_STRING_DECODE */
5015 result = savestring (string);
5016 #endif /* !PROMPT_STRING_DECODE */
5018 /* Save the delimiter stack and point `dstack' to temp space so any
5019 command substitutions in the prompt string won't result in screwing
5020 up the parser's quoting state. */
5021 save_dstack = dstack;
5022 dstack = temp_dstack;
5023 dstack.delimiter_depth = 0;
5025 /* Perform variable and parameter expansion and command substitution on
5026 the prompt string. */
5027 if (promptvars || posixly_correct)
5030 list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
5032 list = expand_prompt_string (result, Q_DOUBLE_QUOTES);
5035 result = string_list (list);
5036 dispose_words (list);
5040 t = dequote_string (result);
5045 dstack = save_dstack;
5050 /* Report a syntax error, and restart the parser. Call here for fatal
5055 report_syntax_error ((char *)NULL);
5060 /* Report a syntax error with line numbers, etc.
5061 Call here for recoverable errors. If you have a message to print,
5062 then place it in MESSAGE, otherwise pass NULL and this will figure
5063 out an appropriate message for you. */
5065 report_syntax_error (message)
5074 parser_error (line_number, "%s", message);
5075 if (interactive && EOF_Reached)
5077 last_command_exit_value = EX_USAGE;
5081 /* If the line of input we're reading is not null, try to find the
5082 objectionable token. */
5083 if (shell_input_line && *shell_input_line)
5085 t = shell_input_line;
5086 i = shell_input_line_index;
5089 if (i && t[i] == '\0')
5092 while (i && (whitespace (t[i]) || t[i] == '\n'))
5098 while (i && (member (t[i], " \n\t;|&") == 0))
5101 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
5104 /* Print the offending token. */
5105 if (token_end || (i == 0 && token_end == 0))
5108 msg = substring (t, i, token_end);
5109 else /* one-character token */
5116 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
5122 /* If not interactive, print the line containing the error. */
5123 if (interactive == 0)
5125 msg = savestring (shell_input_line);
5126 token_end = strlen (msg);
5127 while (token_end && msg[token_end - 1] == '\n')
5128 msg[--token_end] = '\0';
5130 parser_error (line_number, "`%s'", msg);
5136 msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
5137 parser_error (line_number, "%s", msg);
5138 /* When the shell is interactive, this file uses EOF_Reached
5139 only for error reporting. Other mechanisms are used to
5140 decide whether or not to exit. */
5141 if (interactive && EOF_Reached)
5144 last_command_exit_value = EX_USAGE;
5147 /* ??? Needed function. ??? We have to be able to discard the constructs
5148 created during parsing. In the case of error, we want to return
5149 allocated objects to the memory pool. In the case of no error, we want
5150 to throw away the information about where the allocated objects live.
5151 (dispose_command () will actually free the command. */
5153 discard_parser_constructs (error_p)
5158 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
5160 /* A flag denoting whether or not ignoreeof is set. */
5163 /* The number of times that we have encountered an EOF character without
5164 another character intervening. When this gets above the limit, the
5165 shell terminates. */
5166 int eof_encountered = 0;
5168 /* The limit for eof_encountered. */
5169 int eof_encountered_limit = 10;
5171 /* If we have EOF as the only input unit, this user wants to leave
5172 the shell. If the shell is not interactive, then just leave.
5173 Otherwise, if ignoreeof is set, and we haven't done this the
5174 required number of times in a row, print a message. */
5176 handle_eof_input_unit ()
5180 /* shell.c may use this to decide whether or not to write out the
5181 history, among other things. We use it only for error reporting
5186 /* If the user wants to "ignore" eof, then let her do so, kind of. */
5189 if (eof_encountered < eof_encountered_limit)
5191 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
5192 login_shell ? "logout" : "exit");
5194 /* Reset the prompt string to be $PS1. */
5195 prompt_string_pointer = (char **)NULL;
5197 last_read_token = current_token = '\n';
5202 /* In this case EOF should exit the shell. Do it now. */
5204 exit_builtin ((WORD_LIST *)NULL);
5208 /* We don't write history files, etc., for non-interactive shells. */
5213 static WORD_LIST parse_string_error;
5215 /* Take a string and run it through the shell parser, returning the
5216 resultant word list. Used by compound array assignment. */
5218 parse_string_to_word_list (s, whom)
5222 int tok, orig_line_number, orig_input_terminator;
5223 #if defined (HISTORY)
5224 int old_remember_on_history, old_history_expansion_inhibited;
5227 #if defined (HISTORY)
5228 old_remember_on_history = remember_on_history;
5229 # if defined (BANG_HISTORY)
5230 old_history_expansion_inhibited = history_expansion_inhibited;
5232 bash_history_disable ();
5235 orig_line_number = line_number;
5236 orig_input_terminator = shell_input_line_terminator;
5239 last_read_token = '\n';
5241 with_input_from_string (s, whom);
5242 wl = (WORD_LIST *)NULL;
5243 while ((tok = read_token (READ)) != yacc_EOF)
5245 if (tok == '\n' && *bash_input.location.string == '\0')
5247 if (tok != WORD && tok != ASSIGNMENT_WORD)
5249 line_number = orig_line_number + line_number - 1;
5250 yyerror (); /* does the right thing */
5253 wl = &parse_string_error;
5256 wl = make_word_list (yylval.word, wl);
5259 last_read_token = '\n';
5262 #if defined (HISTORY)
5263 remember_on_history = old_remember_on_history;
5264 # if defined (BANG_HISTORY)
5265 history_expansion_inhibited = old_history_expansion_inhibited;
5266 # endif /* BANG_HISTORY */
5267 #endif /* HISTORY */
5269 shell_input_line_terminator = orig_input_terminator;
5271 if (wl == &parse_string_error)
5273 last_command_exit_value = EXECUTION_FAILURE;
5274 if (interactive_shell == 0 && posixly_correct)
5275 jump_to_top_level (FORCE_EOF);
5277 jump_to_top_level (DISCARD);
5280 return (REVERSE_LIST (wl, WORD_LIST *));