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
36 #define GREATER_GREATER 286
39 #define GREATER_AND 289
41 #define LESS_LESS_MINUS 291
42 #define AND_GREATER 292
43 #define LESS_GREATER 293
44 #define GREATER_BAR 294
47 #line 21 "/usr/homes/chet/src/bash/src/parse.y"
51 #include "bashtypes.h"
54 #if defined (HAVE_UNISTD_H)
58 #if defined (HAVE_LOCALE_H)
71 #include "mailcheck.h"
72 #include "builtins/common.h"
73 #include "builtins/builtext.h"
75 #if defined (READLINE)
76 # include "bashline.h"
77 # include <readline/readline.h>
81 # include "bashhist.h"
82 # include <readline/history.h>
85 #if defined (JOB_CONTROL)
87 #endif /* JOB_CONTROL */
93 #if defined (PROMPT_STRING_DECODE)
95 # include <sys/param.h>
99 #endif /* PROMPT_STRING_DECODE */
101 #define RE_READ_TOKEN -99
102 #define NO_EXPANSION -100
106 #if defined (EXTENDED_GLOB)
107 #define PATTERN_CHAR(c) \
108 ((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!')
110 extern int extended_glob;
113 extern int eof_encountered;
114 extern int no_line_editing, running_under_emacs;
115 extern int current_command_number;
116 extern int interactive, interactive_shell, login_shell;
117 extern int sourcelevel;
118 extern int posixly_correct;
119 extern int last_command_exit_value;
120 extern int interrupt_immediately;
121 extern char *shell_name, *current_host_name;
122 extern char *dist_version;
123 extern int patch_level;
124 extern int dump_translatable_strings, dump_po_strings;
125 extern Function *last_shell_builtin, *this_shell_builtin;
126 #if defined (BUFFERED_INPUT)
127 extern int bash_input_fd_changed;
130 /* **************************************************************** */
132 /* "Forward" declarations */
134 /* **************************************************************** */
136 static char *ansiexpand ();
137 static char *localeexpand ();
138 static int reserved_word_acceptable ();
139 static int read_token ();
141 static int parse_arith_cmd ();
142 #if defined (COND_COMMAND)
143 static COMMAND *parse_cond_command ();
145 static int read_token_word ();
146 static void discard_parser_constructs ();
148 static void report_syntax_error ();
149 static void handle_eof_input_unit ();
150 static void prompt_again ();
152 static void reset_readline_prompt ();
154 static void print_prompt ();
156 extern int yyerror ();
158 /* Default prompt strings */
159 char *primary_prompt = PPROMPT;
160 char *secondary_prompt = SPROMPT;
162 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
163 char *ps1_prompt, *ps2_prompt;
165 /* Handle on the current prompt string. Indirectly points through
166 ps1_ or ps2_prompt. */
167 char **prompt_string_pointer = (char **)NULL;
168 char *current_prompt_string;
170 /* Non-zero means we expand aliases in commands. */
171 int expand_aliases = 0;
173 /* If non-zero, the decoded prompt string undergoes parameter and
174 variable substitution, command substitution, arithmetic substitution,
175 string expansion, process substitution, and quote removal in
176 decode_prompt_string. */
179 /* The decoded prompt string. Used if READLINE is not defined or if
180 editing is turned off. Analogous to current_readline_prompt. */
181 static char *current_decoded_prompt;
183 /* The number of lines read from input while creating the current command. */
184 int current_command_line_count;
186 /* Variables to manage the task of reading here documents, because we need to
187 defer the reading until after a complete command has been collected. */
188 static REDIRECT *redir_stack[10];
191 /* Where shell input comes from. History expansion is performed on each
192 line when the shell is interactive. */
193 static char *shell_input_line = (char *)NULL;
194 static int shell_input_line_index;
195 static int shell_input_line_size; /* Amount allocated for shell_input_line. */
196 static int shell_input_line_len; /* strlen (shell_input_line) */
198 /* Either zero or EOF. */
199 static int shell_input_line_terminator;
201 /* The line number in a script on which a function definition starts. */
202 static int function_dstart;
204 /* The line number in a script on which a function body starts. */
205 static int function_bstart;
207 static REDIRECTEE redir;
209 #line 183 "/usr/homes/chet/src/bash/src/parse.y"
211 WORD_DESC *word; /* the word that we read. */
212 int number; /* the number that we read. */
213 WORD_LIST *word_list;
217 PATTERN_LIST *pattern;
230 #define YYFLAG -32768
233 #define YYTRANSLATE(x) ((unsigned)(x) <= 295 ? yytranslate[x] : 85)
235 static const char yytranslate[] = { 0,
236 2, 2, 2, 2, 2, 2, 2, 2, 2, 42,
237 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
238 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
239 2, 2, 2, 2, 2, 2, 2, 40, 2, 50,
240 51, 2, 2, 2, 47, 2, 2, 2, 2, 2,
241 2, 2, 2, 2, 2, 2, 2, 2, 41, 46,
242 2, 45, 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, 2, 2, 2,
245 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
246 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
247 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
248 2, 2, 48, 44, 49, 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, 2, 2, 2, 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, 1, 2, 3, 4, 5,
262 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
263 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
264 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
269 static const short yyprhs[] = { 0,
270 0, 3, 5, 8, 10, 12, 15, 18, 21, 25,
271 29, 32, 36, 39, 43, 46, 50, 53, 57, 60,
272 64, 67, 71, 74, 78, 81, 85, 88, 92, 95,
273 99, 102, 105, 109, 111, 113, 115, 117, 120, 122,
274 125, 127, 129, 132, 134, 136, 142, 148, 150, 152,
275 154, 156, 158, 160, 162, 169, 176, 184, 192, 203,
276 214, 221, 228, 236, 244, 255, 266, 273, 281, 288,
277 294, 301, 306, 310, 316, 324, 331, 335, 337, 341,
278 346, 353, 359, 361, 364, 369, 374, 380, 386, 389,
279 393, 395, 399, 402, 404, 407, 411, 415, 419, 424,
280 429, 434, 439, 444, 446, 448, 450, 452, 453, 456,
281 458, 461, 464, 469, 474, 478, 482, 484, 486, 489,
282 492, 496, 500, 505, 507, 509
285 static const short yyrhs[] = { 80,
286 42, 0, 42, 0, 1, 42, 0, 43, 0, 24,
287 0, 53, 24, 0, 45, 24, 0, 46, 24, 0,
288 26, 45, 24, 0, 26, 46, 24, 0, 31, 24,
289 0, 26, 31, 24, 0, 32, 24, 0, 26, 32,
290 24, 0, 33, 26, 0, 26, 33, 26, 0, 34,
291 26, 0, 26, 34, 26, 0, 33, 24, 0, 26,
292 33, 24, 0, 34, 24, 0, 26, 34, 24, 0,
293 36, 24, 0, 26, 36, 24, 0, 34, 47, 0,
294 26, 34, 47, 0, 33, 47, 0, 26, 33, 47,
295 0, 37, 24, 0, 26, 38, 24, 0, 38, 24,
296 0, 39, 24, 0, 26, 39, 24, 0, 24, 0,
297 25, 0, 54, 0, 54, 0, 56, 54, 0, 55,
298 0, 57, 55, 0, 57, 0, 59, 0, 59, 56,
299 0, 60, 0, 62, 0, 12, 75, 14, 75, 15,
300 0, 13, 75, 14, 75, 15, 0, 61, 0, 65,
301 0, 64, 0, 66, 0, 67, 0, 68, 0, 63,
302 0, 10, 24, 79, 14, 75, 15, 0, 10, 24,
303 79, 48, 75, 49, 0, 10, 24, 41, 79, 14,
304 75, 15, 0, 10, 24, 41, 79, 48, 75, 49,
305 0, 10, 24, 79, 20, 53, 78, 79, 14, 75,
306 15, 0, 10, 24, 79, 20, 53, 78, 79, 48,
307 75, 49, 0, 11, 24, 79, 14, 74, 15, 0,
308 11, 24, 79, 48, 74, 49, 0, 11, 24, 41,
309 79, 14, 74, 15, 0, 11, 24, 41, 79, 48,
310 74, 49, 0, 11, 24, 79, 20, 53, 78, 79,
311 14, 74, 15, 0, 11, 24, 79, 20, 53, 78,
312 79, 48, 74, 49, 0, 8, 24, 79, 20, 79,
313 9, 0, 8, 24, 79, 20, 72, 79, 9, 0,
314 8, 24, 79, 20, 70, 9, 0, 24, 50, 51,
315 79, 66, 0, 16, 24, 50, 51, 79, 66, 0,
316 16, 24, 79, 66, 0, 50, 75, 51, 0, 3,
317 75, 4, 75, 7, 0, 3, 75, 4, 75, 5,
318 75, 7, 0, 3, 75, 4, 75, 69, 7, 0,
319 48, 74, 49, 0, 27, 0, 17, 28, 18, 0,
320 6, 75, 4, 75, 0, 6, 75, 4, 75, 5,
321 75, 0, 6, 75, 4, 75, 69, 0, 71, 0,
322 72, 71, 0, 79, 73, 51, 75, 0, 79, 73,
323 51, 79, 0, 79, 50, 73, 51, 75, 0, 79,
324 50, 73, 51, 79, 0, 71, 35, 0, 72, 71,
325 35, 0, 24, 0, 73, 44, 24, 0, 79, 76,
326 0, 74, 0, 79, 77, 0, 77, 42, 79, 0,
327 77, 40, 79, 0, 77, 41, 79, 0, 77, 29,
328 79, 77, 0, 77, 30, 79, 77, 0, 77, 40,
329 79, 77, 0, 77, 41, 79, 77, 0, 77, 42,
330 79, 77, 0, 82, 0, 42, 0, 41, 0, 43,
331 0, 0, 79, 42, 0, 81, 0, 81, 40, 0,
332 81, 41, 0, 81, 29, 79, 81, 0, 81, 30,
333 79, 81, 0, 81, 40, 81, 0, 81, 41, 81,
334 0, 82, 0, 83, 0, 21, 83, 0, 84, 83,
335 0, 84, 21, 83, 0, 21, 84, 83, 0, 83,
336 44, 79, 83, 0, 58, 0, 22, 0, 22, 23,
343 static const short yyrline[] = { 0,
344 232, 241, 248, 263, 273, 275, 279, 284, 289, 294,
345 299, 304, 309, 315, 321, 326, 331, 336, 341, 346,
346 351, 356, 361, 368, 375, 380, 385, 390, 395, 400,
347 405, 410, 415, 422, 424, 426, 430, 434, 445, 447,
348 451, 453, 455, 484, 486, 488, 490, 492, 494, 496,
349 498, 500, 502, 504, 508, 510, 512, 514, 516, 518,
350 522, 526, 530, 534, 538, 542, 548, 550, 552, 556,
351 560, 563, 567, 571, 573, 575, 580, 584, 588, 592,
352 594, 596, 600, 601, 605, 607, 609, 611, 615, 616,
353 620, 622, 631, 639, 640, 646, 647, 654, 658, 660,
354 662, 669, 671, 673, 677, 678, 679, 682, 683, 692,
355 698, 707, 715, 717, 719, 726, 729, 733, 735, 740,
356 745, 750, 757, 760, 764, 766
361 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
363 static const char * const yytname[] = { "$","error","$undefined.","IF","THEN",
364 "ELSE","ELIF","FI","CASE","ESAC","FOR","SELECT","WHILE","UNTIL","DO","DONE",
365 "FUNCTION","COND_START","COND_END","COND_ERROR","IN","BANG","TIME","TIMEOPT",
366 "WORD","ASSIGNMENT_WORD","NUMBER","ARITH_CMD","COND_CMD","AND_AND","OR_OR","GREATER_GREATER",
367 "LESS_LESS","LESS_AND","GREATER_AND","SEMI_SEMI","LESS_LESS_MINUS","AND_GREATER",
368 "LESS_GREATER","GREATER_BAR","'&'","';'","'\\n'","yacc_EOF","'|'","'>'","'<'",
369 "'-'","'{'","'}'","'('","')'","inputunit","word_list","redirection","simple_command_element",
370 "redirection_list","simple_command","command","shell_command","for_command",
371 "select_command","case_command","function_def","subshell","if_command","group_command",
372 "arith_command","cond_command","elif_clause","case_clause","pattern_list","case_clause_sequence",
373 "pattern","list","compound_list","list0","list1","list_terminator","newline_list",
374 "simple_list","simple_list1","pipeline_command","pipeline","timespec", NULL
378 static const short yyr1[] = { 0,
379 52, 52, 52, 52, 53, 53, 54, 54, 54, 54,
380 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
381 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
382 54, 54, 54, 55, 55, 55, 56, 56, 57, 57,
383 58, 58, 58, 59, 59, 59, 59, 59, 59, 59,
384 59, 59, 59, 59, 60, 60, 60, 60, 60, 60,
385 61, 61, 61, 61, 61, 61, 62, 62, 62, 63,
386 63, 63, 64, 65, 65, 65, 66, 67, 68, 69,
387 69, 69, 70, 70, 71, 71, 71, 71, 72, 72,
388 73, 73, 74, 75, 75, 76, 76, 76, 77, 77,
389 77, 77, 77, 77, 78, 78, 78, 79, 79, 80,
390 80, 80, 81, 81, 81, 81, 81, 82, 82, 82,
391 82, 82, 83, 83, 84, 84
394 static const short yyr2[] = { 0,
395 2, 1, 2, 1, 1, 2, 2, 2, 3, 3,
396 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
397 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
398 2, 2, 3, 1, 1, 1, 1, 2, 1, 2,
399 1, 1, 2, 1, 1, 5, 5, 1, 1, 1,
400 1, 1, 1, 1, 6, 6, 7, 7, 10, 10,
401 6, 6, 7, 7, 10, 10, 6, 7, 6, 5,
402 6, 4, 3, 5, 7, 6, 3, 1, 3, 4,
403 6, 5, 1, 2, 4, 4, 5, 5, 2, 3,
404 1, 3, 2, 1, 2, 3, 3, 3, 4, 4,
405 4, 4, 4, 1, 1, 1, 1, 0, 2, 1,
406 2, 2, 4, 4, 3, 3, 1, 1, 2, 2,
410 static const short yydefact[] = { 0,
411 0, 108, 0, 0, 0, 108, 108, 0, 0, 0,
412 125, 34, 35, 0, 78, 0, 0, 0, 0, 0,
413 0, 0, 0, 2, 4, 0, 0, 108, 108, 36,
414 39, 41, 124, 42, 44, 48, 45, 54, 50, 49,
415 51, 52, 53, 0, 110, 117, 118, 0, 3, 94,
416 0, 0, 108, 108, 108, 0, 0, 108, 0, 119,
417 0, 126, 0, 0, 0, 0, 0, 0, 0, 0,
418 0, 0, 11, 13, 19, 15, 27, 21, 17, 25,
419 23, 29, 31, 32, 7, 8, 0, 0, 0, 34,
420 40, 37, 43, 1, 108, 108, 111, 112, 108, 0,
421 120, 108, 109, 93, 95, 104, 0, 108, 0, 108,
422 0, 108, 108, 0, 0, 79, 122, 108, 12, 14,
423 20, 16, 28, 22, 18, 26, 24, 30, 33, 9,
424 10, 77, 0, 73, 38, 0, 0, 115, 116, 0,
425 121, 0, 108, 108, 108, 108, 108, 108, 0, 108,
426 0, 108, 0, 108, 0, 108, 0, 0, 108, 72,
427 0, 113, 114, 0, 0, 123, 108, 108, 74, 0,
428 0, 0, 97, 98, 96, 0, 83, 108, 0, 108,
429 108, 0, 5, 0, 0, 108, 108, 0, 0, 0,
430 46, 47, 0, 70, 0, 0, 76, 99, 100, 101,
431 102, 103, 69, 89, 84, 0, 67, 91, 0, 0,
432 0, 0, 55, 6, 106, 105, 107, 108, 56, 0,
433 0, 61, 108, 62, 71, 75, 108, 108, 108, 108,
434 90, 68, 0, 0, 108, 57, 58, 0, 63, 64,
435 0, 80, 0, 0, 0, 108, 92, 85, 86, 108,
436 108, 108, 108, 108, 82, 87, 88, 0, 0, 0,
437 0, 81, 59, 60, 65, 66, 0, 0, 0
440 static const short yydefgoto[] = { 267,
441 184, 30, 31, 93, 32, 33, 34, 35, 36, 37,
442 38, 39, 40, 41, 42, 43, 170, 176, 177, 178,
443 210, 50, 51, 104, 105, 218, 52, 44, 138, 106,
447 static const short yypact[] = { 246,
448 -34,-32768, 11, 20, 24,-32768,-32768, 33, -10, 369,
449 29, 19,-32768, 529,-32768, 42, 47, 30, 36, 64,
450 66, 78, 81,-32768,-32768, 84, 92,-32768,-32768,-32768,
451 -32768, 155,-32768, 513,-32768,-32768,-32768,-32768,-32768,-32768,
452 -32768,-32768,-32768, 89, -15,-32768, 77, 410,-32768,-32768,
453 130, 287,-32768, 95, 99, 127, 131, 97, 132, 77,
454 492,-32768, 100, 128, 129, 44, 56, 134, 135, 136,
455 139, 140,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
456 -32768,-32768,-32768,-32768,-32768,-32768, 105, 287, 104,-32768,
457 -32768,-32768, 513,-32768,-32768,-32768, 328, 328,-32768, 492,
458 77,-32768,-32768,-32768, 88,-32768, 1,-32768, -1,-32768,
459 16,-32768,-32768, 116, -32,-32768, 77,-32768,-32768,-32768,
460 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
461 -32768,-32768, 88,-32768,-32768, 287, 287, 69, 69, 451,
462 77, 79,-32768,-32768,-32768,-32768,-32768,-32768, 3,-32768,
463 144,-32768, 13,-32768, 144,-32768, 141, 157,-32768,-32768,
464 -32,-32768,-32768, 328, 328, 77,-32768,-32768,-32768, 166,
465 287, 287, 287, 287, 287, 169, 147,-32768, -4,-32768,
466 -32768, 175,-32768, 52, 146,-32768,-32768, 181, 52, 149,
467 -32768,-32768, -32,-32768, 192, 199,-32768,-32768,-32768, 71,
468 71, 71,-32768,-32768, 170, 0,-32768,-32768, 180, -22,
469 191, 161,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 196,
470 163,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
471 -32768,-32768, 28, 189,-32768,-32768,-32768, 17,-32768,-32768,
472 25, 114, 287, 287, 287,-32768,-32768,-32768, 287,-32768,
473 -32768,-32768,-32768,-32768,-32768,-32768, 287, 200, 167, 202,
474 171,-32768,-32768,-32768,-32768,-32768, 218, 219,-32768
477 static const short yypgoto[] = {-32768,
478 67, -30, 194,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
479 -32768,-32768,-32768, -112,-32768,-32768, -19,-32768, 46,-32768,
480 18, -17, -6,-32768, -60, 39, -21,-32768, 6, 12,
488 static const short yytable[] = { 56,
489 57, 60, 160, 92, 207, 45, 88, 49, 232, 103,
490 87, 46, 150, 95, 96, 28, 180, 59, 151, 208,
491 148, 234, 89, 208, 97, 98, 186, 133, 235, 154,
492 250, 107, 109, 111, 53, 155, 115, 103, 252, 101,
493 103, 103, 103, 54, 103, 209, 152, 55, 194, 209,
494 181, 62, 117, 75, 103, 76, 58, 103, 103, 78,
495 187, 79, 135, 156, 251, 73, 103, 121, 63, 122,
496 74, 234, 253, 136, 137, 214, 77, 140, 246, 124,
497 225, 125, 80, 167, 168, 169, 149, 81, 153, 82,
498 123, 141, 215, 216, 217, 142, 161, 95, 96, 143,
499 144, 83, 126, 139, 84, 157, 158, 85, 46, 46,
500 198, 199, 200, 201, 202, 86, 143, 144, 254, 168,
501 99, 171, 172, 173, 174, 175, 179, 145, 146, 147,
502 94, 166, 88, 102, 88, 108, 188, 193, 190, 110,
503 112, 162, 163, 182, 113, 185, 114, 46, 46, 116,
504 118, 119, 120, 132, 134, 191, 206, 127, 128, 129,
505 195, 196, 130, 131, 88, 88, 159, 183, 220, 221,
506 139, 192, 197, 211, 212, 46, 46, 203, 90, 13,
507 14, 204, 200, 201, 202, 16, 17, 18, 19, 213,
508 20, 21, 22, 23, 219, 222, 238, 224, 226, 26,
509 27, 241, 227, 208, 231, 236, 243, 244, 245, 237,
510 239, 240, 247, 249, 263, 264, 265, 268, 269, 266,
511 242, 189, 255, 205, 257, 91, 233, 223, 248, 61,
512 88, 88, 0, 0, 260, 261, 0, 0, 0, 256,
513 0, 0, 0, 258, 259, 0, 1, 262, 2, 0,
514 0, 0, 0, 3, 0, 4, 5, 6, 7, 0,
515 0, 8, 9, 0, 0, 0, 10, 11, 0, 12,
516 13, 14, 15, 0, 0, 0, 16, 17, 18, 19,
517 0, 20, 21, 22, 23, 0, 0, 24, 25, 2,
518 26, 27, 0, 28, 3, 29, 4, 5, 6, 7,
519 0, 0, 8, 9, 0, 0, 0, 10, 11, 0,
520 12, 13, 14, 15, 0, 0, 0, 16, 17, 18,
521 19, 0, 20, 21, 22, 23, 0, 0, 103, 0,
522 2, 26, 27, 0, 28, 3, 29, 4, 5, 6,
523 7, 0, 0, 8, 9, 0, 0, 0, 10, 11,
524 0, 12, 13, 14, 15, 0, 0, 0, 16, 17,
525 18, 19, 0, 20, 21, 22, 23, 0, 0, 0,
526 0, 2, 26, 27, 0, 28, 3, 29, 4, 5,
527 6, 7, 0, 0, 8, 9, 0, 0, 0, 0,
528 11, 0, 12, 13, 14, 15, 0, 0, 0, 16,
529 17, 18, 19, 0, 20, 21, 22, 23, 0, 0,
530 0, 0, 2, 26, 27, 0, 28, 3, 29, 4,
531 5, 6, 7, 0, 0, 8, 9, 0, 0, 0,
532 100, 0, 0, 12, 13, 14, 15, 0, 0, 0,
533 16, 17, 18, 19, 0, 20, 21, 22, 23, 0,
534 0, 0, 0, 2, 26, 27, 0, 28, 3, 29,
535 4, 5, 6, 7, 0, 0, 8, 9, 0, 0,
536 0, 0, 0, 0, 12, 13, 14, 15, 0, 0,
537 0, 16, 17, 18, 19, 0, 20, 21, 22, 23,
538 0, 0, 103, 0, 2, 26, 27, 0, 28, 3,
539 29, 4, 5, 6, 7, 0, 0, 8, 9, 0,
540 0, 0, 0, 0, 0, 12, 13, 14, 15, 0,
541 0, 0, 16, 17, 18, 19, 0, 20, 21, 22,
542 23, 0, 0, 0, 0, 0, 26, 27, 14, 28,
543 0, 29, 0, 16, 17, 18, 19, 0, 20, 21,
544 22, 23, 0, 0, 0, 0, 0, 26, 27, 64,
545 65, 66, 67, 0, 68, 0, 69, 70, 0, 0,
549 static const short yycheck[] = { 6,
550 7, 10, 115, 34, 9, 0, 28, 42, 9, 42,
551 28, 0, 14, 29, 30, 48, 14, 28, 20, 24,
552 20, 44, 29, 24, 40, 41, 14, 88, 51, 14,
553 14, 53, 54, 55, 24, 20, 58, 42, 14, 48,
554 42, 42, 42, 24, 42, 50, 48, 24, 161, 50,
555 48, 23, 61, 24, 42, 26, 24, 42, 42, 24,
556 48, 26, 93, 48, 48, 24, 42, 24, 50, 26,
557 24, 44, 48, 95, 96, 24, 47, 99, 51, 24,
558 193, 26, 47, 5, 6, 7, 108, 24, 110, 24,
559 47, 100, 41, 42, 43, 102, 118, 29, 30, 29,
560 30, 24, 47, 98, 24, 112, 113, 24, 97, 98,
561 171, 172, 173, 174, 175, 24, 29, 30, 5, 6,
562 44, 143, 144, 145, 146, 147, 148, 40, 41, 42,
563 42, 140, 154, 4, 156, 41, 154, 159, 156, 41,
564 14, 136, 137, 150, 14, 152, 50, 136, 137, 18,
565 51, 24, 24, 49, 51, 15, 178, 24, 24, 24,
566 167, 168, 24, 24, 186, 187, 51, 24, 186, 187,
567 165, 15, 7, 180, 181, 164, 165, 9, 24, 25,
568 26, 35, 243, 244, 245, 31, 32, 33, 34, 15,
569 36, 37, 38, 39, 49, 15, 218, 49, 7, 45,
570 46, 223, 4, 24, 35, 15, 228, 229, 230, 49,
571 15, 49, 24, 235, 15, 49, 15, 0, 0, 49,
572 227, 155, 242, 178, 246, 32, 209, 189, 235, 10,
573 252, 253, -1, -1, 252, 253, -1, -1, -1, 246,
574 -1, -1, -1, 250, 251, -1, 1, 254, 3, -1,
575 -1, -1, -1, 8, -1, 10, 11, 12, 13, -1,
576 -1, 16, 17, -1, -1, -1, 21, 22, -1, 24,
577 25, 26, 27, -1, -1, -1, 31, 32, 33, 34,
578 -1, 36, 37, 38, 39, -1, -1, 42, 43, 3,
579 45, 46, -1, 48, 8, 50, 10, 11, 12, 13,
580 -1, -1, 16, 17, -1, -1, -1, 21, 22, -1,
581 24, 25, 26, 27, -1, -1, -1, 31, 32, 33,
582 34, -1, 36, 37, 38, 39, -1, -1, 42, -1,
583 3, 45, 46, -1, 48, 8, 50, 10, 11, 12,
584 13, -1, -1, 16, 17, -1, -1, -1, 21, 22,
585 -1, 24, 25, 26, 27, -1, -1, -1, 31, 32,
586 33, 34, -1, 36, 37, 38, 39, -1, -1, -1,
587 -1, 3, 45, 46, -1, 48, 8, 50, 10, 11,
588 12, 13, -1, -1, 16, 17, -1, -1, -1, -1,
589 22, -1, 24, 25, 26, 27, -1, -1, -1, 31,
590 32, 33, 34, -1, 36, 37, 38, 39, -1, -1,
591 -1, -1, 3, 45, 46, -1, 48, 8, 50, 10,
592 11, 12, 13, -1, -1, 16, 17, -1, -1, -1,
593 21, -1, -1, 24, 25, 26, 27, -1, -1, -1,
594 31, 32, 33, 34, -1, 36, 37, 38, 39, -1,
595 -1, -1, -1, 3, 45, 46, -1, 48, 8, 50,
596 10, 11, 12, 13, -1, -1, 16, 17, -1, -1,
597 -1, -1, -1, -1, 24, 25, 26, 27, -1, -1,
598 -1, 31, 32, 33, 34, -1, 36, 37, 38, 39,
599 -1, -1, 42, -1, 3, 45, 46, -1, 48, 8,
600 50, 10, 11, 12, 13, -1, -1, 16, 17, -1,
601 -1, -1, -1, -1, -1, 24, 25, 26, 27, -1,
602 -1, -1, 31, 32, 33, 34, -1, 36, 37, 38,
603 39, -1, -1, -1, -1, -1, 45, 46, 26, 48,
604 -1, 50, -1, 31, 32, 33, 34, -1, 36, 37,
605 38, 39, -1, -1, -1, -1, -1, 45, 46, 31,
606 32, 33, 34, -1, 36, -1, 38, 39, -1, -1,
609 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
610 #line 3 "/usr/share/misc/bison.simple"
612 /* Skeleton output parser for bison,
613 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
615 This program is free software; you can redistribute it and/or modify
616 it under the terms of the GNU General Public License as published by
617 the Free Software Foundation; either version 2, or (at your option)
620 This program is distributed in the hope that it will be useful,
621 but WITHOUT ANY WARRANTY; without even the implied warranty of
622 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
623 GNU General Public License for more details.
625 You should have received a copy of the GNU General Public License
626 along with this program; if not, write to the Free Software
627 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
629 /* As a special exception, when this file is copied by Bison into a
630 Bison output file, you may use that output file without restriction.
631 This special exception was added by the Free Software Foundation
632 in version 1.24 of Bison. */
636 #define alloca __builtin_alloca
637 #else /* not GNU C. */
638 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
640 #else /* not sparc */
641 #if defined (MSDOS) && !defined (__TURBOC__)
643 #else /* not MSDOS, or __TURBOC__ */
647 #else /* not MSDOS, __TURBOC__, or _AIX */
651 void *alloca (unsigned int);
653 #else /* not __cplusplus */
655 #endif /* not __cplusplus */
657 #endif /* not _AIX */
658 #endif /* not MSDOS, or __TURBOC__ */
659 #endif /* not sparc. */
660 #endif /* not GNU C. */
661 #endif /* alloca not defined. */
663 /* This is the parser code that is written into each bison parser
664 when the %semantic_parser declaration is not specified in the grammar.
665 It was written by Richard Stallman by simplifying the hairy parser
666 used when %semantic_parser is specified. */
668 /* Note: there must be only one dollar sign in this file.
669 It is replaced by the list of actions, each action
670 as one case of the switch. */
672 #define yyerrok (yyerrstatus = 0)
673 #define yyclearin (yychar = YYEMPTY)
676 #define YYACCEPT return(0)
677 #define YYABORT return(1)
678 #define YYERROR goto yyerrlab1
679 /* Like YYERROR except do call yyerror.
680 This remains here temporarily to ease the
681 transition to the new meaning of YYERROR, for GCC.
682 Once GCC version 2 has supplanted version 1, this can go. */
683 #define YYFAIL goto yyerrlab
684 #define YYRECOVERING() (!!yyerrstatus)
685 #define YYBACKUP(token, value) \
687 if (yychar == YYEMPTY && yylen == 1) \
688 { yychar = (token), yylval = (value); \
689 yychar1 = YYTRANSLATE (yychar); \
694 { yyerror ("syntax error: cannot back up"); YYERROR; } \
698 #define YYERRCODE 256
701 #define YYLEX yylex()
707 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
709 #define YYLEX yylex(&yylval, &yylloc)
711 #else /* not YYLSP_NEEDED */
713 #define YYLEX yylex(&yylval, YYLEX_PARAM)
715 #define YYLEX yylex(&yylval)
717 #endif /* not YYLSP_NEEDED */
720 /* If nonreentrant, generate the variables here */
724 int yychar; /* the lookahead symbol */
725 YYSTYPE yylval; /* the semantic value of the */
726 /* lookahead symbol */
729 YYLTYPE yylloc; /* location data for the lookahead */
733 int yynerrs; /* number of parse errors so far */
734 #endif /* not YYPURE */
737 int yydebug; /* nonzero means print parse trace */
738 /* Since this is uninitialized, it does not stop multiple parsers
742 /* YYINITDEPTH indicates the initial size of the parser's stacks */
745 #define YYINITDEPTH 200
748 /* YYMAXDEPTH is the maximum size the stacks can grow to
749 (effective only if the built-in stack extension method is used). */
756 #define YYMAXDEPTH 10000
759 /* Prevent warning if -Wstrict-prototypes. */
764 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
765 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
766 #else /* not GNU C or C++ */
769 /* This is the most reliable way to avoid incompatibilities
770 in available built-in functions on various systems. */
772 __yy_memcpy (to, from, count)
777 register char *f = from;
778 register char *t = to;
779 register int i = count;
785 #else /* __cplusplus */
787 /* This is the most reliable way to avoid incompatibilities
788 in available built-in functions on various systems. */
790 __yy_memcpy (char *to, char *from, int count)
792 register char *f = from;
793 register char *t = to;
794 register int i = count;
803 #line 196 "/usr/share/misc/bison.simple"
805 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
806 into yyparse. The argument should have type void *.
807 It should actually point to an object.
808 Grammar actions can access the variable by casting it
809 to the proper pointer type. */
813 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
814 #define YYPARSE_PARAM_DECL
815 #else /* not __cplusplus */
816 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
817 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
818 #endif /* not __cplusplus */
819 #else /* not YYPARSE_PARAM */
820 #define YYPARSE_PARAM_ARG
821 #define YYPARSE_PARAM_DECL
822 #endif /* not YYPARSE_PARAM */
825 yyparse(YYPARSE_PARAM_ARG)
828 register int yystate;
830 register short *yyssp;
831 register YYSTYPE *yyvsp;
832 int yyerrstatus; /* number of tokens to shift before error messages enabled */
833 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
835 short yyssa[YYINITDEPTH]; /* the state stack */
836 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
838 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
839 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
842 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
843 YYLTYPE *yyls = yylsa;
846 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
848 #define YYPOPSTACK (yyvsp--, yyssp--)
851 int yystacksize = YYINITDEPTH;
862 YYSTYPE yyval; /* the variable used to return */
863 /* semantic values from the action */
870 fprintf(stderr, "Starting parse\n");
876 yychar = YYEMPTY; /* Cause a token to be read. */
878 /* Initialize stack pointers.
879 Waste one element of value and location stack
880 so that they stay on the same level as the state stack.
881 The wasted elements are never initialized. */
889 /* Push a new state, which is found in yystate . */
890 /* In all cases, when you get here, the value and location stacks
891 have just been pushed. so pushing a state here evens the stacks. */
896 if (yyssp >= yyss + yystacksize - 1)
898 /* Give user a chance to reallocate the stack */
899 /* Use copies of these so that the &'s don't force the real ones into memory. */
900 YYSTYPE *yyvs1 = yyvs;
903 YYLTYPE *yyls1 = yyls;
906 /* Get the current used size of the three stacks, in elements. */
907 int size = yyssp - yyss + 1;
910 /* Each stack pointer address is followed by the size of
911 the data in use in that stack, in bytes. */
913 /* This used to be a conditional around just the two extra args,
914 but that might be undefined if yyoverflow is a macro. */
915 yyoverflow("parser stack overflow",
916 &yyss1, size * sizeof (*yyssp),
917 &yyvs1, size * sizeof (*yyvsp),
918 &yyls1, size * sizeof (*yylsp),
921 yyoverflow("parser stack overflow",
922 &yyss1, size * sizeof (*yyssp),
923 &yyvs1, size * sizeof (*yyvsp),
927 yyss = yyss1; yyvs = yyvs1;
931 #else /* no yyoverflow */
932 /* Extend the stack our own way. */
933 if (yystacksize >= YYMAXDEPTH)
935 yyerror("parser stack overflow");
939 if (yystacksize > YYMAXDEPTH)
940 yystacksize = YYMAXDEPTH;
941 yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
942 __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
943 yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
944 __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
946 yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
947 __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
949 #endif /* no yyoverflow */
951 yyssp = yyss + size - 1;
952 yyvsp = yyvs + size - 1;
954 yylsp = yyls + size - 1;
959 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
962 if (yyssp >= yyss + yystacksize - 1)
968 fprintf(stderr, "Entering state %d\n", yystate);
974 /* Do appropriate processing given the current state. */
975 /* Read a lookahead token if we need one and don't already have one. */
978 /* First try to decide what to do without reference to lookahead token. */
980 yyn = yypact[yystate];
984 /* Not known => get a lookahead token if don't already have one. */
986 /* yychar is either YYEMPTY or YYEOF
987 or a valid token in external form. */
989 if (yychar == YYEMPTY)
993 fprintf(stderr, "Reading a token: ");
998 /* Convert token to internal form (in yychar1) for indexing tables with */
1000 if (yychar <= 0) /* This means end of input. */
1003 yychar = YYEOF; /* Don't call YYLEX any more */
1007 fprintf(stderr, "Now at end of input.\n");
1012 yychar1 = YYTRANSLATE(yychar);
1017 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
1018 /* Give the individual parser a way to print the precise meaning
1019 of a token, for further debugging info. */
1021 YYPRINT (stderr, yychar, yylval);
1023 fprintf (stderr, ")\n");
1029 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
1034 /* yyn is what to do for this token type in this state.
1035 Negative => reduce, -yyn is rule number.
1036 Positive => shift, yyn is new state.
1037 New state is final state => don't bother to shift,
1038 just return success.
1039 0, or most negative number => error. */
1054 /* Shift the lookahead token. */
1058 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
1061 /* Discard the token being shifted unless it is eof. */
1062 if (yychar != YYEOF)
1070 /* count tokens shifted since error; after three, turn off error status. */
1071 if (yyerrstatus) yyerrstatus--;
1076 /* Do the default action for the current state. */
1079 yyn = yydefact[yystate];
1083 /* Do a reduction. yyn is the number of a rule to reduce with. */
1087 yyval = yyvsp[1-yylen]; /* implement default value of the action */
1094 fprintf (stderr, "Reducing via rule %d (line %d), ",
1097 /* Print the symbols being reduced, and their result. */
1098 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
1099 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
1100 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
1108 #line 233 "/usr/homes/chet/src/bash/src/parse.y"
1110 /* Case of regular command. Discard the error
1111 safety net,and return the command just parsed. */
1112 global_command = yyvsp[-1].command;
1113 eof_encountered = 0;
1114 discard_parser_constructs (0);
1119 #line 242 "/usr/homes/chet/src/bash/src/parse.y"
1121 /* Case of regular command, but not a very
1122 interesting one. Return a NULL command. */
1123 global_command = (COMMAND *)NULL;
1128 #line 249 "/usr/homes/chet/src/bash/src/parse.y"
1130 /* Error during parsing. Return NULL command. */
1131 global_command = (COMMAND *)NULL;
1132 eof_encountered = 0;
1133 discard_parser_constructs (1);
1145 #line 264 "/usr/homes/chet/src/bash/src/parse.y"
1147 /* Case of EOF seen by itself. Do ignoreeof or
1149 global_command = (COMMAND *)NULL;
1150 handle_eof_input_unit ();
1155 #line 274 "/usr/homes/chet/src/bash/src/parse.y"
1156 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1159 #line 276 "/usr/homes/chet/src/bash/src/parse.y"
1160 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); ;
1163 #line 280 "/usr/homes/chet/src/bash/src/parse.y"
1165 redir.filename = yyvsp[0].word;
1166 yyval.redirect = make_redirection (1, r_output_direction, redir);
1170 #line 285 "/usr/homes/chet/src/bash/src/parse.y"
1172 redir.filename = yyvsp[0].word;
1173 yyval.redirect = make_redirection (0, r_input_direction, redir);
1177 #line 290 "/usr/homes/chet/src/bash/src/parse.y"
1179 redir.filename = yyvsp[0].word;
1180 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
1184 #line 295 "/usr/homes/chet/src/bash/src/parse.y"
1186 redir.filename = yyvsp[0].word;
1187 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
1191 #line 300 "/usr/homes/chet/src/bash/src/parse.y"
1193 redir.filename = yyvsp[0].word;
1194 yyval.redirect = make_redirection (1, r_appending_to, redir);
1198 #line 305 "/usr/homes/chet/src/bash/src/parse.y"
1200 redir.filename = yyvsp[0].word;
1201 yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
1205 #line 310 "/usr/homes/chet/src/bash/src/parse.y"
1207 redir.filename = yyvsp[0].word;
1208 yyval.redirect = make_redirection (0, r_reading_until, redir);
1209 redir_stack[need_here_doc++] = yyval.redirect;
1213 #line 316 "/usr/homes/chet/src/bash/src/parse.y"
1215 redir.filename = yyvsp[0].word;
1216 yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, redir);
1217 redir_stack[need_here_doc++] = yyval.redirect;
1221 #line 322 "/usr/homes/chet/src/bash/src/parse.y"
1223 redir.dest = yyvsp[0].number;
1224 yyval.redirect = make_redirection (0, r_duplicating_input, redir);
1228 #line 327 "/usr/homes/chet/src/bash/src/parse.y"
1230 redir.dest = yyvsp[0].number;
1231 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
1235 #line 332 "/usr/homes/chet/src/bash/src/parse.y"
1237 redir.dest = yyvsp[0].number;
1238 yyval.redirect = make_redirection (1, r_duplicating_output, redir);
1242 #line 337 "/usr/homes/chet/src/bash/src/parse.y"
1244 redir.dest = yyvsp[0].number;
1245 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
1249 #line 342 "/usr/homes/chet/src/bash/src/parse.y"
1251 redir.filename = yyvsp[0].word;
1252 yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
1256 #line 347 "/usr/homes/chet/src/bash/src/parse.y"
1258 redir.filename = yyvsp[0].word;
1259 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
1263 #line 352 "/usr/homes/chet/src/bash/src/parse.y"
1265 redir.filename = yyvsp[0].word;
1266 yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
1270 #line 357 "/usr/homes/chet/src/bash/src/parse.y"
1272 redir.filename = yyvsp[0].word;
1273 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
1277 #line 362 "/usr/homes/chet/src/bash/src/parse.y"
1279 redir.filename = yyvsp[0].word;
1280 yyval.redirect = make_redirection
1281 (0, r_deblank_reading_until, redir);
1282 redir_stack[need_here_doc++] = yyval.redirect;
1286 #line 369 "/usr/homes/chet/src/bash/src/parse.y"
1288 redir.filename = yyvsp[0].word;
1289 yyval.redirect = make_redirection
1290 (yyvsp[-2].number, r_deblank_reading_until, redir);
1291 redir_stack[need_here_doc++] = yyval.redirect;
1295 #line 376 "/usr/homes/chet/src/bash/src/parse.y"
1298 yyval.redirect = make_redirection (1, r_close_this, redir);
1302 #line 381 "/usr/homes/chet/src/bash/src/parse.y"
1305 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1309 #line 386 "/usr/homes/chet/src/bash/src/parse.y"
1312 yyval.redirect = make_redirection (0, r_close_this, redir);
1316 #line 391 "/usr/homes/chet/src/bash/src/parse.y"
1319 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1323 #line 396 "/usr/homes/chet/src/bash/src/parse.y"
1325 redir.filename = yyvsp[0].word;
1326 yyval.redirect = make_redirection (1, r_err_and_out, redir);
1330 #line 401 "/usr/homes/chet/src/bash/src/parse.y"
1332 redir.filename = yyvsp[0].word;
1333 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
1337 #line 406 "/usr/homes/chet/src/bash/src/parse.y"
1339 redir.filename = yyvsp[0].word;
1340 yyval.redirect = make_redirection (0, r_input_output, redir);
1344 #line 411 "/usr/homes/chet/src/bash/src/parse.y"
1346 redir.filename = yyvsp[0].word;
1347 yyval.redirect = make_redirection (1, r_output_force, redir);
1351 #line 416 "/usr/homes/chet/src/bash/src/parse.y"
1353 redir.filename = yyvsp[0].word;
1354 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
1358 #line 423 "/usr/homes/chet/src/bash/src/parse.y"
1359 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1362 #line 425 "/usr/homes/chet/src/bash/src/parse.y"
1363 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1366 #line 427 "/usr/homes/chet/src/bash/src/parse.y"
1367 { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; ;
1370 #line 431 "/usr/homes/chet/src/bash/src/parse.y"
1372 yyval.redirect = yyvsp[0].redirect;
1376 #line 435 "/usr/homes/chet/src/bash/src/parse.y"
1378 register REDIRECT *t;
1380 for (t = yyvsp[-1].redirect; t->next; t = t->next)
1382 t->next = yyvsp[0].redirect;
1383 yyval.redirect = yyvsp[-1].redirect;
1387 #line 446 "/usr/homes/chet/src/bash/src/parse.y"
1388 { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); ;
1391 #line 448 "/usr/homes/chet/src/bash/src/parse.y"
1392 { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); ;
1395 #line 452 "/usr/homes/chet/src/bash/src/parse.y"
1396 { yyval.command = clean_simple_command (yyvsp[0].command); ;
1399 #line 454 "/usr/homes/chet/src/bash/src/parse.y"
1400 { yyval.command = yyvsp[0].command; ;
1403 #line 456 "/usr/homes/chet/src/bash/src/parse.y"
1407 tc = yyvsp[-1].command;
1408 /* According to Posix.2 3.9.5, redirections
1409 specified after the body of a function should
1410 be attached to the function and performed when
1411 the function is executed, not as part of the
1412 function definition command. */
1413 if (tc->type == cm_function_def)
1415 tc = tc->value.Function_def->command;
1416 if (tc->type == cm_group)
1417 tc = tc->value.Group->command;
1421 register REDIRECT *t;
1422 for (t = tc->redirects; t->next; t = t->next)
1424 t->next = yyvsp[0].redirect;
1427 tc->redirects = yyvsp[0].redirect;
1428 yyval.command = yyvsp[-1].command;
1432 #line 485 "/usr/homes/chet/src/bash/src/parse.y"
1433 { yyval.command = yyvsp[0].command; ;
1436 #line 487 "/usr/homes/chet/src/bash/src/parse.y"
1437 { yyval.command = yyvsp[0].command; ;
1440 #line 489 "/usr/homes/chet/src/bash/src/parse.y"
1441 { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); ;
1444 #line 491 "/usr/homes/chet/src/bash/src/parse.y"
1445 { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); ;
1448 #line 493 "/usr/homes/chet/src/bash/src/parse.y"
1449 { yyval.command = yyvsp[0].command; ;
1452 #line 495 "/usr/homes/chet/src/bash/src/parse.y"
1453 { yyval.command = yyvsp[0].command; ;
1456 #line 497 "/usr/homes/chet/src/bash/src/parse.y"
1457 { yyval.command = yyvsp[0].command; ;
1460 #line 499 "/usr/homes/chet/src/bash/src/parse.y"
1461 { yyval.command = yyvsp[0].command; ;
1464 #line 501 "/usr/homes/chet/src/bash/src/parse.y"
1465 { yyval.command = yyvsp[0].command; ;
1468 #line 503 "/usr/homes/chet/src/bash/src/parse.y"
1469 { yyval.command = yyvsp[0].command; ;
1472 #line 505 "/usr/homes/chet/src/bash/src/parse.y"
1473 { yyval.command = yyvsp[0].command; ;
1476 #line 509 "/usr/homes/chet/src/bash/src/parse.y"
1477 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1480 #line 511 "/usr/homes/chet/src/bash/src/parse.y"
1481 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1484 #line 513 "/usr/homes/chet/src/bash/src/parse.y"
1485 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1488 #line 515 "/usr/homes/chet/src/bash/src/parse.y"
1489 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1492 #line 517 "/usr/homes/chet/src/bash/src/parse.y"
1493 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1496 #line 519 "/usr/homes/chet/src/bash/src/parse.y"
1497 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1500 #line 523 "/usr/homes/chet/src/bash/src/parse.y"
1502 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1506 #line 527 "/usr/homes/chet/src/bash/src/parse.y"
1508 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command);
1512 #line 531 "/usr/homes/chet/src/bash/src/parse.y"
1514 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1518 #line 535 "/usr/homes/chet/src/bash/src/parse.y"
1520 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1524 #line 539 "/usr/homes/chet/src/bash/src/parse.y"
1526 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1530 #line 543 "/usr/homes/chet/src/bash/src/parse.y"
1532 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1536 #line 549 "/usr/homes/chet/src/bash/src/parse.y"
1537 { yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL); ;
1540 #line 551 "/usr/homes/chet/src/bash/src/parse.y"
1541 { yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern); ;
1544 #line 553 "/usr/homes/chet/src/bash/src/parse.y"
1545 { yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern); ;
1548 #line 557 "/usr/homes/chet/src/bash/src/parse.y"
1549 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1552 #line 561 "/usr/homes/chet/src/bash/src/parse.y"
1553 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1556 #line 564 "/usr/homes/chet/src/bash/src/parse.y"
1557 { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command, function_dstart, function_bstart); ;
1560 #line 568 "/usr/homes/chet/src/bash/src/parse.y"
1561 { yyvsp[-1].command->flags |= CMD_WANT_SUBSHELL; yyval.command = yyvsp[-1].command; ;
1564 #line 572 "/usr/homes/chet/src/bash/src/parse.y"
1565 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); ;
1568 #line 574 "/usr/homes/chet/src/bash/src/parse.y"
1569 { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); ;
1572 #line 576 "/usr/homes/chet/src/bash/src/parse.y"
1573 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); ;
1576 #line 581 "/usr/homes/chet/src/bash/src/parse.y"
1577 { yyval.command = make_group_command (yyvsp[-1].command); ;
1580 #line 585 "/usr/homes/chet/src/bash/src/parse.y"
1581 { yyval.command = make_arith_command (yyvsp[0].word_list); ;
1584 #line 589 "/usr/homes/chet/src/bash/src/parse.y"
1585 { yyval.command = yyvsp[-1].command; ;
1588 #line 593 "/usr/homes/chet/src/bash/src/parse.y"
1589 { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); ;
1592 #line 595 "/usr/homes/chet/src/bash/src/parse.y"
1593 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); ;
1596 #line 597 "/usr/homes/chet/src/bash/src/parse.y"
1597 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); ;
1600 #line 602 "/usr/homes/chet/src/bash/src/parse.y"
1601 { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
1604 #line 606 "/usr/homes/chet/src/bash/src/parse.y"
1605 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1608 #line 608 "/usr/homes/chet/src/bash/src/parse.y"
1609 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1612 #line 610 "/usr/homes/chet/src/bash/src/parse.y"
1613 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1616 #line 612 "/usr/homes/chet/src/bash/src/parse.y"
1617 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1620 #line 617 "/usr/homes/chet/src/bash/src/parse.y"
1621 { yyvsp[-1].pattern->next = yyvsp[-2].pattern; yyval.pattern = yyvsp[-1].pattern; ;
1624 #line 621 "/usr/homes/chet/src/bash/src/parse.y"
1625 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1628 #line 623 "/usr/homes/chet/src/bash/src/parse.y"
1629 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); ;
1632 #line 632 "/usr/homes/chet/src/bash/src/parse.y"
1634 yyval.command = yyvsp[0].command;
1636 gather_here_documents ();
1640 #line 641 "/usr/homes/chet/src/bash/src/parse.y"
1642 yyval.command = yyvsp[0].command;
1646 #line 648 "/usr/homes/chet/src/bash/src/parse.y"
1648 if (yyvsp[-2].command->type == cm_connection)
1649 yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
1651 yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
1655 #line 659 "/usr/homes/chet/src/bash/src/parse.y"
1656 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1659 #line 661 "/usr/homes/chet/src/bash/src/parse.y"
1660 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1663 #line 663 "/usr/homes/chet/src/bash/src/parse.y"
1665 if (yyvsp[-3].command->type == cm_connection)
1666 yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
1668 yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
1672 #line 670 "/usr/homes/chet/src/bash/src/parse.y"
1673 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1676 #line 672 "/usr/homes/chet/src/bash/src/parse.y"
1677 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1680 #line 674 "/usr/homes/chet/src/bash/src/parse.y"
1681 { yyval.command = yyvsp[0].command; ;
1684 #line 693 "/usr/homes/chet/src/bash/src/parse.y"
1686 yyval.command = yyvsp[0].command;
1688 gather_here_documents ();
1692 #line 699 "/usr/homes/chet/src/bash/src/parse.y"
1694 if (yyvsp[-1].command->type == cm_connection)
1695 yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
1697 yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
1699 gather_here_documents ();
1703 #line 708 "/usr/homes/chet/src/bash/src/parse.y"
1705 yyval.command = yyvsp[-1].command;
1707 gather_here_documents ();
1711 #line 716 "/usr/homes/chet/src/bash/src/parse.y"
1712 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1715 #line 718 "/usr/homes/chet/src/bash/src/parse.y"
1716 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1719 #line 720 "/usr/homes/chet/src/bash/src/parse.y"
1721 if (yyvsp[-2].command->type == cm_connection)
1722 yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
1724 yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
1728 #line 727 "/usr/homes/chet/src/bash/src/parse.y"
1729 { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); ;
1732 #line 730 "/usr/homes/chet/src/bash/src/parse.y"
1733 { yyval.command = yyvsp[0].command; ;
1736 #line 734 "/usr/homes/chet/src/bash/src/parse.y"
1737 { yyval.command = yyvsp[0].command; ;
1740 #line 736 "/usr/homes/chet/src/bash/src/parse.y"
1742 yyvsp[0].command->flags |= CMD_INVERT_RETURN;
1743 yyval.command = yyvsp[0].command;
1747 #line 741 "/usr/homes/chet/src/bash/src/parse.y"
1749 yyvsp[0].command->flags |= yyvsp[-1].number;
1750 yyval.command = yyvsp[0].command;
1754 #line 746 "/usr/homes/chet/src/bash/src/parse.y"
1756 yyvsp[0].command->flags |= yyvsp[-2].number;
1757 yyval.command = yyvsp[0].command;
1761 #line 751 "/usr/homes/chet/src/bash/src/parse.y"
1763 yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
1764 yyval.command = yyvsp[0].command;
1768 #line 759 "/usr/homes/chet/src/bash/src/parse.y"
1769 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); ;
1772 #line 761 "/usr/homes/chet/src/bash/src/parse.y"
1773 { yyval.command = yyvsp[0].command; ;
1776 #line 765 "/usr/homes/chet/src/bash/src/parse.y"
1777 { yyval.number = CMD_TIME_PIPELINE; ;
1780 #line 767 "/usr/homes/chet/src/bash/src/parse.y"
1781 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; ;
1784 /* the action file gets copied in in place of this dollarsign */
1785 #line 498 "/usr/share/misc/bison.simple"
1796 short *ssp1 = yyss - 1;
1797 fprintf (stderr, "state stack now");
1798 while (ssp1 != yyssp)
1799 fprintf (stderr, " %d", *++ssp1);
1800 fprintf (stderr, "\n");
1810 yylsp->first_line = yylloc.first_line;
1811 yylsp->first_column = yylloc.first_column;
1812 yylsp->last_line = (yylsp-1)->last_line;
1813 yylsp->last_column = (yylsp-1)->last_column;
1818 yylsp->last_line = (yylsp+yylen-1)->last_line;
1819 yylsp->last_column = (yylsp+yylen-1)->last_column;
1823 /* Now "shift" the result of the reduction.
1824 Determine what state that goes to,
1825 based on the state we popped back to
1826 and the rule number reduced by. */
1830 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1831 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1832 yystate = yytable[yystate];
1834 yystate = yydefgoto[yyn - YYNTBASE];
1838 yyerrlab: /* here on detecting error */
1841 /* If not already recovering from an error, report this error. */
1845 #ifdef YYERROR_VERBOSE
1846 yyn = yypact[yystate];
1848 if (yyn > YYFLAG && yyn < YYLAST)
1855 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1856 for (x = (yyn < 0 ? -yyn : 0);
1857 x < (sizeof(yytname) / sizeof(char *)); x++)
1858 if (yycheck[x + yyn] == x)
1859 size += strlen(yytname[x]) + 15, count++;
1860 msg = (char *) malloc(size + 15);
1863 strcpy(msg, "parse error");
1868 for (x = (yyn < 0 ? -yyn : 0);
1869 x < (sizeof(yytname) / sizeof(char *)); x++)
1870 if (yycheck[x + yyn] == x)
1872 strcat(msg, count == 0 ? ", expecting `" : " or `");
1873 strcat(msg, yytname[x]);
1882 yyerror ("parse error; also virtual memory exceeded");
1885 #endif /* YYERROR_VERBOSE */
1886 yyerror("parse error");
1890 yyerrlab1: /* here on error raised explicitly by an action */
1892 if (yyerrstatus == 3)
1894 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1896 /* return failure if at end of input */
1897 if (yychar == YYEOF)
1902 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1908 /* Else will try to reuse lookahead token
1909 after shifting the error token. */
1911 yyerrstatus = 3; /* Each real token shifted decrements this */
1915 yyerrdefault: /* current state does not do anything special for the error token. */
1918 /* This is wrong; only states that explicitly want error tokens
1919 should shift them. */
1920 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1921 if (yyn) goto yydefault;
1924 yyerrpop: /* pop the current state because it cannot handle the error token */
1926 if (yyssp == yyss) YYABORT;
1936 short *ssp1 = yyss - 1;
1937 fprintf (stderr, "Error: state stack now");
1938 while (ssp1 != yyssp)
1939 fprintf (stderr, " %d", *++ssp1);
1940 fprintf (stderr, "\n");
1946 yyn = yypact[yystate];
1951 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1970 fprintf(stderr, "Shifting error token, ");
1981 #line 769 "/usr/homes/chet/src/bash/src/parse.y"
1984 /* Possible states for the parser that require it to do special things. */
1985 #define PST_CASEPAT 0x001 /* in a case pattern list */
1986 #define PST_ALEXPNEXT 0x002 /* expand next word for aliases */
1987 #define PST_ALLOWOPNBRC 0x004 /* allow open brace for function def */
1988 #define PST_NEEDCLOSBRC 0x008 /* need close brace */
1989 #define PST_DBLPAREN 0x010 /* double-paren parsing */
1990 #define PST_SUBSHELL 0x020 /* ( ... ) subshell */
1991 #define PST_CMDSUBST 0x040 /* $( ... ) command substitution */
1992 #define PST_CASESTMT 0x080 /* parsing a case statement */
1993 #define PST_CONDCMD 0x100 /* parsing a [[...]] command */
1994 #define PST_CONDEXPR 0x200 /* parsing the guts of [[...]] */
1996 /* Initial size to allocate for tokens, and the
1997 amount to grow them by. */
1998 #define TOKEN_DEFAULT_INITIAL_SIZE 496
1999 #define TOKEN_DEFAULT_GROW_SIZE 512
2001 /* Shell meta-characters that, when unquoted, separate words. */
2002 #define shellmeta(c) (strchr (shell_meta_chars, (c)) != 0)
2003 #define shellbreak(c) (strchr (shell_break_chars, (c)) != 0)
2004 #define shellquote(c) ((c) == '"' || (c) == '`' || (c) == '\'')
2005 #define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>')
2007 char *shell_meta_chars = "()<>;&|";
2008 char *shell_break_chars = "()<>;&| \t\n";
2010 /* The token currently being read. */
2011 static int current_token;
2013 /* The last read token, or NULL. read_token () uses this for context
2015 static int last_read_token;
2017 /* The token read prior to last_read_token. */
2018 static int token_before_that;
2020 /* The token read prior to token_before_that. */
2021 static int two_tokens_ago;
2023 /* If non-zero, it is the token that we want read_token to return
2024 regardless of what text is (or isn't) present to be read. This
2025 is reset by read_token. If token_to_read == WORD or
2026 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
2027 static int token_to_read;
2028 static WORD_DESC *word_desc_to_read;
2030 /* The current parser state. */
2031 static int parser_state;
2033 /* Global var is non-zero when end of file has been reached. */
2034 int EOF_Reached = 0;
2045 /* yy_getc () returns the next available character from input or EOF.
2046 yy_ungetc (c) makes `c' the next character to read.
2047 init_yy_io (get, unget, type, location) makes the function GET the
2048 installed function for getting the next character, makes UNGET the
2049 installed function for un-getting a character, sets the type of stream
2050 (either string or file) from TYPE, and makes LOCATION point to where
2051 the input is coming from. */
2053 /* Unconditionally returns end-of-file. */
2060 /* Variable containing the current get and unget functions.
2061 See ./input.h for a clearer description. */
2062 BASH_INPUT bash_input;
2064 /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
2065 is non-null, avoiding a memory leak. */
2067 initialize_bash_input ()
2069 bash_input.type = st_none;
2070 FREE (bash_input.name);
2071 bash_input.name = (char *)NULL;
2072 bash_input.location.file = (FILE *)NULL;
2073 bash_input.location.string = (char *)NULL;
2074 bash_input.getter = (Function *)NULL;
2075 bash_input.ungetter = (Function *)NULL;
2078 /* Set the contents of the current bash input stream from
2079 GET, UNGET, TYPE, NAME, and LOCATION. */
2081 init_yy_io (get, unget, type, name, location)
2082 Function *get, *unget;
2083 enum stream_type type;
2085 INPUT_STREAM location;
2087 bash_input.type = type;
2088 FREE (bash_input.name);
2089 bash_input.name = name ? savestring (name) : (char *)NULL;
2093 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
2095 bash_input.location = location;
2097 bash_input.getter = get;
2098 bash_input.ungetter = unget;
2101 /* Call this to get the next character of input. */
2105 return (*(bash_input.getter)) ();
2108 /* Call this to unget C. That is, to make C the next character
2114 return (*(bash_input.ungetter)) (c);
2117 #if defined (BUFFERED_INPUT)
2119 input_file_descriptor ()
2121 switch (bash_input.type)
2124 return (fileno (bash_input.location.file));
2126 return (bash_input.location.buffered_fd);
2129 return (fileno (stdin));
2132 #endif /* BUFFERED_INPUT */
2134 /* **************************************************************** */
2136 /* Let input be read from readline (). */
2138 /* **************************************************************** */
2140 #if defined (READLINE)
2141 char *current_readline_prompt = (char *)NULL;
2142 char *current_readline_line = (char *)NULL;
2143 int current_readline_line_index = 0;
2148 SigHandler *old_sigint;
2151 if (!current_readline_line)
2153 if (!bash_readline_initialized)
2154 initialize_readline ();
2156 #if defined (JOB_CONTROL)
2158 give_terminal_to (shell_pgrp);
2159 #endif /* JOB_CONTROL */
2161 if (signal_is_ignored (SIGINT) == 0)
2163 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
2164 interrupt_immediately++;
2167 current_readline_line = readline (current_readline_prompt ?
2168 current_readline_prompt : "");
2170 if (signal_is_ignored (SIGINT) == 0)
2172 interrupt_immediately--;
2173 set_signal_handler (SIGINT, old_sigint);
2177 /* Reset the prompt to the decoded value of prompt_string_pointer. */
2178 reset_readline_prompt ();
2181 if (current_readline_line == 0)
2184 current_readline_line_index = 0;
2185 line_len = strlen (current_readline_line);
2187 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
2188 current_readline_line[line_len++] = '\n';
2189 current_readline_line[line_len] = '\0';
2192 if (current_readline_line[current_readline_line_index] == 0)
2194 free (current_readline_line);
2195 current_readline_line = (char *)NULL;
2196 return (yy_readline_get ());
2200 c = (unsigned char)current_readline_line[current_readline_line_index++];
2206 yy_readline_unget (c)
2209 if (current_readline_line_index && current_readline_line)
2210 current_readline_line[--current_readline_line_index] = c;
2215 with_input_from_stdin ()
2217 INPUT_STREAM location;
2219 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
2221 location.string = current_readline_line;
2222 init_yy_io (yy_readline_get, yy_readline_unget,
2223 st_stdin, "readline stdin", location);
2227 #else /* !READLINE */
2230 with_input_from_stdin ()
2232 with_input_from_stream (stdin, "stdin");
2234 #endif /* !READLINE */
2236 /* **************************************************************** */
2238 /* Let input come from STRING. STRING is zero terminated. */
2240 /* **************************************************************** */
2245 register char *string;
2248 string = bash_input.location.string;
2251 /* If the string doesn't exist, or is empty, EOF found. */
2252 if (string && *string)
2254 c = *(unsigned char *)string++;
2255 bash_input.location.string = string;
2264 *(--bash_input.location.string) = c;
2269 with_input_from_string (string, name)
2270 char *string, *name;
2272 INPUT_STREAM location;
2274 location.string = string;
2275 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
2278 /* **************************************************************** */
2280 /* Let input come from STREAM. */
2282 /* **************************************************************** */
2289 if (bash_input.location.file)
2291 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2292 result = getc_with_restart (bash_input.location.file);
2293 #else /* HAVE_RESTARTABLE_SYSCALLS */
2294 result = getc (bash_input.location.file);
2295 result = (feof (bash_input.location.file)) ? EOF : (unsigned char)result;
2296 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2305 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2306 return (ungetc_with_restart (c, bash_input.location.file));
2307 #else /* HAVE_RESTARTABLE_SYSCALLS */
2308 return (ungetc (c, bash_input.location.file));
2309 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2313 with_input_from_stream (stream, name)
2317 INPUT_STREAM location;
2319 location.file = stream;
2320 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
2323 typedef struct stream_saver {
2324 struct stream_saver *next;
2325 BASH_INPUT bash_input;
2327 #if defined (BUFFERED_INPUT)
2328 BUFFERED_STREAM *bstream;
2329 #endif /* BUFFERED_INPUT */
2332 /* The globally known line number. */
2333 int line_number = 0;
2335 #if defined (COND_COMMAND)
2336 static int cond_lineno;
2337 static int cond_token;
2340 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
2343 push_stream (reset_lineno)
2346 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
2348 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
2350 #if defined (BUFFERED_INPUT)
2351 saver->bstream = (BUFFERED_STREAM *)NULL;
2352 /* If we have a buffered stream, clear out buffers[fd]. */
2353 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2354 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
2355 (BUFFERED_STREAM *)NULL);
2356 #endif /* BUFFERED_INPUT */
2358 saver->line = line_number;
2359 bash_input.name = (char *)NULL;
2360 saver->next = stream_list;
2361 stream_list = saver;
2374 STREAM_SAVER *saver = stream_list;
2377 stream_list = stream_list->next;
2379 init_yy_io (saver->bash_input.getter,
2380 saver->bash_input.ungetter,
2381 saver->bash_input.type,
2382 saver->bash_input.name,
2383 saver->bash_input.location);
2385 #if defined (BUFFERED_INPUT)
2386 /* If we have a buffered stream, restore buffers[fd]. */
2387 /* If the input file descriptor was changed while this was on the
2388 save stack, update the buffered fd to the new file descriptor and
2389 re-establish the buffer <-> bash_input fd correspondence. */
2390 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2392 if (bash_input_fd_changed)
2394 bash_input_fd_changed = 0;
2395 if (default_buffered_input >= 0)
2397 bash_input.location.buffered_fd = default_buffered_input;
2398 saver->bstream->b_fd = default_buffered_input;
2401 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
2403 #endif /* BUFFERED_INPUT */
2405 line_number = saver->line;
2407 FREE (saver->bash_input.name);
2412 /* Return 1 if a stream of type TYPE is saved on the stack. */
2414 stream_on_stack (type)
2415 enum stream_type type;
2417 register STREAM_SAVER *s;
2419 for (s = stream_list; s; s = s->next)
2420 if (s->bash_input.type == type)
2426 * This is used to inhibit alias expansion and reserved word recognition
2427 * inside case statement pattern lists. A `case statement pattern list' is:
2429 * everything between the `in' in a `case word in' and the next ')'
2431 * everything between a `;;' and the next `)' or `esac'
2434 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2436 #if !defined (ALIAS)
2437 typedef void *alias_t;
2440 #define END_OF_ALIAS 0
2443 * Pseudo-global variables used in implementing token-wise alias expansion.
2447 * Pushing and popping strings. This works together with shell_getc to
2448 * implement alias expansion on a per-token basis.
2451 typedef struct string_saver {
2452 struct string_saver *next;
2453 int expand_alias; /* Value to set expand_alias to when string is popped. */
2456 alias_t *expander; /* alias that caused this line to be pushed. */
2458 int saved_line_size, saved_line_index, saved_line_terminator;
2461 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
2464 * Push the current shell_input_line onto a stack of such lines and make S
2465 * the current input. Used when expanding aliases. EXPAND is used to set
2466 * the value of expand_next_token when the string is popped, so that the
2467 * word after the alias in the original line is handled correctly when the
2468 * alias expands to multiple words. TOKEN is the token that was expanded
2469 * into S; it is saved and used to prevent infinite recursive expansion.
2472 push_string (s, expand, ap)
2477 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
2479 temp->expand_alias = expand;
2480 temp->saved_line = shell_input_line;
2481 temp->saved_line_size = shell_input_line_size;
2482 temp->saved_line_index = shell_input_line_index;
2483 temp->saved_line_terminator = shell_input_line_terminator;
2485 temp->expander = ap;
2487 temp->next = pushed_string_list;
2488 pushed_string_list = temp;
2492 ap->flags |= AL_BEINGEXPANDED;
2495 shell_input_line = s;
2496 shell_input_line_size = strlen (s);
2497 shell_input_line_index = 0;
2498 shell_input_line_terminator = '\0';
2499 parser_state &= ~PST_ALEXPNEXT;
2503 * Make the top of the pushed_string stack be the current shell input.
2504 * Only called when there is something on the stack. Called from shell_getc
2505 * when it thinks it has consumed the string generated by an alias expansion
2506 * and needs to return to the original input line.
2513 FREE (shell_input_line);
2514 shell_input_line = pushed_string_list->saved_line;
2515 shell_input_line_index = pushed_string_list->saved_line_index;
2516 shell_input_line_size = pushed_string_list->saved_line_size;
2517 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
2519 if (pushed_string_list->expand_alias)
2520 parser_state |= PST_ALEXPNEXT;
2522 parser_state &= ~PST_ALEXPNEXT;
2524 t = pushed_string_list;
2525 pushed_string_list = pushed_string_list->next;
2529 t->expander->flags &= ~AL_BEINGEXPANDED;
2538 register STRING_SAVER *t, *t1;
2540 for (t = pushed_string_list; t; )
2543 FREE (t->saved_line);
2546 t->expander->flags &= ~AL_BEINGEXPANDED;
2551 pushed_string_list = (STRING_SAVER *)NULL;
2554 #endif /* ALIAS || DPAREN_ARITHMETIC */
2556 /* Return a line of text, taken from wherever yylex () reads input.
2557 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
2558 is non-zero, we remove unquoted \<newline> pairs. This is used by
2559 read_secondary_line to read here documents. */
2561 read_a_line (remove_quoted_newline)
2562 int remove_quoted_newline;
2564 static char *line_buffer = (char *)NULL;
2565 static int buffer_size = 0;
2566 int indx = 0, c, peekc, pass_next;
2568 #if defined (READLINE)
2569 if (interactive && bash_input.type != st_string && no_line_editing)
2571 if (interactive && bash_input.type != st_string)
2580 /* Allow immediate exit if interrupted during input. */
2586 /* If there is no more input, then we return NULL. */
2589 if (interactive && bash_input.type == st_stream)
2592 return ((char *)NULL);
2596 /* `+2' in case the final character in the buffer is a newline. */
2597 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
2599 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
2600 here document with an unquoted delimiter. In this case,
2601 the line will be expanded as if it were in double quotes.
2602 We allow a backslash to escape the next character, but we
2603 need to treat the backslash specially only if a backslash
2604 quoting a backslash-newline pair appears in the line. */
2607 line_buffer[indx++] = c;
2610 else if (c == '\\' && remove_quoted_newline)
2614 continue; /* Make the unquoted \<newline> pair disappear. */
2619 line_buffer[indx++] = c; /* Preserve the backslash. */
2623 line_buffer[indx++] = c;
2627 line_buffer[indx] = '\0';
2628 return (line_buffer);
2633 /* Return a line as in read_a_line (), but insure that the prompt is
2634 the secondary prompt. This is used to read the lines of a here
2635 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2636 newlines quoted with backslashes while reading the line. It is
2637 non-zero unless the delimiter of the here document was quoted. */
2639 read_secondary_line (remove_quoted_newline)
2640 int remove_quoted_newline;
2642 prompt_string_pointer = &ps2_prompt;
2644 return (read_a_line (remove_quoted_newline));
2647 /* **************************************************************** */
2651 /* **************************************************************** */
2653 /* Reserved words. These are only recognized as the first word of a
2655 STRING_INT_ALIST word_token_alist[] = {
2664 #if defined (SELECT_COMMAND)
2665 { "select", SELECT },
2672 { "function", FUNCTION },
2673 #if defined (COMMAND_TIMING)
2679 #if defined (COND_COMMAND)
2680 { "[[", COND_START },
2686 /* XXX - we should also have an alist with strings for other tokens, so we
2687 can give more descriptive error messages. Look at y.tab.h for the
2690 /* These are used by read_token_word, but appear up here so that shell_getc
2691 can use them to decide when to add otherwise blank lines to the history. */
2693 /* The primary delimiter stack. */
2694 struct dstack dstack = { (char *)NULL, 0, 0 };
2696 /* A temporary delimiter stack to be used when decoding prompt strings.
2697 This is needed because command substitutions in prompt strings (e.g., PS2)
2698 can screw up the parser's quoting state. */
2699 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2701 /* Macro for accessing the top delimiter on the stack. Returns the
2702 delimiter or zero if none. */
2703 #define current_delimiter(ds) \
2704 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2706 #define push_delimiter(ds, character) \
2709 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2710 ds.delimiters = xrealloc \
2711 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2712 ds.delimiters[ds.delimiter_depth] = character; \
2713 ds.delimiter_depth++; \
2717 #define pop_delimiter(ds) ds.delimiter_depth--
2719 /* Return the next shell input character. This always reads characters
2720 from shell_input_line; when that line is exhausted, it is time to
2721 read the next line. This is called by read_token when the shell is
2722 processing normal command input. */
2725 shell_getc (remove_quoted_newline)
2726 int remove_quoted_newline;
2730 static int mustpop = 0;
2734 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2735 /* If shell_input_line[shell_input_line_index] == 0, but there is
2736 something on the pushed list of strings, then we don't want to go
2737 off and get another line. We let the code down below handle it. */
2739 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2740 (pushed_string_list == (STRING_SAVER *)NULL)))
2741 #else /* !ALIAS && !DPAREN_ARITHMETIC */
2742 if (!shell_input_line || !shell_input_line[shell_input_line_index])
2743 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
2749 /* Allow immediate exit if interrupted during input. */
2753 shell_input_line_terminator = 0;
2755 #if defined (JOB_CONTROL)
2756 /* This can cause a problem when reading a command as the result
2757 of a trap, when the trap is called from flush_child. This call
2758 had better not cause jobs to disappear from the job table in
2759 that case, or we will have big trouble. */
2760 notify_and_cleanup ();
2761 #else /* !JOB_CONTROL */
2762 cleanup_dead_jobs ();
2763 #endif /* !JOB_CONTROL */
2765 #if defined (READLINE)
2766 if (interactive && bash_input.type != st_string && no_line_editing)
2768 if (interactive && bash_input.type != st_string)
2772 if (bash_input.type == st_stream)
2775 while (c = yy_getc ())
2777 /* Allow immediate exit if interrupted during input. */
2780 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2784 if (bash_input.type == st_stream)
2788 shell_input_line_terminator = EOF;
2790 shell_input_line[i] = '\0';
2794 shell_input_line[i++] = c;
2798 shell_input_line[--i] = '\0';
2799 current_command_line_count++;
2803 shell_input_line_index = 0;
2804 shell_input_line_len = i; /* == strlen (shell_input_line) */
2806 #if defined (HISTORY)
2807 if (remember_on_history && shell_input_line && shell_input_line[0])
2810 # if defined (BANG_HISTORY)
2813 /* If the current delimiter is a single quote, we should not be
2814 performing history expansion, even if we're on a different
2815 line from the original single quote. */
2816 old_hist = history_expansion_inhibited;
2817 if (current_delimiter (dstack) == '\'')
2818 history_expansion_inhibited = 1;
2820 expansions = pre_process_line (shell_input_line, 1, 1);
2821 # if defined (BANG_HISTORY)
2822 history_expansion_inhibited = old_hist;
2824 if (expansions != shell_input_line)
2826 free (shell_input_line);
2827 shell_input_line = expansions;
2828 shell_input_line_len = shell_input_line ?
2829 strlen (shell_input_line) : 0;
2830 if (!shell_input_line_len)
2831 current_command_line_count--;
2833 /* We have to force the xrealloc below because we don't know
2834 the true allocated size of shell_input_line anymore. */
2835 shell_input_line_size = shell_input_line_len;
2838 /* XXX - this is grotesque */
2839 else if (remember_on_history && shell_input_line &&
2840 shell_input_line[0] == '\0' &&
2841 current_command_line_count > 1 && current_delimiter (dstack))
2843 /* We know shell_input_line[0] == 0 and we're reading some sort of
2844 quoted string. This means we've got a line consisting of only
2845 a newline in a quoted string. We want to make sure this line
2846 gets added to the history. */
2847 maybe_add_history (shell_input_line);
2850 #endif /* HISTORY */
2852 if (shell_input_line)
2854 /* Lines that signify the end of the shell's input should not be
2856 if (echo_input_at_read && (shell_input_line[0] ||
2857 shell_input_line_terminator != EOF))
2858 fprintf (stderr, "%s\n", shell_input_line);
2862 shell_input_line_size = 0;
2863 prompt_string_pointer = ¤t_prompt_string;
2868 /* Add the newline to the end of this string, iff the string does
2869 not already end in an EOF character. */
2870 if (shell_input_line_terminator != EOF)
2872 if (shell_input_line_len + 3 > shell_input_line_size)
2873 shell_input_line = xrealloc (shell_input_line,
2874 1 + (shell_input_line_size += 2));
2876 shell_input_line[shell_input_line_len] = '\n';
2877 shell_input_line[shell_input_line_len + 1] = '\0';
2881 c = shell_input_line[shell_input_line_index];
2884 shell_input_line_index++;
2886 if (c == '\\' && remove_quoted_newline &&
2887 shell_input_line[shell_input_line_index] == '\n')
2894 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2895 /* If C is NULL, we have reached the end of the current input string. If
2896 pushed_string_list is non-empty, it's time to pop to the previous string
2897 because we have fully consumed the result of the last alias expansion.
2898 Do it transparently; just return the next character of the string popped
2900 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
2905 c = shell_input_line[shell_input_line_index];
2907 shell_input_line_index++;
2916 #endif /* ALIAS || DPAREN_ARITHMETIC */
2918 if (!c && shell_input_line_terminator == EOF)
2919 return ((shell_input_line_index != 0) ? '\n' : EOF);
2921 return ((unsigned char)c);
2924 /* Put C back into the input for the shell. */
2929 if (shell_input_line && shell_input_line_index)
2930 shell_input_line[--shell_input_line_index] = c;
2936 if (shell_input_line && shell_input_line_index)
2937 shell_input_line_index--;
2940 /* Discard input until CHARACTER is seen, then push that character back
2941 onto the input stream. */
2943 discard_until (character)
2948 while ((c = shell_getc (0)) != EOF && c != character)
2956 execute_prompt_command (command)
2959 Function *temp_last, *temp_this;
2961 int temp_exit_value, temp_eof_encountered;
2963 temp_last = last_shell_builtin;
2964 temp_this = this_shell_builtin;
2965 temp_exit_value = last_command_exit_value;
2966 temp_eof_encountered = eof_encountered;
2967 last_lastarg = get_string_value ("_");
2969 last_lastarg = savestring (last_lastarg);
2971 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
2973 last_shell_builtin = temp_last;
2974 this_shell_builtin = temp_this;
2975 last_command_exit_value = temp_exit_value;
2976 eof_encountered = temp_eof_encountered;
2978 bind_variable ("_", last_lastarg);
2979 FREE (last_lastarg);
2981 if (token_to_read == '\n') /* reset_parser was called */
2985 /* Place to remember the token. We try to keep the buffer
2986 at a reasonable size, but it can grow. */
2987 static char *token = (char *)NULL;
2989 /* Current size of the token buffer. */
2990 static int token_buffer_size;
2992 /* Command to read_token () explaining what we want it to do. */
2995 #define prompt_is_ps1 \
2996 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2998 /* Function for yyparse to call. yylex keeps track of
2999 the last two tokens read, and calls read_token. */
3003 if (interactive && (current_token == 0 || current_token == '\n'))
3005 /* Before we print a prompt, we might have to check mailboxes.
3006 We do this only if it is time to do so. Notice that only here
3007 is the mail alarm reset; nothing takes place in check_mail ()
3008 except the checking of mail. Please don't change this. */
3009 if (prompt_is_ps1 && time_to_check_mail ())
3012 reset_mail_timer ();
3015 /* Avoid printing a prompt if we're not going to read anything, e.g.
3016 after resetting the parser with read_token (RESET). */
3017 if (token_to_read == 0 && interactive)
3021 two_tokens_ago = token_before_that;
3022 token_before_that = last_read_token;
3023 last_read_token = current_token;
3024 current_token = read_token (READ);
3025 return (current_token);
3028 /* When non-zero, we have read the required tokens
3029 which allow ESAC to be the next one read. */
3030 static int esacs_needed_count;
3033 gather_here_documents ()
3036 while (need_here_doc)
3038 make_here_document (redir_stack[r++]);
3043 /* When non-zero, an open-brace used to create a group is awaiting a close
3045 static int open_brace_count;
3047 #define command_token_position(token) \
3048 (((token) == ASSIGNMENT_WORD) || \
3049 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
3051 #define assignment_acceptable(token) command_token_position(token) && \
3052 ((parser_state & PST_CASEPAT) == 0)
3054 /* Check to see if TOKEN is a reserved word and return the token
3056 #define CHECK_FOR_RESERVED_WORD(tok) \
3058 if (!dollar_present && !quoted && \
3059 reserved_word_acceptable (last_read_token)) \
3062 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
3063 if (STREQ (tok, word_token_alist[i].word)) \
3065 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
3067 if (word_token_alist[i].token == TIME) \
3069 if (word_token_alist[i].token == ESAC) \
3070 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
3071 else if (word_token_alist[i].token == CASE) \
3072 parser_state |= PST_CASESTMT; \
3073 else if (word_token_alist[i].token == COND_END) \
3074 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
3075 else if (word_token_alist[i].token == COND_START) \
3076 parser_state |= PST_CONDCMD; \
3077 else if (word_token_alist[i].token == '{') \
3078 open_brace_count++; \
3079 else if (word_token_alist[i].token == '}' && open_brace_count) \
3080 open_brace_count--; \
3081 return (word_token_alist[i].token); \
3088 /* OK, we have a token. Let's try to alias expand it, if (and only if)
3091 It is eligible for expansion if the shell is in interactive mode, and
3092 the token is unquoted and the last token read was a command
3093 separator (or expand_next_token is set), and we are currently
3094 processing an alias (pushed_string_list is non-empty) and this
3095 token is not the same as the current or any previously
3098 Special cases that disqualify:
3099 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
3101 alias_expand_token (token)
3107 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
3108 (parser_state & PST_CASEPAT) == 0)
3110 ap = find_alias (token);
3112 /* Currently expanding this token. */
3113 if (ap && (ap->flags & AL_BEINGEXPANDED))
3114 return (NO_EXPANSION);
3116 expanded = ap ? savestring (ap->value) : (char *)NULL;
3119 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
3120 return (RE_READ_TOKEN);
3123 /* This is an eligible token that does not have an expansion. */
3124 return (NO_EXPANSION);
3126 return (NO_EXPANSION);
3131 time_command_acceptable ()
3133 #if defined (COMMAND_TIMING)
3134 switch (last_read_token)
3153 #endif /* COMMAND_TIMING */
3156 /* Handle special cases of token recognition:
3157 IN is recognized if the last token was WORD and the token
3158 before that was FOR or CASE or SELECT.
3160 DO is recognized if the last token was WORD and the token
3161 before that was FOR or SELECT.
3163 ESAC is recognized if the last token caused `esacs_needed_count'
3166 `{' is recognized if the last token as WORD and the token
3167 before that was FUNCTION.
3169 `}' is recognized if there is an unclosed `{' prsent.
3171 `-p' is returned as TIMEOPT if the last read token was TIME.
3173 ']]' is returned as COND_END if the parser is currently parsing
3174 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
3176 `time' is returned as TIME if and only if it is immediately
3177 preceded by one of `;', `\n', `||', `&&', or `&'.
3181 special_case_tokens (token)
3184 if ((last_read_token == WORD) &&
3185 #if defined (SELECT_COMMAND)
3186 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3188 ((token_before_that == FOR) || (token_before_that == CASE)) &&
3190 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
3192 if (token_before_that == CASE)
3194 parser_state |= PST_CASEPAT;
3195 esacs_needed_count++;
3200 if (last_read_token == WORD &&
3201 #if defined (SELECT_COMMAND)
3202 (token_before_that == FOR || token_before_that == SELECT) &&
3204 (token_before_that == FOR) &&
3206 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
3209 /* Ditto for ESAC in the CASE case.
3210 Specifically, this handles "case word in esac", which is a legal
3211 construct, certainly because someone will pass an empty arg to the
3212 case construct, and we don't want it to barf. Of course, we should
3213 insist that the case construct has at least one pattern in it, but
3214 the designers disagree. */
3215 if (esacs_needed_count)
3217 esacs_needed_count--;
3218 if (STREQ (token, "esac"))
3220 parser_state &= ~PST_CASEPAT;
3225 /* The start of a shell function definition. */
3226 if (parser_state & PST_ALLOWOPNBRC)
3228 parser_state &= ~PST_ALLOWOPNBRC;
3229 if (token[0] == '{' && token[1] == '\0') /* } */
3232 function_bstart = line_number;
3233 return ('{'); /* } */
3237 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
3239 open_brace_count--; /* { */
3243 #if defined (COMMAND_TIMING)
3244 /* Handle -p after `time'. */
3245 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
3249 #if defined (COMMAND_TIMING)
3250 if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
3252 #endif /* COMMAND_TIMING */
3254 #if defined (COND_COMMAND) /* [[ */
3255 if ((parser_state & PST_CONDEXPR) && token[0] == ']' && token[1] == ']' && token[2] == '\0')
3262 /* Called from shell.c when Control-C is typed at top level. Or
3263 by the error rule at top level. */
3267 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3268 open_brace_count = 0;
3272 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
3273 if (pushed_string_list)
3274 free_string_list ();
3275 #endif /* ALIAS || DPAREN_ARITHMETIC */
3277 if (shell_input_line)
3279 free (shell_input_line);
3280 shell_input_line = (char *)NULL;
3281 shell_input_line_size = shell_input_line_index = 0;
3284 FREE (word_desc_to_read);
3285 word_desc_to_read = (WORD_DESC *)NULL;
3287 last_read_token = '\n';
3288 token_to_read = '\n';
3291 /* Read the next token. Command can be READ (normal operation) or
3292 RESET (to normalize state). */
3294 read_token (command)
3297 int character; /* Current character. */
3298 int peek_char; /* Temporary look-ahead character. */
3299 int result; /* The thing to return. */
3301 if (command == RESET)
3309 result = token_to_read;
3310 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3312 yylval.word = word_desc_to_read;
3313 word_desc_to_read = (WORD_DESC *)NULL;
3319 #if defined (COND_COMMAND)
3320 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
3322 cond_lineno = line_number;
3323 parser_state |= PST_CONDEXPR;
3324 yylval.command = parse_cond_command ();
3325 if (cond_token != COND_END)
3327 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
3328 parser_error (cond_lineno, "unexpected EOF while looking for `]]'");
3329 else if (cond_token != COND_ERROR)
3330 parser_error (cond_lineno, "syntax error in conditional expression");
3333 token_to_read = COND_END;
3334 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
3340 /* This is a place to jump back to once we have successfully expanded a
3341 token with an alias and pushed the string with push_string () */
3345 /* Read a single word from input. Start by skipping blanks. */
3346 while ((character = shell_getc (1)) != EOF && whitespace (character))
3349 if (character == EOF)
3355 if (character == '#' && (!interactive || interactive_comments))
3357 /* A comment. Discard until EOL or EOF, and then return a newline. */
3358 discard_until ('\n');
3360 character = '\n'; /* this will take the next if statement and return. */
3363 if (character == '\n')
3365 /* If we're about to return an unquoted newline, we can go and collect
3366 the text of any pending here document. */
3368 gather_here_documents ();
3371 parser_state &= ~PST_ALEXPNEXT;
3377 /* Shell meta-characters. */
3378 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3381 /* Turn off alias tokenization iff this character sequence would
3382 not leave us ready to read a command. */
3383 if (character == '<' || character == '>')
3384 parser_state &= ~PST_ALEXPNEXT;
3387 peek_char = shell_getc (1);
3388 if (character == peek_char)
3393 /* If '<' then we could be at "<<" or at "<<-". We have to
3394 look ahead one more character. */
3395 peek_char = shell_getc (1);
3396 if (peek_char == '-')
3397 return (LESS_LESS_MINUS);
3400 shell_ungetc (peek_char);
3405 return (GREATER_GREATER);
3408 parser_state |= PST_CASEPAT;
3410 parser_state &= ~PST_ALEXPNEXT;
3420 #if defined (DPAREN_ARITHMETIC)
3422 if (reserved_word_acceptable (last_read_token))
3428 sline = line_number;
3429 cmdtyp = parse_arith_cmd (&wval);
3430 if (cmdtyp == 1) /* arithmetic command */
3432 wd = make_word (wval);
3433 wd->flags = W_QUOTED;
3434 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
3435 free (wval); /* make_word copies it */
3438 else if (cmdtyp == 0) /* nested subshell */
3440 push_string (wval, 0, (alias_t *)NULL);
3441 if ((parser_state & PST_CASEPAT) == 0)
3442 parser_state |= PST_SUBSHELL;
3452 else if (character == '<' && peek_char == '&')
3454 else if (character == '>' && peek_char == '&')
3455 return (GREATER_AND);
3456 else if (character == '<' && peek_char == '>')
3457 return (LESS_GREATER);
3458 else if (character == '>' && peek_char == '|')
3459 return (GREATER_BAR);
3460 else if (peek_char == '>' && character == '&')
3461 return (AND_GREATER);
3463 shell_ungetc (peek_char);
3465 /* If we look like we are reading the start of a function
3466 definition, then let the reader know about it so that
3467 we will do the right thing with `{'. */
3468 if (character == ')' && last_read_token == '(' && token_before_that == WORD)
3470 parser_state |= PST_ALLOWOPNBRC;
3472 parser_state &= ~PST_ALEXPNEXT;
3474 function_dstart = line_number;
3477 /* case pattern lists may be preceded by an optional left paren. If
3478 we're not trying to parse a case pattern list, the left paren
3479 indicates a subshell. */
3480 if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3481 parser_state |= PST_SUBSHELL;
3483 else if ((parser_state & PST_CASEPAT) && character == ')')
3484 parser_state &= ~PST_CASEPAT;
3486 else if ((parser_state & PST_SUBSHELL) && character == ')')
3487 parser_state &= ~PST_SUBSHELL;
3489 #if defined (PROCESS_SUBSTITUTION)
3490 /* Check for the constructs which introduce process substitution.
3491 Shells running in `posix mode' don't do process substitution. */
3492 if (posixly_correct ||
3493 ((character != '>' && character != '<') || peek_char != '('))
3494 #endif /* PROCESS_SUBSTITUTION */
3498 /* Hack <&- (close stdin) case. */
3499 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3502 /* Okay, if we got this far, we have to read a word. Read one,
3503 and then check it against the known ones. */
3504 result = read_token_word (character);
3506 if (result == RE_READ_TOKEN)
3512 /* Match a $(...) or other grouping construct. This has to handle embedded
3513 quoted strings ('', ``, "") and nested constructs. It also must handle
3514 reprompting the user, if necessary, after reading a newline, and returning
3515 correct error values if it reads EOF. */
3517 #define P_FIRSTCLOSE 0x01
3519 static char matched_pair_error;
3521 parse_matched_pair (qc, open, close, lenp, flags)
3522 int qc; /* `"' if this construct is within double quotes */
3526 int count, ch, was_dollar;
3527 int pass_next_character, nestlen, start_lineno;
3528 char *ret, *nestret;
3529 int retind, retsize;
3532 pass_next_character = was_dollar = 0;
3534 ret = xmalloc (retsize = 64);
3537 start_lineno = line_number;
3540 ch = shell_getc (qc != '\'' && pass_next_character == 0);
3544 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
3545 EOF_Reached = 1; /* XXX */
3546 return (&matched_pair_error);
3549 /* Possible reprompting. */
3550 if (ch == '\n' && interactive &&
3551 (bash_input.type == st_stdin || bash_input.type == st_stream))
3554 if (pass_next_character) /* last char was backslash */
3556 pass_next_character = 0;
3557 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3559 if (retind > 0) retind--; /* swallow previously-added backslash */
3563 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3564 if (ch == CTLESC || ch == CTLNUL)
3565 ret[retind++] = CTLESC;
3569 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3571 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3572 ret[retind++] = CTLESC;
3576 else if (ch == close) /* ending delimiter */
3578 else if (((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
3581 /* Add this character. */
3582 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3585 if (open == '\'') /* '' inside grouping construct */
3588 if (ch == '\\') /* backslashes */
3589 pass_next_character++;
3591 if (open != close) /* a grouping construct */
3593 if (shellquote (ch))
3595 /* '', ``, or "" inside $(...) or other grouping construct. */
3596 push_delimiter (dstack, ch);
3597 nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
3598 pop_delimiter (dstack);
3599 if (nestret == &matched_pair_error)
3602 return &matched_pair_error;
3606 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3607 strcpy (ret + retind, nestret);
3613 /* Parse an old-style command substitution within double quotes as a
3615 /* XXX - sh and ksh93 don't do this - XXX */
3616 else if (open == '"' && ch == '`')
3618 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
3619 if (nestret == &matched_pair_error)
3622 return &matched_pair_error;
3626 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3627 strcpy (ret + retind, nestret);
3632 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3633 /* check for $(), $[], or ${} inside quoted string. */
3635 if (open == ch) /* undo previous increment */
3637 if (ch == '(') /* ) */
3638 nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
3639 else if (ch == '{') /* } */
3640 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE);
3641 else if (ch == '[') /* ] */
3642 nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
3643 if (nestret == &matched_pair_error)
3646 return &matched_pair_error;
3650 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3651 strcpy (ret + retind, nestret);
3656 was_dollar = (ch == '$');
3665 #if defined (DPAREN_ARITHMETIC)
3666 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
3667 If not, assume it's a nested subshell for backwards compatibility and
3668 return 0. In any case, put the characters we've consumed into a locally-
3669 allocated buffer and make *ep point to that buffer. Return -1 on an
3670 error, for example EOF. */
3672 parse_arith_cmd (ep)
3675 int exp_lineno, rval, c;
3679 exp_lineno = line_number;
3680 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3682 if (ttok == &matched_pair_error)
3684 /* Check that the next character is the closing right paren. If
3685 not, this is a syntax error. ( */
3686 if ((c = shell_getc (0)) != ')')
3689 token = xmalloc(ttoklen + 4);
3691 /* (( ... )) -> "..." */
3692 token[0] = (rval == 1) ? '"' : '(';
3693 strncpy (token + 1, ttok, ttoklen - 1); /* don't copy the final `)' */
3696 token[ttoklen] = '"';
3697 token[ttoklen+1] = '\0';
3701 token[ttoklen] = ')';
3702 token[ttoklen+1] = c;
3703 token[ttoklen+2] = '\0';
3709 #endif /* DPAREN_ARITHMETIC */
3711 #if defined (COND_COMMAND)
3712 static COND_COM *cond_term ();
3713 static COND_COM *cond_and ();
3714 static COND_COM *cond_or ();
3715 static COND_COM *cond_expr ();
3720 return (cond_or ());
3729 if (cond_token == OR_OR)
3732 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
3743 if (cond_token == AND_AND)
3746 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
3752 cond_skip_newlines ()
3754 while ((cond_token = read_token (READ)) == '\n')
3756 if (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
3759 return (cond_token);
3762 #define COND_RETURN_ERROR() \
3763 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
3769 COND_COM *term, *tleft, *tright;
3772 /* Read a token. It can be a left paren, a `!', a unary operator, or a
3773 word that should be the first argument of a binary operator. Start by
3774 skipping newlines, since this is a compound command. */
3775 tok = cond_skip_newlines ();
3776 lineno = line_number;
3777 if (tok == COND_END)
3779 COND_RETURN_ERROR ();
3781 else if (tok == '(')
3783 term = cond_expr ();
3784 if (cond_token != ')')
3787 dispose_cond_node (term); /* ( */
3788 parser_error (lineno, "expected `)'");
3789 COND_RETURN_ERROR ();
3791 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
3792 (void)cond_skip_newlines ();
3794 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
3797 dispose_word (yylval.word); /* not needed */
3798 term = cond_term ();
3800 term->flags |= CMD_INVERT_RETURN;
3802 else if (tok == WORD && test_unop (yylval.word->word))
3805 tok = read_token (READ);
3808 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3809 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3814 parser_error (line_number, "unexpected argument to conditional unary operator");
3815 COND_RETURN_ERROR ();
3818 (void)cond_skip_newlines ();
3820 else /* left argument to binary operator */
3823 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3826 tok = read_token (READ);
3827 if (tok == WORD && test_binop (yylval.word->word))
3829 else if (tok == '<' || tok == '>')
3830 op = make_word_from_token (tok);
3831 else if (tok == COND_END || tok == AND_AND || tok == OR_OR)
3833 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
3834 the test command. Similarly for [[ x && expr ]] or
3836 op = make_word ("-n");
3837 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3843 parser_error (line_number, "conditional binary operator expected");
3844 dispose_cond_node (tleft);
3845 COND_RETURN_ERROR ();
3849 tok = read_token (READ);
3852 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3853 term = make_cond_node (COND_BINARY, op, tleft, tright);
3857 parser_error (line_number, "unexpected argument to conditional binary operator");
3858 dispose_cond_node (tleft);
3860 COND_RETURN_ERROR ();
3863 (void)cond_skip_newlines ();
3868 /* This is kind of bogus -- we slip a mini recursive-descent parser in
3869 here to handle the conditional statement syntax. */
3871 parse_cond_command ()
3875 cexp = cond_expr ();
3876 return (make_cond_command (cexp));
3881 read_token_word (character)
3884 /* The value for YYLVAL when a WORD is read. */
3885 WORD_DESC *the_word;
3887 /* Index into the token that we are building. */
3890 /* ALL_DIGITS becomes zero when we see a non-digit. */
3893 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3896 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3899 /* Non-zero means to ignore the value of the next character, and just
3900 to add it no matter what. */
3901 int pass_next_character;
3903 /* The current delimiting character. */
3905 int result, peek_char;
3906 char *ttok, *ttrans;
3907 int ttoklen, ttranslen;
3909 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
3910 token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
3913 all_digits = digit (character);
3914 dollar_present = quoted = pass_next_character = 0;
3918 if (character == EOF)
3921 if (pass_next_character)
3923 pass_next_character = 0;
3927 cd = current_delimiter (dstack);
3929 /* Handle backslashes. Quote lots of things when not inside of
3930 double-quotes, quote some things inside of double-quotes. */
3931 if (character == '\\')
3933 peek_char = shell_getc (0);
3935 /* Backslash-newline is ignored in all cases except
3936 when quoted with single quotes. */
3937 if (peek_char == '\n')
3940 goto next_character;
3944 shell_ungetc (peek_char);
3946 /* If the next character is to be quoted, note it now. */
3947 if (cd == 0 || cd == '`' ||
3948 (cd == '"' && member (peek_char, slashify_in_quotes)))
3949 pass_next_character++;
3956 /* Parse a matched pair of quote characters. */
3957 if (shellquote (character))
3959 push_delimiter (dstack, character);
3960 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
3961 pop_delimiter (dstack);
3962 if (ttok == &matched_pair_error)
3963 return -1; /* Bail immediately. */
3964 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3965 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3966 token[token_index++] = character;
3967 strcpy (token + token_index, ttok);
3968 token_index += ttoklen;
3971 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3973 goto next_character;
3976 #ifdef EXTENDED_GLOB
3977 /* Parse a ksh-style extended pattern matching specification. */
3978 if (extended_glob && PATTERN_CHAR(character))
3980 peek_char = shell_getc (1);
3981 if (peek_char == '(') /* ) */
3983 push_delimiter (dstack, peek_char);
3984 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3985 pop_delimiter (dstack);
3986 if (ttok == &matched_pair_error)
3987 return -1; /* Bail immediately. */
3988 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3990 TOKEN_DEFAULT_GROW_SIZE);
3991 token[token_index++] = character;
3992 token[token_index++] = peek_char;
3993 strcpy (token + token_index, ttok);
3994 token_index += ttoklen;
3996 dollar_present = all_digits = 0;
3997 goto next_character;
4000 shell_ungetc (peek_char);
4002 #endif /* EXTENDED_GLOB */
4004 /* If the delimiter character is not single quote, parse some of
4005 the shell expansions that must be read as a single word. */
4006 #if defined (PROCESS_SUBSTITUTION)
4007 if (character == '$' || character == '<' || character == '>')
4009 if (character == '$')
4010 #endif /* !PROCESS_SUBSTITUTION */
4012 peek_char = shell_getc (1);
4013 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
4014 if (peek_char == '(' ||
4015 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
4017 if (peek_char == '{') /* } */
4018 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
4019 else if (peek_char == '(') /* ) */
4021 /* XXX - push and pop the `(' as a delimiter for use by
4022 the command-oriented-history code. This way newlines
4023 appearing in the $(...) string get added to the
4024 history literally rather than causing a possibly-
4025 incorrect `;' to be added. */
4026 push_delimiter (dstack, peek_char);
4027 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4028 pop_delimiter (dstack);
4031 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4032 if (ttok == &matched_pair_error)
4033 return -1; /* Bail immediately. */
4034 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4036 TOKEN_DEFAULT_GROW_SIZE);
4037 token[token_index++] = character;
4038 token[token_index++] = peek_char;
4039 strcpy (token + token_index, ttok);
4040 token_index += ttoklen;
4044 goto next_character;
4046 /* This handles $'...' and $"..." new-style quoted strings. */
4047 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
4051 first_line = line_number;
4052 ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
4053 if (ttok == &matched_pair_error)
4055 if (peek_char == '\'')
4056 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4058 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4060 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
4062 TOKEN_DEFAULT_GROW_SIZE);
4063 token[token_index++] = peek_char;
4064 strcpy (token + token_index, ttrans);
4065 token_index += ttranslen;
4066 token[token_index++] = peek_char;
4070 goto next_character;
4072 /* This could eventually be extended to recognize all of the
4073 shell's single-character parameter expansions, and set flags.*/
4074 else if (character == '$' && peek_char == '$')
4077 ttok[0] = ttok[1] = '$';
4079 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
4081 TOKEN_DEFAULT_GROW_SIZE);
4082 strcpy (token + token_index, ttok);
4087 goto next_character;
4090 shell_ungetc (peek_char);
4093 #if defined (ARRAY_VARS)
4094 /* Identify possible compound array variable assignment. */
4095 else if (character == '=' && token_index > 0)
4097 peek_char = shell_getc (1);
4098 if (peek_char == '(') /* ) */
4100 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4101 if (ttok == &matched_pair_error)
4102 return -1; /* Bail immediately. */
4103 if (ttok[0] == '(') /* ) */
4108 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4110 TOKEN_DEFAULT_GROW_SIZE);
4111 token[token_index++] = character;
4112 token[token_index++] = peek_char;
4113 strcpy (token + token_index, ttok);
4114 token_index += ttoklen;
4117 goto next_character;
4120 shell_ungetc (peek_char);
4124 /* When not parsing a multi-character word construct, shell meta-
4125 characters break words. */
4126 if (shellbreak (character))
4128 shell_ungetc (character);
4134 all_digits &= digit (character);
4135 dollar_present |= character == '$';
4137 if (character == CTLESC || character == CTLNUL)
4138 token[token_index++] = CTLESC;
4140 token[token_index++] = character;
4142 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
4143 TOKEN_DEFAULT_GROW_SIZE);
4146 if (character == '\n' && interactive &&
4147 (bash_input.type == st_stdin || bash_input.type == st_stream))
4150 /* We want to remove quoted newlines (that is, a \<newline> pair)
4151 unless we are within single quotes or pass_next_character is
4152 set (the shell equivalent of literal-next). */
4153 cd = current_delimiter (dstack);
4154 character = shell_getc (cd != '\'' && pass_next_character == 0);
4155 } /* end for (;;) */
4159 token[token_index] = '\0';
4161 /* Check to see what thing we should return. If the last_read_token
4162 is a `<', or a `&', or the character which ended this token is
4163 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
4164 Otherwise, it is just a word, and should be returned as such. */
4165 if (all_digits && (character == '<' || character == '>' ||
4166 last_read_token == LESS_AND ||
4167 last_read_token == GREATER_AND))
4169 yylval.number = atoi (token);
4173 /* Check for special case tokens. */
4174 result = special_case_tokens (token);
4179 /* Posix.2 does not allow reserved words to be aliased, so check for all
4180 of them, including special cases, before expanding the current token
4182 if (posixly_correct)
4183 CHECK_FOR_RESERVED_WORD (token);
4185 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
4186 inhibits alias expansion. */
4187 if (expand_aliases && quoted == 0)
4189 result = alias_expand_token (token);
4190 if (result == RE_READ_TOKEN)
4191 return (RE_READ_TOKEN);
4192 else if (result == NO_EXPANSION)
4193 parser_state &= ~PST_ALEXPNEXT;
4196 /* If not in Posix.2 mode, check for reserved words after alias
4198 if (posixly_correct == 0)
4200 CHECK_FOR_RESERVED_WORD (token);
4202 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
4203 the_word->word = xmalloc (1 + token_index);
4204 the_word->flags = 0;
4205 strcpy (the_word->word, token);
4207 the_word->flags |= W_HASDOLLAR;
4209 the_word->flags |= W_QUOTED;
4210 /* A word is an assignment if it appears at the beginning of a
4211 simple command, or after another assignment word. This is
4212 context-dependent, so it cannot be handled in the grammar. */
4213 if (assignment (token))
4215 the_word->flags |= W_ASSIGNMENT;
4216 /* Don't perform word splitting on assignment statements. */
4217 if (assignment_acceptable (last_read_token))
4218 the_word->flags |= W_NOSPLIT;
4221 yylval.word = the_word;
4223 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
4224 ? ASSIGNMENT_WORD : WORD;
4226 if (last_read_token == FUNCTION)
4228 parser_state |= PST_ALLOWOPNBRC;
4229 function_dstart = line_number;
4235 /* $'...' ANSI-C expand the portion of STRING between START and END and
4236 return the result. The result cannot be longer than the input string. */
4238 ansiexpand (string, start, end, lenp)
4240 int start, end, *lenp;
4245 temp = xmalloc (end - start + 1);
4246 for (tlen = 0, len = start; len < end; )
4247 temp[tlen++] = string[len++];
4252 t = ansicstr (temp, tlen, (int *)NULL, lenp);
4264 /* $"..." -- Translate the portion of STRING between START and END
4265 according to current locale using gettext (if available) and return
4266 the result. The caller will take care of leaving the quotes intact.
4267 The string will be left without the leading `$' by the caller.
4268 If translation is performed, the translated string will be double-quoted
4269 by the caller. The length of the translated string is returned in LENP,
4272 localeexpand (string, start, end, lineno, lenp)
4274 int start, end, lineno, *lenp;
4279 temp = xmalloc (end - start + 1);
4280 for (tlen = 0, len = start; len < end; )
4281 temp[tlen++] = string[len++];
4284 /* If we're just dumping translatable strings, don't do anything. */
4285 if (dump_translatable_strings)
4287 if (dump_po_strings)
4288 printf ("#: %s:%d\nmsgid \"%s\"\nmsgstr \"\"\n",
4289 (bash_input.name ? bash_input.name : "stdin"), lineno, temp);
4291 printf ("\"%s\"\n", temp);
4298 t = localetrans (temp, tlen, &len);
4312 /* Return 1 if TOKEN is a token that after being read would allow
4313 a reserved word to be seen, else 0. */
4315 reserved_word_acceptable (token)
4318 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
4319 token == '|' || token == '&' || token == '{' ||
4320 token == '}' || /* XXX */
4323 token == TIME || token == TIMEOPT ||
4330 token == SEMI_SEMI ||
4334 token == DONE || /* XXX these two are experimental */
4342 /* Return the index of TOKEN in the alist of reserved words, or -1 if
4343 TOKEN is not a shell reserved word. */
4345 find_reserved_word (token)
4349 for (i = 0; word_token_alist[i].word; i++)
4350 if (STREQ (token, word_token_alist[i].word))
4356 #if defined (READLINE)
4357 /* Called after each time readline is called. This insures that whatever
4358 the new prompt string is gets propagated to readline's local prompt
4361 reset_readline_prompt ()
4365 if (prompt_string_pointer)
4367 temp_prompt = (*prompt_string_pointer)
4368 ? decode_prompt_string (*prompt_string_pointer)
4371 if (temp_prompt == 0)
4373 temp_prompt = xmalloc (1);
4374 temp_prompt[0] = '\0';
4377 FREE (current_readline_prompt);
4378 current_readline_prompt = temp_prompt;
4381 #endif /* READLINE */
4384 #if defined (HISTORY)
4385 /* A list of tokens which can be followed by newlines, but not by
4386 semi-colons. When concatenating multiple lines of history, the
4387 newline separator for such tokens is replaced with a space. */
4388 static int no_semi_successors[] = {
4389 '\n', '{', '(', ')', ';', '&', '|',
4390 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
4394 /* If we are not within a delimited expression, try to be smart
4395 about which separators can be semi-colons and which must be
4396 newlines. Returns the string that should be added into the
4399 history_delimiting_chars ()
4403 if (dstack.delimiter_depth != 0)
4406 /* First, handle some special cases. */
4408 /* If we just read `()', assume it's a function definition, and don't
4409 add a semicolon. If the token before the `)' was not `(', and we're
4410 not in the midst of parsing a case statement, assume it's a
4411 parenthesized command and add the semicolon. */
4413 if (token_before_that == ')')
4415 if (two_tokens_ago == '(') /*)*/ /* function def */
4417 /* This does not work for subshells inside case statement
4418 command lists. It's a suboptimal solution. */
4419 else if (parser_state & PST_CASESTMT) /* case statement pattern */
4422 return "; "; /* (...) subshell */
4424 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
4425 return " "; /* function def using `function name' without `()' */
4427 for (i = 0; no_semi_successors[i]; i++)
4429 if (token_before_that == no_semi_successors[i])
4435 #endif /* HISTORY */
4437 /* Issue a prompt, or prepare to issue a prompt when the next character
4444 if (!interactive) /* XXX */
4447 ps1_prompt = get_string_value ("PS1");
4448 ps2_prompt = get_string_value ("PS2");
4450 if (!prompt_string_pointer)
4451 prompt_string_pointer = &ps1_prompt;
4453 temp_prompt = *prompt_string_pointer
4454 ? decode_prompt_string (*prompt_string_pointer)
4457 if (temp_prompt == 0)
4459 temp_prompt = xmalloc (1);
4460 temp_prompt[0] = '\0';
4463 current_prompt_string = *prompt_string_pointer;
4464 prompt_string_pointer = &ps2_prompt;
4466 #if defined (READLINE)
4467 if (!no_line_editing)
4469 FREE (current_readline_prompt);
4470 current_readline_prompt = temp_prompt;
4473 #endif /* READLINE */
4475 FREE (current_decoded_prompt);
4476 current_decoded_prompt = temp_prompt;
4483 fprintf (stderr, "%s", current_decoded_prompt);
4487 /* Return a string which will be printed as a prompt. The string
4488 may contain special characters which are decoded as follows:
4491 \e escape (ascii 033)
4492 \d the date in Day Mon Date format
4493 \h the hostname up to the first `.'
4496 \s the name of the shell
4497 \t the time in 24-hour hh:mm:ss format
4498 \T the time in 12-hour hh:mm:ss format
4499 \@ the time in 12-hour am/pm format
4500 \v the version of bash (e.g., 2.00)
4501 \V the release of bash, version + patchlevel (e.g., 2.00.0)
4502 \w the current working directory
4503 \W the last element of $PWD
4505 \# the command number of this command
4506 \! the history number of this command
4507 \$ a $ or a # if you are root
4508 \nnn character code nnn in octal
4510 \[ begin a sequence of non-printing chars
4511 \] end a sequence of non-printing chars
4513 #define PROMPT_GROWTH 48
4515 decode_prompt_string (string)
4520 struct dstack save_dstack;
4521 #if defined (PROMPT_STRING_DECODE)
4522 int result_size, result_index;
4524 char *temp, octal_string[4];
4527 result = xmalloc (result_size = PROMPT_GROWTH);
4528 result[result_index = 0] = 0;
4529 temp = (char *)NULL;
4531 while (c = *string++)
4533 if (posixly_correct && c == '!')
4537 temp = savestring ("!");
4542 #if !defined (HISTORY)
4543 temp = savestring ("1");
4545 temp = itos (history_number ());
4546 #endif /* HISTORY */
4547 string--; /* add_string increments string again. */
4565 strncpy (octal_string, string, 3);
4566 octal_string[3] = '\0';
4568 n = read_octal (octal_string);
4571 if (n == CTLESC || n == CTLNUL)
4597 /* Make the current time/date into a string. */
4598 the_time = time (0);
4599 temp = ctime (&the_time);
4601 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
4602 temp[(c != 'd') ? 8 : 10] = '\0';
4604 /* quick and dirty conversion to 12-hour time */
4605 if (c == 'T' || c == '@')
4609 temp[5] = 'a'; /* am/pm format */
4620 temp[0] = (n / 10) + '0';
4621 temp[1] = (n % 10) + '0';
4623 if (n >= 0 && temp[5] == 'a')
4636 temp[0] = no_line_editing ? '\n' : '\r';
4637 temp[1] = no_line_editing ? '\0' : '\n';
4642 temp = base_pathname (shell_name);
4643 temp = savestring (temp);
4650 strcpy (temp, dist_version);
4652 sprintf (temp, "%s.%d", dist_version, patch_level);
4658 /* Use the value of PWD because it is much more efficient. */
4659 char t_string[PATH_MAX];
4662 temp = get_string_value ("PWD");
4666 if (getcwd (t_string, sizeof(t_string)) == 0)
4672 tlen = strlen (t_string);
4676 tlen = sizeof (t_string) - 1;
4677 strncpy (t_string, temp, tlen);
4679 t_string[tlen] = '\0';
4683 t = strrchr (t_string, '/');
4684 if (t && t != t_string)
4685 strcpy (t_string, t + 1);
4688 /* polite_directory_format is guaranteed to return a string
4689 no longer than PATH_MAX - 1 characters. */
4690 strcpy (t_string, polite_directory_format (t_string));
4692 /* If we're going to be expanding the prompt string later,
4693 quote the directory name. */
4694 if (promptvars || posixly_correct)
4695 temp = backslash_quote (t_string);
4697 temp = savestring (t_string);
4703 temp = savestring (current_user.user_name);
4708 temp = savestring (current_host_name);
4709 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4714 temp = itos (current_command_number);
4718 #if !defined (HISTORY)
4719 temp = savestring ("1");
4721 temp = itos (history_number ());
4722 #endif /* HISTORY */
4726 t = temp = xmalloc (3);
4727 if ((promptvars || posixly_correct) && (current_user.euid != 0))
4729 *t++ = current_user.euid == 0 ? '#' : '$';
4733 #if defined (READLINE)
4738 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4741 #endif /* READLINE */
4752 temp[0] = (c == 'a') ? '\07' : '\033';
4766 sub_append_string (temp, result, &result_index, &result_size);
4767 temp = (char *)NULL; /* Freed in sub_append_string (). */
4768 result[result_index] = '\0';
4774 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
4775 result[result_index++] = c;
4776 result[result_index] = '\0';
4779 #else /* !PROMPT_STRING_DECODE */
4780 result = savestring (string);
4781 #endif /* !PROMPT_STRING_DECODE */
4783 /* Save the delimiter stack and point `dstack' to temp space so any
4784 command substitutions in the prompt string won't result in screwing
4785 up the parser's quoting state. */
4786 save_dstack = dstack;
4787 dstack = temp_dstack;
4788 dstack.delimiter_depth = 0;
4790 /* Perform variable and parameter expansion and command substitution on
4791 the prompt string. */
4792 if (promptvars || posixly_correct)
4794 list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
4796 result = string_list (list);
4797 dispose_words (list);
4801 t = dequote_string (result);
4806 dstack = save_dstack;
4811 /* Report a syntax error, and restart the parser. Call here for fatal
4816 report_syntax_error ((char *)NULL);
4821 /* Report a syntax error with line numbers, etc.
4822 Call here for recoverable errors. If you have a message to print,
4823 then place it in MESSAGE, otherwise pass NULL and this will figure
4824 out an appropriate message for you. */
4826 report_syntax_error (message)
4835 parser_error (line_number, "%s", message);
4836 if (interactive && EOF_Reached)
4838 last_command_exit_value = EX_USAGE;
4842 /* If the line of input we're reading is not null, try to find the
4843 objectionable token. */
4844 if (shell_input_line && *shell_input_line)
4846 t = shell_input_line;
4847 i = shell_input_line_index;
4850 if (i && t[i] == '\0')
4853 while (i && (whitespace (t[i]) || t[i] == '\n'))
4859 while (i && (member (t[i], " \n\t;|&") == 0))
4862 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4865 /* Print the offending token. */
4866 if (token_end || (i == 0 && token_end == 0))
4870 msg = xmalloc (1 + (token_end - i));
4871 strncpy (msg, t + i, token_end - i);
4872 msg[token_end - i] = '\0';
4874 else /* one-character token */
4881 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
4887 /* If not interactive, print the line containing the error. */
4888 if (interactive == 0)
4890 msg = savestring (shell_input_line);
4891 token_end = strlen (msg);
4892 while (token_end && msg[token_end - 1] == '\n')
4893 msg[--token_end] = '\0';
4895 parser_error (line_number, "`%s'", msg);
4901 msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
4902 parser_error (line_number, "%s", msg);
4903 /* When the shell is interactive, this file uses EOF_Reached
4904 only for error reporting. Other mechanisms are used to
4905 decide whether or not to exit. */
4906 if (interactive && EOF_Reached)
4909 last_command_exit_value = EX_USAGE;
4912 /* ??? Needed function. ??? We have to be able to discard the constructs
4913 created during parsing. In the case of error, we want to return
4914 allocated objects to the memory pool. In the case of no error, we want
4915 to throw away the information about where the allocated objects live.
4916 (dispose_command () will actually free the command. */
4918 discard_parser_constructs (error_p)
4923 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4925 /* A flag denoting whether or not ignoreeof is set. */
4928 /* The number of times that we have encountered an EOF character without
4929 another character intervening. When this gets above the limit, the
4930 shell terminates. */
4931 int eof_encountered = 0;
4933 /* The limit for eof_encountered. */
4934 int eof_encountered_limit = 10;
4936 /* If we have EOF as the only input unit, this user wants to leave
4937 the shell. If the shell is not interactive, then just leave.
4938 Otherwise, if ignoreeof is set, and we haven't done this the
4939 required number of times in a row, print a message. */
4941 handle_eof_input_unit ()
4945 /* shell.c may use this to decide whether or not to write out the
4946 history, among other things. We use it only for error reporting
4951 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4954 if (eof_encountered < eof_encountered_limit)
4956 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
4957 login_shell ? "logout" : "exit");
4959 /* Reset the prompt string to be $PS1. */
4960 prompt_string_pointer = (char **)NULL;
4962 last_read_token = current_token = '\n';
4967 /* In this case EOF should exit the shell. Do it now. */
4969 exit_builtin ((WORD_LIST *)NULL);
4973 /* We don't write history files, etc., for non-interactive shells. */