3 yyrcsid[] = "$FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28 2000/01/17 02:04:06 bde Exp $";
11 #define yyclearin (yychar=(YYEMPTY))
12 #define yyerrok (yyerrflag=0)
13 #define YYRECOVERING() (yyerrflag!=0)
14 static int yygrowstack();
16 #line 22 "/usr/homes/chet/src/bash/src/parse.y"
19 #include "bashtypes.h"
24 #if defined (HAVE_UNISTD_H)
28 #if defined (HAVE_LOCALE_H)
41 #include "mailcheck.h"
42 #include "builtins/common.h"
43 #include "builtins/builtext.h"
45 #if defined (READLINE)
46 # include "bashline.h"
47 # include <readline/readline.h>
51 # include "bashhist.h"
52 # include <readline/history.h>
55 #if defined (JOB_CONTROL)
57 #endif /* JOB_CONTROL */
63 #if defined (PROMPT_STRING_DECODE)
65 # include <sys/param.h>
69 #endif /* PROMPT_STRING_DECODE */
71 #define RE_READ_TOKEN -99
72 #define NO_EXPANSION -100
76 #if defined (EXTENDED_GLOB)
77 extern int extended_glob;
80 extern int eof_encountered;
81 extern int no_line_editing, running_under_emacs;
82 extern int current_command_number;
83 extern int interactive, interactive_shell, login_shell;
84 extern int sourcelevel;
85 extern int posixly_correct;
86 extern int last_command_exit_value;
87 extern int interrupt_immediately;
88 extern char *shell_name, *current_host_name;
89 extern char *dist_version;
90 extern int patch_level;
91 extern int dump_translatable_strings, dump_po_strings;
92 extern Function *last_shell_builtin, *this_shell_builtin;
93 #if defined (BUFFERED_INPUT)
94 extern int bash_input_fd_changed;
98 /* **************************************************************** */
100 /* "Forward" declarations */
102 /* **************************************************************** */
104 static char *ansiexpand ();
105 static char *localeexpand ();
106 static int reserved_word_acceptable ();
107 static int read_token ();
109 static int parse_arith_cmd ();
110 #if defined (COND_COMMAND)
111 static COMMAND *parse_cond_command ();
113 static int read_token_word ();
114 static void discard_parser_constructs ();
116 static void report_syntax_error ();
117 static void handle_eof_input_unit ();
118 static void prompt_again ();
120 static void reset_readline_prompt ();
122 static void print_prompt ();
124 #if defined (HISTORY)
125 char *history_delimiting_chars ();
128 extern int yyerror ();
130 /* Default prompt strings */
131 char *primary_prompt = PPROMPT;
132 char *secondary_prompt = SPROMPT;
134 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
135 char *ps1_prompt, *ps2_prompt;
137 /* Handle on the current prompt string. Indirectly points through
138 ps1_ or ps2_prompt. */
139 char **prompt_string_pointer = (char **)NULL;
140 char *current_prompt_string;
142 /* Non-zero means we expand aliases in commands. */
143 int expand_aliases = 0;
145 /* If non-zero, the decoded prompt string undergoes parameter and
146 variable substitution, command substitution, arithmetic substitution,
147 string expansion, process substitution, and quote removal in
148 decode_prompt_string. */
151 /* The decoded prompt string. Used if READLINE is not defined or if
152 editing is turned off. Analogous to current_readline_prompt. */
153 static char *current_decoded_prompt;
155 /* The number of lines read from input while creating the current command. */
156 int current_command_line_count;
158 /* Variables to manage the task of reading here documents, because we need to
159 defer the reading until after a complete command has been collected. */
160 static REDIRECT *redir_stack[10];
163 /* Where shell input comes from. History expansion is performed on each
164 line when the shell is interactive. */
165 static char *shell_input_line = (char *)NULL;
166 static int shell_input_line_index;
167 static int shell_input_line_size; /* Amount allocated for shell_input_line. */
168 static int shell_input_line_len; /* strlen (shell_input_line) */
170 /* Either zero or EOF. */
171 static int shell_input_line_terminator;
173 /* The line number in a script on which a function definition starts. */
174 static int function_dstart;
176 /* The line number in a script on which a function body starts. */
177 static int function_bstart;
179 /* The line number in a script at which an arithmetic for command starts. */
180 static int arith_for_lineno;
182 static REDIRECTEE redir;
183 #line 190 "/usr/homes/chet/src/bash/src/parse.y"
185 WORD_DESC *word; /* the word that we read. */
186 int number; /* the number that we read. */
187 WORD_LIST *word_list;
191 PATTERN_LIST *pattern;
194 #define YYERRCODE 256
209 #define COND_START 271
211 #define COND_ERROR 273
217 #define ASSIGNMENT_WORD 279
219 #define ARITH_CMD 281
220 #define ARITH_FOR_EXPRS 282
224 #define GREATER_GREATER 286
225 #define LESS_LESS 287
227 #define GREATER_AND 289
228 #define SEMI_SEMI 290
229 #define LESS_LESS_MINUS 291
230 #define AND_GREATER 292
231 #define LESS_GREATER 293
232 #define GREATER_BAR 294
234 const short yylhs[] = { -1,
235 0, 0, 0, 0, 27, 27, 24, 24, 24, 24,
236 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
237 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
238 24, 24, 24, 26, 26, 26, 25, 25, 10, 10,
239 1, 1, 1, 1, 11, 11, 11, 11, 11, 11,
240 11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
241 12, 18, 18, 18, 18, 13, 13, 13, 13, 13,
242 13, 14, 14, 14, 19, 19, 19, 20, 20, 23,
243 21, 21, 21, 15, 16, 17, 22, 22, 22, 31,
244 31, 29, 29, 29, 29, 30, 30, 28, 28, 4,
245 7, 7, 5, 5, 5, 6, 6, 6, 6, 6,
246 6, 34, 34, 34, 33, 33, 8, 8, 8, 9,
247 9, 9, 9, 9, 3, 3, 3, 3, 3, 2,
250 const short yylen[] = { 2,
251 2, 1, 2, 1, 1, 2, 2, 2, 3, 3,
252 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
253 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
254 2, 2, 3, 1, 1, 1, 1, 2, 1, 2,
255 1, 1, 2, 1, 1, 1, 5, 5, 1, 1,
256 1, 1, 1, 1, 1, 6, 6, 7, 7, 10,
257 10, 7, 7, 5, 5, 6, 6, 7, 7, 10,
258 10, 6, 7, 6, 5, 6, 4, 1, 2, 3,
259 5, 7, 6, 3, 1, 3, 4, 6, 5, 1,
260 2, 4, 4, 5, 5, 2, 3, 1, 3, 2,
261 1, 2, 3, 3, 3, 4, 4, 4, 4, 4,
262 1, 1, 1, 1, 0, 2, 1, 2, 2, 4,
263 4, 3, 3, 1, 1, 2, 2, 3, 3, 4,
266 const short yydefred[] = { 0,
267 0, 115, 0, 0, 0, 115, 115, 0, 0, 0,
268 0, 0, 35, 0, 85, 0, 0, 0, 0, 0,
269 0, 0, 0, 2, 4, 0, 0, 115, 115, 0,
270 131, 0, 124, 0, 0, 0, 0, 45, 49, 46,
271 52, 53, 54, 55, 44, 50, 51, 36, 39, 0,
272 3, 101, 0, 0, 115, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 133, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 11, 13, 19, 15, 27,
275 21, 17, 25, 23, 29, 31, 32, 7, 8, 0,
276 0, 115, 1, 115, 115, 0, 0, 34, 40, 37,
277 0, 0, 0, 115, 116, 111, 100, 0, 0, 115,
278 0, 115, 113, 112, 114, 115, 115, 115, 0, 115,
279 115, 0, 0, 86, 0, 115, 12, 14, 20, 16,
280 28, 22, 18, 26, 24, 30, 33, 9, 10, 84,
281 80, 0, 0, 0, 0, 0, 38, 0, 0, 115,
282 115, 115, 115, 115, 115, 0, 115, 0, 115, 0,
283 0, 0, 0, 115, 0, 115, 0, 0, 115, 0,
284 77, 0, 0, 120, 121, 0, 0, 115, 115, 81,
285 0, 0, 0, 0, 0, 0, 0, 115, 0, 0,
286 115, 115, 0, 5, 0, 0, 64, 65, 115, 115,
287 115, 115, 0, 0, 0, 0, 47, 48, 0, 0,
288 75, 0, 0, 83, 106, 107, 0, 0, 0, 96,
289 0, 0, 74, 72, 98, 0, 0, 0, 0, 56,
290 6, 115, 57, 0, 0, 0, 0, 66, 0, 115,
291 67, 76, 82, 115, 115, 115, 115, 97, 73, 0,
292 0, 115, 58, 59, 0, 62, 63, 68, 69, 0,
293 0, 0, 0, 0, 115, 99, 92, 0, 115, 115,
294 115, 115, 115, 89, 94, 0, 0, 0, 0, 0,
297 const short yydgoto[] = { 30,
298 31, 32, 106, 52, 107, 108, 53, 34, 145, 36,
299 37, 38, 39, 40, 41, 42, 43, 44, 45, 171,
300 46, 181, 47, 48, 101, 49, 195, 227, 187, 188,
303 const short yysindex[] = { -10,
304 2, 0, -258, -255, -246, 0, 0, -237, -249, 846,
305 -226, 15, 0, 123, 0, -211, -203, -44, -43, -199,
306 -198, -194, -193, 0, 0, -192, -191, 0, 0, 0,
307 0, -41, 0, 78, 23, 956, 975, 0, 0, 0,
308 0, 0, 0, 0, 0, 0, 0, 0, 0, 721,
309 0, 0, -169, 71, 0, 35, -6, 39, -177, -172,
310 61, -168, -41, 933, 0, 62, -176, -173, -30, -27,
311 -166, -163, -162, -160, -159, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0, 0, -17,
313 69, 0, 0, 0, 0, 813, 813, 0, 0, 0,
314 975, 933, -41, 0, 0, 0, 0, 19, -7, 0,
315 66, 0, 0, 0, 0, 0, 0, 0, 99, 0,
316 0, 79, 305, 0, -41, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 104, 71, 71, -247, -247, 0, -41, -195, 0,
319 0, 0, 0, 0, 0, 4, 0, -156, 0, -145,
320 1, 7, 12, 0, -156, 0, -144, -140, 0, 975,
321 0, 305, -41, 0, 0, 813, 813, 0, 0, 0,
322 -138, 71, 71, 71, 71, 71, -158, 0, -129, -4,
323 0, 0, -132, 0, -5, 16, 0, 0, 0, 0,
324 0, 0, -126, 71, -5, 20, 0, 0, 305, 975,
325 0, -115, -111, 0, 0, 0, -240, -240, -240, 0,
326 -142, 32, 0, 0, 0, -128, -34, -120, 26, 0,
327 0, 0, 0, -114, 36, -107, 38, 0, 19, 0,
328 0, 0, 0, 0, 0, 0, 0, 0, 0, -25,
329 -113, 0, 0, 0, 29, 0, 0, 0, 0, 37,
330 -201, 71, 71, 71, 0, 0, 0, 71, 0, 0,
331 0, 0, 0, 0, 0, 71, -100, 45, -98, 48,
334 const short yyrindex[] = { 0,
335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336 888, 33, 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
338 0, 450, 0, 0, 164, 118, 162, 0, 0, 0,
339 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340 0, 0, 0, 0, 0, 126, 0, 126, 0, 0,
341 216, 0, 462, 0, 0, 0, 0, 0, 0, 0,
342 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
343 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344 0, 0, 0, 0, 0, 165, 166, 0, 0, 0,
345 174, 0, 495, 0, 0, 0, 0, 436, 0, 0,
346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
347 0, 0, 0, 0, 507, 0, 0, 0, 0, 0,
348 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
349 0, 0, 0, 0, 11, 18, 0, 540, 0, 0,
350 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
351 0, 0, 0, 0, 0, 0, 0, 0, 0, 403,
352 0, 0, 553, 0, 0, 0, 0, 0, 0, 0,
353 0, 0, 0, 573, 662, 765, -85, 0, 0, 0,
354 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
355 0, 0, 0, 0, 0, 0, 0, 0, 0, 416,
356 0, 0, 0, 0, 0, 0, 587, 599, 611, 0,
357 -84, 0, 0, 0, 0, 0, 0, 0, 0, 0,
358 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
359 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
360 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
361 -81, 0, 0, 0, 0, 0, 0, -250, 0, 0,
362 0, 0, 0, 0, 0, -244, 0, 0, 0, 0,
365 const short yygindex[] = { 0,
366 0, -2, 10, -133, 0, 340, 798, 0, 24, 0,
367 -112, 0, 0, 0, 0, 0, 0, 0, 0, -146,
368 0, -80, 0, -28, 21, 152, 25, -33, 8, 0,
371 #define YYTABLESIZE 1468
372 const short yytable[] = { 24,
373 80, 83, 105, 114, 114, 105, 252, 63, 100, 33,
374 170, 51, 93, 105, 131, 265, 105, 134, 95, 55,
375 122, 105, 56, 35, 232, 211, 57, 123, 154, 29,
376 203, 58, 206, 62, 240, 226, 94, 95, 105, 93,
377 61, 105, 34, 150, 151, 95, 105, 103, 122, 27,
378 65, 26, 113, 113, 66, 123, 152, 273, 179, 170,
379 96, 125, 242, 178, 179, 180, 76, 236, 237, 122,
380 34, 226, 147, 34, 77, 105, 123, 153, 84, 85,
381 105, 97, 92, 86, 87, 88, 89, 93, 104, 251,
382 120, 34, 34, 110, 34, 121, 170, 118, 251, 148,
383 122, 127, 126, 124, 128, 33, 33, 140, 105, 141,
384 29, 135, 28, 105, 136, 137, 116, 138, 139, 169,
385 146, 194, 214, 197, 207, 198, 192, 41, 208, 200,
386 27, 220, 26, 223, 202, 115, 230, 279, 280, 173,
387 233, 100, 238, 29, 241, 243, 244, 248, 253, 225,
388 254, 270, 33, 33, 256, 41, 34, 34, 41, 272,
389 257, 258, 259, 27, 266, 26, 174, 175, 282, 283,
390 284, 42, 285, 117, 118, 119, 41, 90, 91, 87,
391 274, 147, 75, 43, 74, 33, 33, 99, 159, 205,
392 210, 64, 250, 28, 0, 221, 0, 0, 0, 42,
393 146, 0, 42, 0, 0, 0, 0, 0, 0, 0,
394 0, 43, 0, 0, 43, 0, 0, 0, 0, 0,
395 42, 166, 0, 0, 0, 115, 28, 0, 0, 0,
396 0, 0, 43, 78, 81, 79, 82, 0, 0, 0,
397 0, 41, 41, 0, 0, 1, 2, 129, 115, 130,
398 132, 3, 133, 4, 5, 6, 7, 0, 224, 8,
399 9, 112, 0, 0, 10, 11, 155, 12, 13, 14,
400 15, 191, 231, 225, 199, 16, 17, 18, 19, 201,
401 20, 21, 22, 23, 25, 42, 42, 0, 115, 115,
402 34, 34, 34, 34, 249, 34, 269, 43, 43, 0,
403 34, 34, 150, 151, 271, 0, 94, 95, 0, 225,
404 34, 34, 34, 0, 105, 0, 34, 34, 34, 34,
405 34, 34, 34, 34, 34, 34, 34, 2, 0, 0,
406 0, 0, 3, 157, 4, 5, 6, 7, 115, 158,
407 8, 9, 0, 0, 29, 10, 11, 0, 12, 13,
408 14, 15, 0, 0, 0, 0, 16, 17, 18, 19,
409 2, 20, 21, 22, 23, 3, 164, 4, 5, 6,
410 7, 0, 165, 8, 9, 41, 41, 41, 41, 0,
411 41, 12, 13, 14, 15, 41, 41, 0, 0, 16,
412 17, 18, 19, 115, 20, 21, 22, 23, 0, 115,
413 0, 41, 41, 0, 0, 0, 0, 41, 67, 68,
414 69, 70, 78, 71, 0, 72, 73, 0, 0, 42,
415 42, 42, 42, 0, 42, 79, 0, 28, 0, 42,
416 42, 43, 43, 43, 43, 0, 43, 0, 0, 0,
417 78, 43, 43, 78, 0, 42, 42, 0, 0, 0,
418 0, 42, 0, 79, 0, 0, 79, 43, 43, 125,
419 0, 78, 0, 43, 0, 0, 0, 0, 0, 0,
420 0, 126, 115, 0, 79, 0, 102, 115, 0, 115,
421 115, 115, 115, 0, 0, 0, 115, 125, 0, 0,
422 125, 0, 0, 0, 0, 0, 115, 0, 0, 126,
423 0, 0, 126, 0, 127, 0, 0, 0, 125, 0,
424 0, 0, 0, 0, 0, 0, 129, 0, 0, 0,
425 126, 215, 216, 217, 218, 219, 78, 78, 0, 0,
426 0, 0, 127, 0, 0, 127, 0, 0, 0, 79,
427 79, 0, 0, 239, 129, 0, 0, 129, 0, 128,
428 0, 0, 0, 127, 0, 0, 0, 0, 0, 0,
429 102, 2, 130, 0, 0, 129, 3, 0, 4, 5,
430 6, 7, 0, 0, 125, 9, 0, 128, 0, 0,
431 128, 0, 0, 0, 0, 15, 126, 0, 0, 0,
432 130, 0, 0, 130, 0, 0, 108, 0, 128, 0,
433 0, 217, 218, 219, 0, 0, 0, 0, 109, 0,
434 0, 130, 0, 104, 0, 0, 0, 0, 0, 127,
435 110, 0, 0, 0, 108, 0, 0, 108, 0, 0,
436 0, 129, 0, 0, 0, 0, 109, 0, 0, 109,
437 0, 0, 0, 0, 0, 108, 0, 0, 110, 0,
438 0, 110, 0, 0, 0, 0, 0, 109, 0, 0,
439 78, 78, 78, 78, 128, 78, 0, 0, 0, 110,
440 78, 78, 0, 79, 79, 79, 79, 130, 79, 0,
441 0, 0, 0, 79, 79, 0, 78, 78, 0, 0,
442 0, 0, 78, 102, 102, 102, 102, 104, 102, 79,
443 79, 0, 105, 102, 102, 79, 0, 125, 125, 125,
444 125, 108, 125, 0, 0, 0, 0, 125, 125, 126,
445 126, 126, 126, 109, 126, 102, 0, 0, 0, 126,
446 126, 0, 0, 125, 125, 110, 0, 0, 0, 125,
447 0, 0, 0, 0, 0, 126, 126, 0, 0, 0,
448 0, 126, 127, 127, 127, 127, 0, 127, 0, 0,
449 29, 0, 127, 127, 129, 129, 129, 129, 0, 129,
450 0, 0, 0, 0, 129, 129, 0, 0, 127, 127,
451 27, 0, 26, 0, 127, 0, 105, 0, 0, 0,
452 129, 129, 0, 0, 0, 0, 129, 128, 128, 128,
453 128, 0, 128, 59, 60, 103, 0, 128, 128, 0,
454 130, 130, 130, 130, 0, 130, 0, 0, 0, 0,
455 130, 130, 0, 128, 128, 90, 91, 0, 0, 128,
456 104, 104, 104, 104, 0, 104, 130, 130, 0, 0,
457 104, 104, 130, 28, 108, 108, 108, 108, 0, 108,
458 0, 0, 29, 0, 108, 108, 109, 109, 109, 109,
459 0, 109, 104, 0, 0, 0, 109, 109, 110, 110,
460 110, 110, 27, 110, 26, 0, 108, 0, 110, 110,
461 0, 0, 0, 0, 0, 29, 0, 0, 109, 103,
462 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
463 110, 149, 0, 0, 0, 27, 0, 26, 0, 160,
464 0, 0, 0, 161, 0, 0, 0, 167, 168, 105,
465 105, 105, 105, 0, 105, 0, 0, 132, 0, 105,
466 105, 0, 0, 0, 0, 28, 0, 0, 0, 0,
467 0, 0, 0, 0, 0, 0, 0, 132, 0, 132,
468 0, 105, 0, 0, 193, 0, 196, 0, 0, 0,
469 0, 0, 0, 0, 0, 0, 0, 0, 28, 0,
470 0, 0, 29, 0, 0, 212, 213, 2, 0, 0,
471 0, 0, 3, 0, 4, 5, 6, 7, 228, 229,
472 8, 9, 27, 0, 26, 102, 234, 235, 12, 13,
473 14, 15, 0, 0, 0, 0, 16, 17, 18, 19,
474 132, 20, 21, 22, 23, 27, 0, 26, 0, 0,
475 0, 0, 103, 103, 103, 103, 0, 103, 0, 0,
476 0, 0, 103, 103, 27, 0, 26, 0, 0, 0,
477 0, 261, 0, 0, 0, 0, 0, 0, 0, 267,
478 0, 0, 0, 0, 103, 28, 0, 0, 0, 0,
479 0, 0, 275, 0, 0, 0, 277, 278, 0, 2,
480 281, 0, 0, 0, 3, 0, 4, 5, 6, 7,
481 0, 0, 8, 9, 0, 0, 0, 10, 11, 0,
482 12, 13, 14, 15, 0, 0, 0, 0, 16, 17,
483 18, 19, 2, 20, 21, 22, 23, 3, 0, 4,
484 5, 6, 7, 0, 0, 8, 9, 0, 0, 0,
485 0, 11, 0, 12, 13, 14, 15, 0, 0, 0,
486 0, 16, 17, 18, 19, 0, 20, 21, 22, 23,
487 0, 0, 0, 0, 132, 0, 0, 0, 0, 132,
488 0, 132, 132, 132, 132, 0, 0, 132, 132, 0,
489 0, 0, 132, 0, 0, 132, 132, 132, 132, 0,
490 0, 0, 0, 132, 132, 132, 132, 0, 132, 132,
491 132, 132, 0, 0, 0, 0, 0, 0, 0, 2,
492 0, 0, 0, 0, 3, 0, 4, 5, 6, 7,
493 0, 0, 8, 9, 0, 0, 0, 0, 0, 0,
494 12, 13, 14, 15, 0, 0, 0, 0, 16, 17,
495 18, 19, 0, 20, 21, 22, 23, 0, 0, 0,
496 0, 0, 0, 98, 13, 14, 0, 0, 0, 0,
497 0, 16, 17, 18, 19, 0, 20, 21, 22, 23,
498 109, 111, 0, 119, 14, 0, 123, 0, 0, 0,
499 16, 17, 18, 19, 0, 20, 21, 22, 23, 0,
500 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
501 0, 0, 0, 0, 0, 0, 0, 142, 0, 143,
502 144, 0, 0, 0, 0, 0, 0, 0, 0, 0,
503 0, 0, 0, 0, 0, 156, 0, 0, 0, 0,
504 0, 0, 162, 163, 0, 0, 0, 0, 0, 0,
505 0, 172, 0, 0, 0, 0, 0, 0, 0, 0,
506 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
507 0, 0, 0, 0, 0, 182, 183, 184, 185, 186,
508 190, 0, 0, 0, 0, 0, 0, 0, 0, 204,
509 0, 204, 0, 0, 209, 0, 0, 0, 0, 0,
510 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
511 0, 0, 0, 222, 0, 0, 0, 0, 0, 0,
512 0, 0, 0, 0, 0, 0, 204, 204, 0, 0,
513 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
514 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
515 0, 0, 0, 0, 0, 0, 0, 255, 0, 0,
516 0, 0, 0, 0, 0, 260, 0, 0, 0, 0,
517 262, 263, 264, 0, 0, 0, 0, 268, 0, 0,
518 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
519 276, 0, 0, 0, 0, 0, 204, 204,
521 const short yycheck[] = { 10,
522 45, 45, 10, 10, 10, 10, 41, 10, 37, 0,
523 123, 10, 263, 10, 45, 41, 10, 45, 263, 278,
524 10, 10, 278, 0, 195, 172, 282, 10, 10, 40,
525 164, 278, 166, 283, 205, 40, 284, 285, 10, 290,
526 278, 10, 10, 284, 285, 290, 10, 50, 38, 60,
527 277, 62, 59, 59, 40, 38, 38, 259, 260, 172,
528 38, 64, 209, 259, 260, 261, 278, 201, 202, 59,
529 38, 40, 101, 41, 278, 10, 59, 59, 278, 278,
530 10, 59, 124, 278, 278, 278, 278, 10, 258, 124,
531 268, 59, 60, 59, 62, 268, 209, 59, 124, 102,
532 40, 278, 41, 272, 278, 96, 97, 125, 10, 41,
533 40, 278, 123, 10, 278, 278, 123, 278, 278, 41,
534 97, 278, 261, 269, 269, 125, 123, 10, 269, 123,
535 60, 290, 62, 263, 123, 10, 269, 271, 272, 142,
536 125, 170, 269, 40, 125, 261, 258, 290, 269, 278,
537 125, 123, 143, 144, 269, 38, 124, 125, 41, 123,
538 125, 269, 125, 60, 278, 62, 143, 144, 269, 125,
539 269, 10, 125, 10, 10, 10, 59, 263, 263, 261,
540 261, 210, 60, 10, 62, 176, 177, 36, 123, 165,
541 170, 10, 226, 123, -1, 188, -1, -1, -1, 38,
542 177, -1, 41, -1, -1, -1, -1, -1, -1, -1,
543 -1, 38, -1, -1, 41, -1, -1, -1, -1, -1,
544 59, 123, -1, -1, -1, 10, 123, -1, -1, -1,
545 -1, -1, 59, 278, 278, 280, 280, -1, -1, -1,
546 -1, 124, 125, -1, -1, 256, 257, 278, 123, 280,
547 278, 262, 280, 264, 265, 266, 267, -1, 263, 270,
548 271, 268, -1, -1, 275, 276, 274, 278, 279, 280,
549 281, 268, 278, 278, 268, 286, 287, 288, 289, 268,
550 291, 292, 293, 294, 295, 124, 125, -1, 295, 295,
551 258, 259, 260, 261, 263, 263, 268, 124, 125, -1,
552 268, 269, 284, 285, 268, -1, 284, 285, -1, 278,
553 278, 279, 280, -1, 10, -1, 284, 285, 286, 287,
554 288, 289, 290, 291, 292, 293, 294, 257, -1, -1,
555 -1, -1, 262, 268, 264, 265, 266, 267, 123, 274,
556 270, 271, -1, -1, 40, 275, 276, -1, 278, 279,
557 280, 281, -1, -1, -1, -1, 286, 287, 288, 289,
558 257, 291, 292, 293, 294, 262, 268, 264, 265, 266,
559 267, -1, 274, 270, 271, 258, 259, 260, 261, -1,
560 263, 278, 279, 280, 281, 268, 269, -1, -1, 286,
561 287, 288, 289, 268, 291, 292, 293, 294, -1, 274,
562 -1, 284, 285, -1, -1, -1, -1, 290, 286, 287,
563 288, 289, 10, 291, -1, 293, 294, -1, -1, 258,
564 259, 260, 261, -1, 263, 10, -1, 123, -1, 268,
565 269, 258, 259, 260, 261, -1, 263, -1, -1, -1,
566 38, 268, 269, 41, -1, 284, 285, -1, -1, -1,
567 -1, 290, -1, 38, -1, -1, 41, 284, 285, 10,
568 -1, 59, -1, 290, -1, -1, -1, -1, -1, -1,
569 -1, 10, 257, -1, 59, -1, 41, 262, -1, 264,
570 265, 266, 267, -1, -1, -1, 271, 38, -1, -1,
571 41, -1, -1, -1, -1, -1, 281, -1, -1, 38,
572 -1, -1, 41, -1, 10, -1, -1, -1, 59, -1,
573 -1, -1, -1, -1, -1, -1, 10, -1, -1, -1,
574 59, 182, 183, 184, 185, 186, 124, 125, -1, -1,
575 -1, -1, 38, -1, -1, 41, -1, -1, -1, 124,
576 125, -1, -1, 204, 38, -1, -1, 41, -1, 10,
577 -1, -1, -1, 59, -1, -1, -1, -1, -1, -1,
578 125, 257, 10, -1, -1, 59, 262, -1, 264, 265,
579 266, 267, -1, -1, 125, 271, -1, 38, -1, -1,
580 41, -1, -1, -1, -1, 281, 125, -1, -1, -1,
581 38, -1, -1, 41, -1, -1, 10, -1, 59, -1,
582 -1, 262, 263, 264, -1, -1, -1, -1, 10, -1,
583 -1, 59, -1, 41, -1, -1, -1, -1, -1, 125,
584 10, -1, -1, -1, 38, -1, -1, 41, -1, -1,
585 -1, 125, -1, -1, -1, -1, 38, -1, -1, 41,
586 -1, -1, -1, -1, -1, 59, -1, -1, 38, -1,
587 -1, 41, -1, -1, -1, -1, -1, 59, -1, -1,
588 258, 259, 260, 261, 125, 263, -1, -1, -1, 59,
589 268, 269, -1, 258, 259, 260, 261, 125, 263, -1,
590 -1, -1, -1, 268, 269, -1, 284, 285, -1, -1,
591 -1, -1, 290, 258, 259, 260, 261, 125, 263, 284,
592 285, -1, 41, 268, 269, 290, -1, 258, 259, 260,
593 261, 125, 263, -1, -1, -1, -1, 268, 269, 258,
594 259, 260, 261, 125, 263, 290, -1, -1, -1, 268,
595 269, -1, -1, 284, 285, 125, -1, -1, -1, 290,
596 -1, -1, -1, -1, -1, 284, 285, -1, -1, -1,
597 -1, 290, 258, 259, 260, 261, -1, 263, -1, -1,
598 40, -1, 268, 269, 258, 259, 260, 261, -1, 263,
599 -1, -1, -1, -1, 268, 269, -1, -1, 284, 285,
600 60, -1, 62, -1, 290, -1, 125, -1, -1, -1,
601 284, 285, -1, -1, -1, -1, 290, 258, 259, 260,
602 261, -1, 263, 6, 7, 41, -1, 268, 269, -1,
603 258, 259, 260, 261, -1, 263, -1, -1, -1, -1,
604 268, 269, -1, 284, 285, 28, 29, -1, -1, 290,
605 258, 259, 260, 261, -1, 263, 284, 285, -1, -1,
606 268, 269, 290, 123, 258, 259, 260, 261, -1, 263,
607 -1, -1, 40, -1, 268, 269, 258, 259, 260, 261,
608 -1, 263, 290, -1, -1, -1, 268, 269, 258, 259,
609 260, 261, 60, 263, 62, -1, 290, -1, 268, 269,
610 -1, -1, -1, -1, -1, 40, -1, -1, 290, 125,
611 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
612 290, 104, -1, -1, -1, 60, -1, 62, -1, 112,
613 -1, -1, -1, 116, -1, -1, -1, 120, 121, 258,
614 259, 260, 261, -1, 263, -1, -1, 40, -1, 268,
615 269, -1, -1, -1, -1, 123, -1, -1, -1, -1,
616 -1, -1, -1, -1, -1, -1, -1, 60, -1, 62,
617 -1, 290, -1, -1, 157, -1, 159, -1, -1, -1,
618 -1, -1, -1, -1, -1, -1, -1, -1, 123, -1,
619 -1, -1, 40, -1, -1, 178, 179, 257, -1, -1,
620 -1, -1, 262, -1, 264, 265, 266, 267, 191, 192,
621 270, 271, 60, -1, 62, 275, 199, 200, 278, 279,
622 280, 281, -1, -1, -1, -1, 286, 287, 288, 289,
623 123, 291, 292, 293, 294, 60, -1, 62, -1, -1,
624 -1, -1, 258, 259, 260, 261, -1, 263, -1, -1,
625 -1, -1, 268, 269, 60, -1, 62, -1, -1, -1,
626 -1, 244, -1, -1, -1, -1, -1, -1, -1, 252,
627 -1, -1, -1, -1, 290, 123, -1, -1, -1, -1,
628 -1, -1, 265, -1, -1, -1, 269, 270, -1, 257,
629 273, -1, -1, -1, 262, -1, 264, 265, 266, 267,
630 -1, -1, 270, 271, -1, -1, -1, 275, 276, -1,
631 278, 279, 280, 281, -1, -1, -1, -1, 286, 287,
632 288, 289, 257, 291, 292, 293, 294, 262, -1, 264,
633 265, 266, 267, -1, -1, 270, 271, -1, -1, -1,
634 -1, 276, -1, 278, 279, 280, 281, -1, -1, -1,
635 -1, 286, 287, 288, 289, -1, 291, 292, 293, 294,
636 -1, -1, -1, -1, 257, -1, -1, -1, -1, 262,
637 -1, 264, 265, 266, 267, -1, -1, 270, 271, -1,
638 -1, -1, 275, -1, -1, 278, 279, 280, 281, -1,
639 -1, -1, -1, 286, 287, 288, 289, -1, 291, 292,
640 293, 294, -1, -1, -1, -1, -1, -1, -1, 257,
641 -1, -1, -1, -1, 262, -1, 264, 265, 266, 267,
642 -1, -1, 270, 271, -1, -1, -1, -1, -1, -1,
643 278, 279, 280, 281, -1, -1, -1, -1, 286, 287,
644 288, 289, -1, 291, 292, 293, 294, -1, -1, -1,
645 -1, -1, -1, 278, 279, 280, -1, -1, -1, -1,
646 -1, 286, 287, 288, 289, -1, 291, 292, 293, 294,
647 55, 56, -1, 58, 280, -1, 61, -1, -1, -1,
648 286, 287, 288, 289, -1, 291, 292, 293, 294, -1,
649 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
650 -1, -1, -1, -1, -1, -1, -1, 92, -1, 94,
651 95, -1, -1, -1, -1, -1, -1, -1, -1, -1,
652 -1, -1, -1, -1, -1, 110, -1, -1, -1, -1,
653 -1, -1, 117, 118, -1, -1, -1, -1, -1, -1,
654 -1, 126, -1, -1, -1, -1, -1, -1, -1, -1,
655 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
656 -1, -1, -1, -1, -1, 150, 151, 152, 153, 154,
657 155, -1, -1, -1, -1, -1, -1, -1, -1, 164,
658 -1, 166, -1, -1, 169, -1, -1, -1, -1, -1,
659 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
660 -1, -1, -1, 188, -1, -1, -1, -1, -1, -1,
661 -1, -1, -1, -1, -1, -1, 201, 202, -1, -1,
662 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
663 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
664 -1, -1, -1, -1, -1, -1, -1, 232, -1, -1,
665 -1, -1, -1, -1, -1, 240, -1, -1, -1, -1,
666 245, 246, 247, -1, -1, -1, -1, 252, -1, -1,
667 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
668 265, -1, -1, -1, -1, -1, 271, 272,
674 #define YYMAXTOKEN 295
676 const char * const yyname[] = {
677 "end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
678 0,0,0,0,0,0,0,"'&'",0,"'('","')'",0,0,0,"'-'",0,0,0,0,0,0,0,0,0,0,0,0,0,"';'",
679 "'<'",0,"'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
680 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'","'|'","'}'",0,0,0,0,
681 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
682 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
683 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
684 0,0,0,0,0,0,0,"IF","THEN","ELSE","ELIF","FI","CASE","ESAC","FOR","SELECT",
685 "WHILE","UNTIL","DO","DONE","FUNCTION","COND_START","COND_END","COND_ERROR",
686 "IN","BANG","TIME","TIMEOPT","WORD","ASSIGNMENT_WORD","NUMBER","ARITH_CMD",
687 "ARITH_FOR_EXPRS","COND_CMD","AND_AND","OR_OR","GREATER_GREATER","LESS_LESS",
688 "LESS_AND","GREATER_AND","SEMI_SEMI","LESS_LESS_MINUS","AND_GREATER",
689 "LESS_GREATER","GREATER_BAR","yacc_EOF",
691 const char * const yyrule[] = {
692 "$accept : inputunit",
693 "inputunit : simple_list '\\n'",
695 "inputunit : error '\\n'",
696 "inputunit : yacc_EOF",
698 "word_list : word_list WORD",
699 "redirection : '>' WORD",
700 "redirection : '<' WORD",
701 "redirection : NUMBER '>' WORD",
702 "redirection : NUMBER '<' WORD",
703 "redirection : GREATER_GREATER WORD",
704 "redirection : NUMBER GREATER_GREATER WORD",
705 "redirection : LESS_LESS WORD",
706 "redirection : NUMBER LESS_LESS WORD",
707 "redirection : LESS_AND NUMBER",
708 "redirection : NUMBER LESS_AND NUMBER",
709 "redirection : GREATER_AND NUMBER",
710 "redirection : NUMBER GREATER_AND NUMBER",
711 "redirection : LESS_AND WORD",
712 "redirection : NUMBER LESS_AND WORD",
713 "redirection : GREATER_AND WORD",
714 "redirection : NUMBER GREATER_AND WORD",
715 "redirection : LESS_LESS_MINUS WORD",
716 "redirection : NUMBER LESS_LESS_MINUS WORD",
717 "redirection : GREATER_AND '-'",
718 "redirection : NUMBER GREATER_AND '-'",
719 "redirection : LESS_AND '-'",
720 "redirection : NUMBER LESS_AND '-'",
721 "redirection : AND_GREATER WORD",
722 "redirection : NUMBER LESS_GREATER WORD",
723 "redirection : LESS_GREATER WORD",
724 "redirection : GREATER_BAR WORD",
725 "redirection : NUMBER GREATER_BAR WORD",
726 "simple_command_element : WORD",
727 "simple_command_element : ASSIGNMENT_WORD",
728 "simple_command_element : redirection",
729 "redirection_list : redirection",
730 "redirection_list : redirection_list redirection",
731 "simple_command : simple_command_element",
732 "simple_command : simple_command simple_command_element",
733 "command : simple_command",
734 "command : shell_command",
735 "command : shell_command redirection_list",
736 "command : function_def",
737 "shell_command : for_command",
738 "shell_command : case_command",
739 "shell_command : WHILE compound_list DO compound_list DONE",
740 "shell_command : UNTIL compound_list DO compound_list DONE",
741 "shell_command : select_command",
742 "shell_command : if_command",
743 "shell_command : subshell",
744 "shell_command : group_command",
745 "shell_command : arith_command",
746 "shell_command : cond_command",
747 "shell_command : arith_for_command",
748 "for_command : FOR WORD newline_list DO compound_list DONE",
749 "for_command : FOR WORD newline_list '{' compound_list '}'",
750 "for_command : FOR WORD ';' newline_list DO compound_list DONE",
751 "for_command : FOR WORD ';' newline_list '{' compound_list '}'",
752 "for_command : FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE",
753 "for_command : FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'",
754 "arith_for_command : FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE",
755 "arith_for_command : FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}'",
756 "arith_for_command : FOR ARITH_FOR_EXPRS DO compound_list DONE",
757 "arith_for_command : FOR ARITH_FOR_EXPRS '{' compound_list '}'",
758 "select_command : SELECT WORD newline_list DO list DONE",
759 "select_command : SELECT WORD newline_list '{' list '}'",
760 "select_command : SELECT WORD ';' newline_list DO list DONE",
761 "select_command : SELECT WORD ';' newline_list '{' list '}'",
762 "select_command : SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE",
763 "select_command : SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}'",
764 "case_command : CASE WORD newline_list IN newline_list ESAC",
765 "case_command : CASE WORD newline_list IN case_clause_sequence newline_list ESAC",
766 "case_command : CASE WORD newline_list IN case_clause ESAC",
767 "function_def : WORD '(' ')' newline_list function_body",
768 "function_def : FUNCTION WORD '(' ')' newline_list function_body",
769 "function_def : FUNCTION WORD newline_list function_body",
770 "function_body : shell_command",
771 "function_body : shell_command redirection_list",
772 "subshell : '(' compound_list ')'",
773 "if_command : IF compound_list THEN compound_list FI",
774 "if_command : IF compound_list THEN compound_list ELSE compound_list FI",
775 "if_command : IF compound_list THEN compound_list elif_clause FI",
776 "group_command : '{' compound_list '}'",
777 "arith_command : ARITH_CMD",
778 "cond_command : COND_START COND_CMD COND_END",
779 "elif_clause : ELIF compound_list THEN compound_list",
780 "elif_clause : ELIF compound_list THEN compound_list ELSE compound_list",
781 "elif_clause : ELIF compound_list THEN compound_list elif_clause",
782 "case_clause : pattern_list",
783 "case_clause : case_clause_sequence pattern_list",
784 "pattern_list : newline_list pattern ')' compound_list",
785 "pattern_list : newline_list pattern ')' newline_list",
786 "pattern_list : newline_list '(' pattern ')' compound_list",
787 "pattern_list : newline_list '(' pattern ')' newline_list",
788 "case_clause_sequence : pattern_list SEMI_SEMI",
789 "case_clause_sequence : case_clause_sequence pattern_list SEMI_SEMI",
791 "pattern : pattern '|' WORD",
792 "list : newline_list list0",
793 "compound_list : list",
794 "compound_list : newline_list list1",
795 "list0 : list1 '\\n' newline_list",
796 "list0 : list1 '&' newline_list",
797 "list0 : list1 ';' newline_list",
798 "list1 : list1 AND_AND newline_list list1",
799 "list1 : list1 OR_OR newline_list list1",
800 "list1 : list1 '&' newline_list list1",
801 "list1 : list1 ';' newline_list list1",
802 "list1 : list1 '\\n' newline_list list1",
803 "list1 : pipeline_command",
804 "list_terminator : '\\n'",
805 "list_terminator : ';'",
806 "list_terminator : yacc_EOF",
808 "newline_list : newline_list '\\n'",
809 "simple_list : simple_list1",
810 "simple_list : simple_list1 '&'",
811 "simple_list : simple_list1 ';'",
812 "simple_list1 : simple_list1 AND_AND newline_list simple_list1",
813 "simple_list1 : simple_list1 OR_OR newline_list simple_list1",
814 "simple_list1 : simple_list1 '&' simple_list1",
815 "simple_list1 : simple_list1 ';' simple_list1",
816 "simple_list1 : pipeline_command",
817 "pipeline_command : pipeline",
818 "pipeline_command : BANG pipeline",
819 "pipeline_command : timespec pipeline",
820 "pipeline_command : timespec BANG pipeline",
821 "pipeline_command : BANG timespec pipeline",
822 "pipeline : pipeline '|' newline_list pipeline",
823 "pipeline : command",
825 "timespec : TIME TIMEOPT",
833 #define YYMAXDEPTH YYSTACKSIZE
836 #define YYSTACKSIZE YYMAXDEPTH
838 #define YYSTACKSIZE 10000
839 #define YYMAXDEPTH 10000
842 #define YYINITSTACKSIZE 200
855 #line 815 "/usr/homes/chet/src/bash/src/parse.y"
857 /* Possible states for the parser that require it to do special things. */
858 #define PST_CASEPAT 0x001 /* in a case pattern list */
859 #define PST_ALEXPNEXT 0x002 /* expand next word for aliases */
860 #define PST_ALLOWOPNBRC 0x004 /* allow open brace for function def */
861 #define PST_NEEDCLOSBRC 0x008 /* need close brace */
862 #define PST_DBLPAREN 0x010 /* double-paren parsing */
863 #define PST_SUBSHELL 0x020 /* ( ... ) subshell */
864 #define PST_CMDSUBST 0x040 /* $( ... ) command substitution */
865 #define PST_CASESTMT 0x080 /* parsing a case statement */
866 #define PST_CONDCMD 0x100 /* parsing a [[...]] command */
867 #define PST_CONDEXPR 0x200 /* parsing the guts of [[...]] */
868 #define PST_ARITHFOR 0x400 /* parsing an arithmetic for command */
870 /* Initial size to allocate for tokens, and the
871 amount to grow them by. */
872 #define TOKEN_DEFAULT_INITIAL_SIZE 496
873 #define TOKEN_DEFAULT_GROW_SIZE 512
875 /* The token currently being read. */
876 static int current_token;
878 /* The last read token, or NULL. read_token () uses this for context
880 static int last_read_token;
882 /* The token read prior to last_read_token. */
883 static int token_before_that;
885 /* The token read prior to token_before_that. */
886 static int two_tokens_ago;
888 /* If non-zero, it is the token that we want read_token to return
889 regardless of what text is (or isn't) present to be read. This
890 is reset by read_token. If token_to_read == WORD or
891 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
892 static int token_to_read;
893 static WORD_DESC *word_desc_to_read;
895 /* The current parser state. */
896 static int parser_state;
898 /* Global var is non-zero when end of file has been reached. */
910 /* yy_getc () returns the next available character from input or EOF.
911 yy_ungetc (c) makes `c' the next character to read.
912 init_yy_io (get, unget, type, location) makes the function GET the
913 installed function for getting the next character, makes UNGET the
914 installed function for un-getting a character, sets the type of stream
915 (either string or file) from TYPE, and makes LOCATION point to where
916 the input is coming from. */
918 /* Unconditionally returns end-of-file. */
925 /* Variable containing the current get and unget functions.
926 See ./input.h for a clearer description. */
927 BASH_INPUT bash_input;
929 /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
930 is non-null, avoiding a memory leak. */
932 initialize_bash_input ()
934 bash_input.type = st_none;
935 FREE (bash_input.name);
936 bash_input.name = (char *)NULL;
937 bash_input.location.file = (FILE *)NULL;
938 bash_input.location.string = (char *)NULL;
939 bash_input.getter = (Function *)NULL;
940 bash_input.ungetter = (Function *)NULL;
943 /* Set the contents of the current bash input stream from
944 GET, UNGET, TYPE, NAME, and LOCATION. */
946 init_yy_io (get, unget, type, name, location)
947 Function *get, *unget;
948 enum stream_type type;
950 INPUT_STREAM location;
952 bash_input.type = type;
953 FREE (bash_input.name);
954 bash_input.name = name ? savestring (name) : (char *)NULL;
958 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
960 bash_input.location = location;
962 bash_input.getter = get;
963 bash_input.ungetter = unget;
966 /* Call this to get the next character of input. */
970 return (*(bash_input.getter)) ();
973 /* Call this to unget C. That is, to make C the next character
979 return (*(bash_input.ungetter)) (c);
982 #if defined (BUFFERED_INPUT)
984 input_file_descriptor ()
986 switch (bash_input.type)
989 return (fileno (bash_input.location.file));
991 return (bash_input.location.buffered_fd);
994 return (fileno (stdin));
997 #endif /* BUFFERED_INPUT */
999 /* **************************************************************** */
1001 /* Let input be read from readline (). */
1003 /* **************************************************************** */
1005 #if defined (READLINE)
1006 char *current_readline_prompt = (char *)NULL;
1007 char *current_readline_line = (char *)NULL;
1008 int current_readline_line_index = 0;
1013 SigHandler *old_sigint;
1016 if (!current_readline_line)
1018 if (!bash_readline_initialized)
1019 initialize_readline ();
1021 #if defined (JOB_CONTROL)
1023 give_terminal_to (shell_pgrp, 0);
1024 #endif /* JOB_CONTROL */
1026 if (signal_is_ignored (SIGINT) == 0)
1028 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
1029 interrupt_immediately++;
1032 current_readline_line = readline (current_readline_prompt ?
1033 current_readline_prompt : "");
1035 if (signal_is_ignored (SIGINT) == 0)
1037 interrupt_immediately--;
1038 set_signal_handler (SIGINT, old_sigint);
1042 /* Reset the prompt to the decoded value of prompt_string_pointer. */
1043 reset_readline_prompt ();
1046 if (current_readline_line == 0)
1049 current_readline_line_index = 0;
1050 line_len = strlen (current_readline_line);
1052 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
1053 current_readline_line[line_len++] = '\n';
1054 current_readline_line[line_len] = '\0';
1057 if (current_readline_line[current_readline_line_index] == 0)
1059 free (current_readline_line);
1060 current_readline_line = (char *)NULL;
1061 return (yy_readline_get ());
1065 c = (unsigned char)current_readline_line[current_readline_line_index++];
1071 yy_readline_unget (c)
1074 if (current_readline_line_index && current_readline_line)
1075 current_readline_line[--current_readline_line_index] = c;
1080 with_input_from_stdin ()
1082 INPUT_STREAM location;
1084 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
1086 location.string = current_readline_line;
1087 init_yy_io (yy_readline_get, yy_readline_unget,
1088 st_stdin, "readline stdin", location);
1092 #else /* !READLINE */
1095 with_input_from_stdin ()
1097 with_input_from_stream (stdin, "stdin");
1099 #endif /* !READLINE */
1101 /* **************************************************************** */
1103 /* Let input come from STRING. STRING is zero terminated. */
1105 /* **************************************************************** */
1110 register char *string;
1113 string = bash_input.location.string;
1116 /* If the string doesn't exist, or is empty, EOF found. */
1117 if (string && *string)
1119 c = *(unsigned char *)string++;
1120 bash_input.location.string = string;
1129 *(--bash_input.location.string) = c;
1134 with_input_from_string (string, name)
1135 char *string, *name;
1137 INPUT_STREAM location;
1139 location.string = string;
1140 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
1143 /* **************************************************************** */
1145 /* Let input come from STREAM. */
1147 /* **************************************************************** */
1149 /* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
1150 define, and just use getc/ungetc if it was defined, but since bash
1151 installs its signal handlers without the SA_RESTART flag, some signals
1152 (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
1153 the read to be restarted. We need to restart it ourselves. */
1161 if (bash_input.location.file)
1162 result = getc_with_restart (bash_input.location.file);
1171 return (ungetc_with_restart (c, bash_input.location.file));
1175 with_input_from_stream (stream, name)
1179 INPUT_STREAM location;
1181 location.file = stream;
1182 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
1185 typedef struct stream_saver {
1186 struct stream_saver *next;
1187 BASH_INPUT bash_input;
1189 #if defined (BUFFERED_INPUT)
1190 BUFFERED_STREAM *bstream;
1191 #endif /* BUFFERED_INPUT */
1194 /* The globally known line number. */
1195 int line_number = 0;
1197 #if defined (COND_COMMAND)
1198 static int cond_lineno;
1199 static int cond_token;
1202 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
1205 push_stream (reset_lineno)
1208 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1210 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1212 #if defined (BUFFERED_INPUT)
1213 saver->bstream = (BUFFERED_STREAM *)NULL;
1214 /* If we have a buffered stream, clear out buffers[fd]. */
1215 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1216 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
1217 (BUFFERED_STREAM *)NULL);
1218 #endif /* BUFFERED_INPUT */
1220 saver->line = line_number;
1221 bash_input.name = (char *)NULL;
1222 saver->next = stream_list;
1223 stream_list = saver;
1236 STREAM_SAVER *saver = stream_list;
1239 stream_list = stream_list->next;
1241 init_yy_io (saver->bash_input.getter,
1242 saver->bash_input.ungetter,
1243 saver->bash_input.type,
1244 saver->bash_input.name,
1245 saver->bash_input.location);
1247 #if defined (BUFFERED_INPUT)
1248 /* If we have a buffered stream, restore buffers[fd]. */
1249 /* If the input file descriptor was changed while this was on the
1250 save stack, update the buffered fd to the new file descriptor and
1251 re-establish the buffer <-> bash_input fd correspondence. */
1252 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1254 if (bash_input_fd_changed)
1256 bash_input_fd_changed = 0;
1257 if (default_buffered_input >= 0)
1259 bash_input.location.buffered_fd = default_buffered_input;
1260 saver->bstream->b_fd = default_buffered_input;
1261 SET_CLOSE_ON_EXEC (default_buffered_input);
1264 /* XXX could free buffered stream returned as result here. */
1265 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
1267 #endif /* BUFFERED_INPUT */
1269 line_number = saver->line;
1271 FREE (saver->bash_input.name);
1276 /* Return 1 if a stream of type TYPE is saved on the stack. */
1278 stream_on_stack (type)
1279 enum stream_type type;
1281 register STREAM_SAVER *s;
1283 for (s = stream_list; s; s = s->next)
1284 if (s->bash_input.type == type)
1289 /* Save the current token state and return it in a malloced array. */
1295 ret = (int *)xmalloc (3 * sizeof (int));
1296 ret[0] = last_read_token;
1297 ret[1] = token_before_that;
1298 ret[2] = two_tokens_ago;
1303 restore_token_state (ts)
1308 last_read_token = ts[0];
1309 token_before_that = ts[1];
1310 two_tokens_ago = ts[2];
1314 * This is used to inhibit alias expansion and reserved word recognition
1315 * inside case statement pattern lists. A `case statement pattern list' is:
1317 * everything between the `in' in a `case word in' and the next ')'
1319 * everything between a `;;' and the next `)' or `esac'
1322 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1324 #if !defined (ALIAS)
1325 typedef void *alias_t;
1328 #define END_OF_ALIAS 0
1331 * Pseudo-global variables used in implementing token-wise alias expansion.
1335 * Pushing and popping strings. This works together with shell_getc to
1336 * implement alias expansion on a per-token basis.
1339 typedef struct string_saver {
1340 struct string_saver *next;
1341 int expand_alias; /* Value to set expand_alias to when string is popped. */
1344 alias_t *expander; /* alias that caused this line to be pushed. */
1346 int saved_line_size, saved_line_index, saved_line_terminator;
1349 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1352 * Push the current shell_input_line onto a stack of such lines and make S
1353 * the current input. Used when expanding aliases. EXPAND is used to set
1354 * the value of expand_next_token when the string is popped, so that the
1355 * word after the alias in the original line is handled correctly when the
1356 * alias expands to multiple words. TOKEN is the token that was expanded
1357 * into S; it is saved and used to prevent infinite recursive expansion.
1360 push_string (s, expand, ap)
1365 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
1367 temp->expand_alias = expand;
1368 temp->saved_line = shell_input_line;
1369 temp->saved_line_size = shell_input_line_size;
1370 temp->saved_line_index = shell_input_line_index;
1371 temp->saved_line_terminator = shell_input_line_terminator;
1373 temp->expander = ap;
1375 temp->next = pushed_string_list;
1376 pushed_string_list = temp;
1380 ap->flags |= AL_BEINGEXPANDED;
1383 shell_input_line = s;
1384 shell_input_line_size = strlen (s);
1385 shell_input_line_index = 0;
1386 shell_input_line_terminator = '\0';
1387 parser_state &= ~PST_ALEXPNEXT;
1391 * Make the top of the pushed_string stack be the current shell input.
1392 * Only called when there is something on the stack. Called from shell_getc
1393 * when it thinks it has consumed the string generated by an alias expansion
1394 * and needs to return to the original input line.
1401 FREE (shell_input_line);
1402 shell_input_line = pushed_string_list->saved_line;
1403 shell_input_line_index = pushed_string_list->saved_line_index;
1404 shell_input_line_size = pushed_string_list->saved_line_size;
1405 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
1407 if (pushed_string_list->expand_alias)
1408 parser_state |= PST_ALEXPNEXT;
1410 parser_state &= ~PST_ALEXPNEXT;
1412 t = pushed_string_list;
1413 pushed_string_list = pushed_string_list->next;
1417 t->expander->flags &= ~AL_BEINGEXPANDED;
1426 register STRING_SAVER *t, *t1;
1428 for (t = pushed_string_list; t; )
1431 FREE (t->saved_line);
1434 t->expander->flags &= ~AL_BEINGEXPANDED;
1439 pushed_string_list = (STRING_SAVER *)NULL;
1442 #endif /* ALIAS || DPAREN_ARITHMETIC */
1444 /* Return a line of text, taken from wherever yylex () reads input.
1445 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
1446 is non-zero, we remove unquoted \<newline> pairs. This is used by
1447 read_secondary_line to read here documents. */
1449 read_a_line (remove_quoted_newline)
1450 int remove_quoted_newline;
1452 static char *line_buffer = (char *)NULL;
1453 static int buffer_size = 0;
1454 int indx = 0, c, peekc, pass_next;
1456 #if defined (READLINE)
1457 if (interactive && bash_input.type != st_string && no_line_editing)
1459 if (interactive && bash_input.type != st_string)
1468 /* Allow immediate exit if interrupted during input. */
1471 /* Ignore null bytes in input. */
1475 internal_warning ("read_a_line: ignored null byte in input");
1480 /* If there is no more input, then we return NULL. */
1483 if (interactive && bash_input.type == st_stream)
1486 return ((char *)NULL);
1490 /* `+2' in case the final character in the buffer is a newline. */
1491 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
1493 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
1494 here document with an unquoted delimiter. In this case,
1495 the line will be expanded as if it were in double quotes.
1496 We allow a backslash to escape the next character, but we
1497 need to treat the backslash specially only if a backslash
1498 quoting a backslash-newline pair appears in the line. */
1501 line_buffer[indx++] = c;
1504 else if (c == '\\' && remove_quoted_newline)
1508 continue; /* Make the unquoted \<newline> pair disappear. */
1513 line_buffer[indx++] = c; /* Preserve the backslash. */
1517 line_buffer[indx++] = c;
1521 line_buffer[indx] = '\0';
1522 return (line_buffer);
1527 /* Return a line as in read_a_line (), but insure that the prompt is
1528 the secondary prompt. This is used to read the lines of a here
1529 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
1530 newlines quoted with backslashes while reading the line. It is
1531 non-zero unless the delimiter of the here document was quoted. */
1533 read_secondary_line (remove_quoted_newline)
1534 int remove_quoted_newline;
1536 prompt_string_pointer = &ps2_prompt;
1538 return (read_a_line (remove_quoted_newline));
1541 /* **************************************************************** */
1545 /* **************************************************************** */
1547 /* Reserved words. These are only recognized as the first word of a
1549 STRING_INT_ALIST word_token_alist[] = {
1558 #if defined (SELECT_COMMAND)
1559 { "select", SELECT },
1566 { "function", FUNCTION },
1567 #if defined (COMMAND_TIMING)
1573 #if defined (COND_COMMAND)
1574 { "[[", COND_START },
1580 /* XXX - we should also have an alist with strings for other tokens, so we
1581 can give more descriptive error messages. Look at y.tab.h for the
1584 /* These are used by read_token_word, but appear up here so that shell_getc
1585 can use them to decide when to add otherwise blank lines to the history. */
1587 /* The primary delimiter stack. */
1588 struct dstack dstack = { (char *)NULL, 0, 0 };
1590 /* A temporary delimiter stack to be used when decoding prompt strings.
1591 This is needed because command substitutions in prompt strings (e.g., PS2)
1592 can screw up the parser's quoting state. */
1593 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
1595 /* Macro for accessing the top delimiter on the stack. Returns the
1596 delimiter or zero if none. */
1597 #define current_delimiter(ds) \
1598 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
1600 #define push_delimiter(ds, character) \
1603 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
1604 ds.delimiters = xrealloc \
1605 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
1606 ds.delimiters[ds.delimiter_depth] = character; \
1607 ds.delimiter_depth++; \
1611 #define pop_delimiter(ds) ds.delimiter_depth--
1613 /* Return the next shell input character. This always reads characters
1614 from shell_input_line; when that line is exhausted, it is time to
1615 read the next line. This is called by read_token when the shell is
1616 processing normal command input. */
1618 /* This implements one-character lookahead/lookbehind across physical input
1619 lines, to avoid something being lost because it's pushed back with
1620 shell_ungetc when we're at the start of a line. */
1621 static int eol_ungetc_lookahead = 0;
1624 shell_getc (remove_quoted_newline)
1625 int remove_quoted_newline;
1629 static int mustpop = 0;
1633 if (eol_ungetc_lookahead)
1635 c = eol_ungetc_lookahead;
1636 eol_ungetc_lookahead = 0;
1640 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1641 /* If shell_input_line[shell_input_line_index] == 0, but there is
1642 something on the pushed list of strings, then we don't want to go
1643 off and get another line. We let the code down below handle it. */
1645 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
1646 (pushed_string_list == (STRING_SAVER *)NULL)))
1647 #else /* !ALIAS && !DPAREN_ARITHMETIC */
1648 if (!shell_input_line || !shell_input_line[shell_input_line_index])
1649 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
1655 /* Allow immediate exit if interrupted during input. */
1659 shell_input_line_terminator = 0;
1661 #if defined (JOB_CONTROL)
1662 /* This can cause a problem when reading a command as the result
1663 of a trap, when the trap is called from flush_child. This call
1664 had better not cause jobs to disappear from the job table in
1665 that case, or we will have big trouble. */
1666 notify_and_cleanup ();
1667 #else /* !JOB_CONTROL */
1668 cleanup_dead_jobs ();
1669 #endif /* !JOB_CONTROL */
1671 #if defined (READLINE)
1672 if (interactive && bash_input.type != st_string && no_line_editing)
1674 if (interactive && bash_input.type != st_string)
1678 if (bash_input.type == st_stream)
1685 /* Allow immediate exit if interrupted during input. */
1691 internal_warning ("shell_getc: ignored null byte in input");
1696 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
1700 if (bash_input.type == st_stream)
1704 shell_input_line_terminator = EOF;
1706 shell_input_line[i] = '\0';
1710 shell_input_line[i++] = c;
1714 shell_input_line[--i] = '\0';
1715 current_command_line_count++;
1720 shell_input_line_index = 0;
1721 shell_input_line_len = i; /* == strlen (shell_input_line) */
1723 #if defined (HISTORY)
1724 if (remember_on_history && shell_input_line && shell_input_line[0])
1727 # if defined (BANG_HISTORY)
1730 /* If the current delimiter is a single quote, we should not be
1731 performing history expansion, even if we're on a different
1732 line from the original single quote. */
1733 old_hist = history_expansion_inhibited;
1734 if (current_delimiter (dstack) == '\'')
1735 history_expansion_inhibited = 1;
1737 expansions = pre_process_line (shell_input_line, 1, 1);
1738 # if defined (BANG_HISTORY)
1739 history_expansion_inhibited = old_hist;
1741 if (expansions != shell_input_line)
1743 free (shell_input_line);
1744 shell_input_line = expansions;
1745 shell_input_line_len = shell_input_line ?
1746 strlen (shell_input_line) : 0;
1747 if (!shell_input_line_len)
1748 current_command_line_count--;
1750 /* We have to force the xrealloc below because we don't know
1751 the true allocated size of shell_input_line anymore. */
1752 shell_input_line_size = shell_input_line_len;
1755 /* Try to do something intelligent with blank lines encountered while
1756 entering multi-line commands. XXX - this is grotesque */
1757 else if (remember_on_history && shell_input_line &&
1758 shell_input_line[0] == '\0' &&
1759 current_command_line_count > 1)
1761 if (current_delimiter (dstack))
1762 /* We know shell_input_line[0] == 0 and we're reading some sort of
1763 quoted string. This means we've got a line consisting of only
1764 a newline in a quoted string. We want to make sure this line
1765 gets added to the history. */
1766 maybe_add_history (shell_input_line);
1770 hdcs = history_delimiting_chars ();
1771 if (hdcs && hdcs[0] == ';')
1772 maybe_add_history (shell_input_line);
1776 #endif /* HISTORY */
1778 if (shell_input_line)
1780 /* Lines that signify the end of the shell's input should not be
1782 if (echo_input_at_read && (shell_input_line[0] ||
1783 shell_input_line_terminator != EOF))
1784 fprintf (stderr, "%s\n", shell_input_line);
1788 shell_input_line_size = 0;
1789 prompt_string_pointer = ¤t_prompt_string;
1794 /* Add the newline to the end of this string, iff the string does
1795 not already end in an EOF character. */
1796 if (shell_input_line_terminator != EOF)
1798 if (shell_input_line_len + 3 > shell_input_line_size)
1799 shell_input_line = xrealloc (shell_input_line,
1800 1 + (shell_input_line_size += 2));
1802 shell_input_line[shell_input_line_len] = '\n';
1803 shell_input_line[shell_input_line_len + 1] = '\0';
1807 c = shell_input_line[shell_input_line_index];
1810 shell_input_line_index++;
1812 if (c == '\\' && remove_quoted_newline &&
1813 shell_input_line[shell_input_line_index] == '\n')
1820 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1821 /* If C is NULL, we have reached the end of the current input string. If
1822 pushed_string_list is non-empty, it's time to pop to the previous string
1823 because we have fully consumed the result of the last alias expansion.
1824 Do it transparently; just return the next character of the string popped
1826 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
1831 c = shell_input_line[shell_input_line_index];
1833 shell_input_line_index++;
1842 #endif /* ALIAS || DPAREN_ARITHMETIC */
1844 if (!c && shell_input_line_terminator == EOF)
1845 return ((shell_input_line_index != 0) ? '\n' : EOF);
1847 return ((unsigned char)c);
1850 /* Put C back into the input for the shell. */
1855 if (shell_input_line && shell_input_line_index)
1856 shell_input_line[--shell_input_line_index] = c;
1858 eol_ungetc_lookahead = c;
1864 if (shell_input_line && shell_input_line_index)
1865 shell_input_line_index--;
1868 /* Discard input until CHARACTER is seen, then push that character back
1869 onto the input stream. */
1871 discard_until (character)
1876 while ((c = shell_getc (0)) != EOF && c != character)
1884 execute_prompt_command (command)
1887 Function *temp_last, *temp_this;
1889 int temp_exit_value, temp_eof_encountered;
1891 temp_last = last_shell_builtin;
1892 temp_this = this_shell_builtin;
1893 temp_exit_value = last_command_exit_value;
1894 temp_eof_encountered = eof_encountered;
1895 last_lastarg = get_string_value ("_");
1897 last_lastarg = savestring (last_lastarg);
1899 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
1901 last_shell_builtin = temp_last;
1902 this_shell_builtin = temp_this;
1903 last_command_exit_value = temp_exit_value;
1904 eof_encountered = temp_eof_encountered;
1906 bind_variable ("_", last_lastarg);
1907 FREE (last_lastarg);
1909 if (token_to_read == '\n') /* reset_parser was called */
1913 /* Place to remember the token. We try to keep the buffer
1914 at a reasonable size, but it can grow. */
1915 static char *token = (char *)NULL;
1917 /* Current size of the token buffer. */
1918 static int token_buffer_size;
1920 /* Command to read_token () explaining what we want it to do. */
1923 #define prompt_is_ps1 \
1924 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
1926 /* Function for yyparse to call. yylex keeps track of
1927 the last two tokens read, and calls read_token. */
1931 if (interactive && (current_token == 0 || current_token == '\n'))
1933 /* Before we print a prompt, we might have to check mailboxes.
1934 We do this only if it is time to do so. Notice that only here
1935 is the mail alarm reset; nothing takes place in check_mail ()
1936 except the checking of mail. Please don't change this. */
1937 if (prompt_is_ps1 && time_to_check_mail ())
1940 reset_mail_timer ();
1943 /* Avoid printing a prompt if we're not going to read anything, e.g.
1944 after resetting the parser with read_token (RESET). */
1945 if (token_to_read == 0 && interactive)
1949 two_tokens_ago = token_before_that;
1950 token_before_that = last_read_token;
1951 last_read_token = current_token;
1952 current_token = read_token (READ);
1953 return (current_token);
1956 /* When non-zero, we have read the required tokens
1957 which allow ESAC to be the next one read. */
1958 static int esacs_needed_count;
1961 gather_here_documents ()
1964 while (need_here_doc)
1966 make_here_document (redir_stack[r++]);
1971 /* When non-zero, an open-brace used to create a group is awaiting a close
1973 static int open_brace_count;
1975 #define command_token_position(token) \
1976 (((token) == ASSIGNMENT_WORD) || \
1977 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
1979 #define assignment_acceptable(token) command_token_position(token) && \
1980 ((parser_state & PST_CASEPAT) == 0)
1982 /* Check to see if TOKEN is a reserved word and return the token
1984 #define CHECK_FOR_RESERVED_WORD(tok) \
1986 if (!dollar_present && !quoted && \
1987 reserved_word_acceptable (last_read_token)) \
1990 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
1991 if (STREQ (tok, word_token_alist[i].word)) \
1993 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
1995 if (word_token_alist[i].token == TIME) \
1997 if (word_token_alist[i].token == ESAC) \
1998 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
1999 else if (word_token_alist[i].token == CASE) \
2000 parser_state |= PST_CASESTMT; \
2001 else if (word_token_alist[i].token == COND_END) \
2002 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
2003 else if (word_token_alist[i].token == COND_START) \
2004 parser_state |= PST_CONDCMD; \
2005 else if (word_token_alist[i].token == '{') \
2006 open_brace_count++; \
2007 else if (word_token_alist[i].token == '}' && open_brace_count) \
2008 open_brace_count--; \
2009 return (word_token_alist[i].token); \
2016 /* OK, we have a token. Let's try to alias expand it, if (and only if)
2019 It is eligible for expansion if the shell is in interactive mode, and
2020 the token is unquoted and the last token read was a command
2021 separator (or expand_next_token is set), and we are currently
2022 processing an alias (pushed_string_list is non-empty) and this
2023 token is not the same as the current or any previously
2026 Special cases that disqualify:
2027 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
2029 alias_expand_token (token)
2035 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
2036 (parser_state & PST_CASEPAT) == 0)
2038 ap = find_alias (token);
2040 /* Currently expanding this token. */
2041 if (ap && (ap->flags & AL_BEINGEXPANDED))
2042 return (NO_EXPANSION);
2044 expanded = ap ? savestring (ap->value) : (char *)NULL;
2047 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
2048 return (RE_READ_TOKEN);
2051 /* This is an eligible token that does not have an expansion. */
2052 return (NO_EXPANSION);
2054 return (NO_EXPANSION);
2059 time_command_acceptable ()
2061 #if defined (COMMAND_TIMING)
2062 switch (last_read_token)
2081 #endif /* COMMAND_TIMING */
2084 /* Handle special cases of token recognition:
2085 IN is recognized if the last token was WORD and the token
2086 before that was FOR or CASE or SELECT.
2088 DO is recognized if the last token was WORD and the token
2089 before that was FOR or SELECT.
2091 ESAC is recognized if the last token caused `esacs_needed_count'
2094 `{' is recognized if the last token as WORD and the token
2095 before that was FUNCTION, or if we just parsed an arithmetic
2098 `}' is recognized if there is an unclosed `{' present.
2100 `-p' is returned as TIMEOPT if the last read token was TIME.
2102 ']]' is returned as COND_END if the parser is currently parsing
2103 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
2105 `time' is returned as TIME if and only if it is immediately
2106 preceded by one of `;', `\n', `||', `&&', or `&'.
2110 special_case_tokens (token)
2113 if ((last_read_token == WORD) &&
2114 #if defined (SELECT_COMMAND)
2115 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
2117 ((token_before_that == FOR) || (token_before_that == CASE)) &&
2119 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
2121 if (token_before_that == CASE)
2123 parser_state |= PST_CASEPAT;
2124 esacs_needed_count++;
2129 if (last_read_token == WORD &&
2130 #if defined (SELECT_COMMAND)
2131 (token_before_that == FOR || token_before_that == SELECT) &&
2133 (token_before_that == FOR) &&
2135 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
2138 /* Ditto for ESAC in the CASE case.
2139 Specifically, this handles "case word in esac", which is a legal
2140 construct, certainly because someone will pass an empty arg to the
2141 case construct, and we don't want it to barf. Of course, we should
2142 insist that the case construct has at least one pattern in it, but
2143 the designers disagree. */
2144 if (esacs_needed_count)
2146 esacs_needed_count--;
2147 if (STREQ (token, "esac"))
2149 parser_state &= ~PST_CASEPAT;
2154 /* The start of a shell function definition. */
2155 if (parser_state & PST_ALLOWOPNBRC)
2157 parser_state &= ~PST_ALLOWOPNBRC;
2158 if (token[0] == '{' && token[1] == '\0') /* } */
2161 function_bstart = line_number;
2162 return ('{'); /* } */
2166 /* We allow a `do' after a for ((...)) without an intervening
2168 if (last_read_token == ARITH_FOR_EXPRS && token[0] == 'd' && token[1] == 'o' && !token[2])
2170 if (last_read_token == ARITH_FOR_EXPRS && token[0] == '{' && token[1] == '\0') /* } */
2173 return ('{'); /* } */
2176 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
2178 open_brace_count--; /* { */
2182 #if defined (COMMAND_TIMING)
2183 /* Handle -p after `time'. */
2184 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
2188 #if defined (COMMAND_TIMING)
2189 if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
2191 #endif /* COMMAND_TIMING */
2193 #if defined (COND_COMMAND) /* [[ */
2194 if ((parser_state & PST_CONDEXPR) && token[0] == ']' && token[1] == ']' && token[2] == '\0')
2201 /* Called from shell.c when Control-C is typed at top level. Or
2202 by the error rule at top level. */
2206 dstack.delimiter_depth = 0; /* No delimiters found so far. */
2207 open_brace_count = 0;
2211 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2212 if (pushed_string_list)
2213 free_string_list ();
2214 #endif /* ALIAS || DPAREN_ARITHMETIC */
2216 if (shell_input_line)
2218 free (shell_input_line);
2219 shell_input_line = (char *)NULL;
2220 shell_input_line_size = shell_input_line_index = 0;
2223 FREE (word_desc_to_read);
2224 word_desc_to_read = (WORD_DESC *)NULL;
2226 last_read_token = '\n';
2227 token_to_read = '\n';
2230 /* Read the next token. Command can be READ (normal operation) or
2231 RESET (to normalize state). */
2233 read_token (command)
2236 int character; /* Current character. */
2237 int peek_char; /* Temporary look-ahead character. */
2238 int result; /* The thing to return. */
2240 if (command == RESET)
2248 result = token_to_read;
2249 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
2251 yylval.word = word_desc_to_read;
2252 word_desc_to_read = (WORD_DESC *)NULL;
2258 #if defined (COND_COMMAND)
2259 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
2261 cond_lineno = line_number;
2262 parser_state |= PST_CONDEXPR;
2263 yylval.command = parse_cond_command ();
2264 if (cond_token != COND_END)
2266 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
2267 parser_error (cond_lineno, "unexpected EOF while looking for `]]'");
2268 else if (cond_token != COND_ERROR)
2269 parser_error (cond_lineno, "syntax error in conditional expression");
2272 token_to_read = COND_END;
2273 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
2279 /* This is a place to jump back to once we have successfully expanded a
2280 token with an alias and pushed the string with push_string () */
2284 /* Read a single word from input. Start by skipping blanks. */
2285 while ((character = shell_getc (1)) != EOF && whitespace (character))
2288 if (character == EOF)
2294 if (character == '#' && (!interactive || interactive_comments))
2296 /* A comment. Discard until EOL or EOF, and then return a newline. */
2297 discard_until ('\n');
2299 character = '\n'; /* this will take the next if statement and return. */
2302 if (character == '\n')
2304 /* If we're about to return an unquoted newline, we can go and collect
2305 the text of any pending here document. */
2307 gather_here_documents ();
2310 parser_state &= ~PST_ALEXPNEXT;
2316 /* Shell meta-characters. */
2317 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
2320 /* Turn off alias tokenization iff this character sequence would
2321 not leave us ready to read a command. */
2322 if (character == '<' || character == '>')
2323 parser_state &= ~PST_ALEXPNEXT;
2326 peek_char = shell_getc (1);
2327 if (character == peek_char)
2332 /* If '<' then we could be at "<<" or at "<<-". We have to
2333 look ahead one more character. */
2334 peek_char = shell_getc (1);
2335 if (peek_char == '-')
2336 return (LESS_LESS_MINUS);
2339 shell_ungetc (peek_char);
2344 return (GREATER_GREATER);
2347 parser_state |= PST_CASEPAT;
2349 parser_state &= ~PST_ALEXPNEXT;
2359 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
2361 # if defined (ARITH_FOR_COMMAND)
2362 if (last_read_token == FOR)
2368 arith_for_lineno = line_number;
2369 cmdtyp = parse_arith_cmd (&wval);
2372 /* parse_arith_cmd adds quotes at the beginning and end
2373 of the string it returns; we need to take those out. */
2374 len = strlen (wval);
2375 wv2 = xmalloc (len);
2376 strncpy (wv2, wval + 1, len - 2);
2377 wv2[len - 2] = '\0';
2378 wd = make_word (wv2);
2379 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2382 return (ARITH_FOR_EXPRS);
2385 return -1; /* ERROR */
2388 # if defined (DPAREN_ARITHMETIC)
2389 if (reserved_word_acceptable (last_read_token))
2395 sline = line_number;
2396 cmdtyp = parse_arith_cmd (&wval);
2397 if (cmdtyp == 1) /* arithmetic command */
2399 wd = make_word (wval);
2400 wd->flags = W_QUOTED;
2401 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2402 free (wval); /* make_word copies it */
2405 else if (cmdtyp == 0) /* nested subshell */
2407 push_string (wval, 0, (alias_t *)NULL);
2408 if ((parser_state & PST_CASEPAT) == 0)
2409 parser_state |= PST_SUBSHELL;
2420 else if (character == '<' && peek_char == '&')
2422 else if (character == '>' && peek_char == '&')
2423 return (GREATER_AND);
2424 else if (character == '<' && peek_char == '>')
2425 return (LESS_GREATER);
2426 else if (character == '>' && peek_char == '|')
2427 return (GREATER_BAR);
2428 else if (peek_char == '>' && character == '&')
2429 return (AND_GREATER);
2431 shell_ungetc (peek_char);
2433 /* If we look like we are reading the start of a function
2434 definition, then let the reader know about it so that
2435 we will do the right thing with `{'. */
2436 if (character == ')' && last_read_token == '(' && token_before_that == WORD)
2438 parser_state |= PST_ALLOWOPNBRC;
2440 parser_state &= ~PST_ALEXPNEXT;
2442 function_dstart = line_number;
2445 /* case pattern lists may be preceded by an optional left paren. If
2446 we're not trying to parse a case pattern list, the left paren
2447 indicates a subshell. */
2448 if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
2449 parser_state |= PST_SUBSHELL;
2451 else if ((parser_state & PST_CASEPAT) && character == ')')
2452 parser_state &= ~PST_CASEPAT;
2454 else if ((parser_state & PST_SUBSHELL) && character == ')')
2455 parser_state &= ~PST_SUBSHELL;
2457 #if defined (PROCESS_SUBSTITUTION)
2458 /* Check for the constructs which introduce process substitution.
2459 Shells running in `posix mode' don't do process substitution. */
2460 if (posixly_correct ||
2461 ((character != '>' && character != '<') || peek_char != '('))
2462 #endif /* PROCESS_SUBSTITUTION */
2466 /* Hack <&- (close stdin) case. */
2467 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
2470 /* Okay, if we got this far, we have to read a word. Read one,
2471 and then check it against the known ones. */
2472 result = read_token_word (character);
2474 if (result == RE_READ_TOKEN)
2480 /* Match a $(...) or other grouping construct. This has to handle embedded
2481 quoted strings ('', ``, "") and nested constructs. It also must handle
2482 reprompting the user, if necessary, after reading a newline, and returning
2483 correct error values if it reads EOF. */
2485 #define P_FIRSTCLOSE 0x01
2486 #define P_ALLOWESC 0x02
2488 static char matched_pair_error;
2490 parse_matched_pair (qc, open, close, lenp, flags)
2491 int qc; /* `"' if this construct is within double quotes */
2495 int count, ch, was_dollar;
2496 int pass_next_character, nestlen, ttranslen, start_lineno;
2497 char *ret, *nestret, *ttrans;
2498 int retind, retsize;
2501 pass_next_character = was_dollar = 0;
2503 ret = xmalloc (retsize = 64);
2506 start_lineno = line_number;
2509 ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
2513 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
2514 EOF_Reached = 1; /* XXX */
2515 return (&matched_pair_error);
2518 /* Possible reprompting. */
2519 if (ch == '\n' && interactive &&
2520 (bash_input.type == st_stdin || bash_input.type == st_stream))
2523 if (pass_next_character) /* last char was backslash */
2525 pass_next_character = 0;
2526 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
2528 if (retind > 0) retind--; /* swallow previously-added backslash */
2532 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2533 if (ch == CTLESC || ch == CTLNUL)
2534 ret[retind++] = CTLESC;
2538 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
2540 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2541 ret[retind++] = CTLESC;
2545 else if (ch == close) /* ending delimiter */
2548 /* handle nested ${...} specially. */
2549 else if (open != close && was_dollar && open == '{' && ch == open) /* } */
2552 else if (((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
2555 /* Add this character. */
2556 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
2559 if (open == '\'') /* '' inside grouping construct */
2561 if ((flags & P_ALLOWESC) && ch == '\\')
2562 pass_next_character++;
2566 if (ch == '\\') /* backslashes */
2567 pass_next_character++;
2569 if (open != close) /* a grouping construct */
2571 if (shellquote (ch))
2573 /* '', ``, or "" inside $(...) or other grouping construct. */
2574 push_delimiter (dstack, ch);
2575 if (was_dollar && ch == '\'') /* $'...' inside group */
2576 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC);
2578 nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
2579 pop_delimiter (dstack);
2580 if (nestret == &matched_pair_error)
2583 return &matched_pair_error;
2585 if (was_dollar && ch == '\'')
2587 /* Translate $'...' here. */
2588 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
2590 nestret = sh_single_quote (ttrans);
2592 nestlen = strlen (nestret);
2593 retind -= 2; /* back up before the $' */
2595 else if (was_dollar && ch == '"')
2597 /* Locale expand $"..." here. */
2598 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
2600 nestret = xmalloc (ttranslen + 3);
2602 strcpy (nestret + 1, ttrans);
2603 nestret[ttranslen + 1] = '"';
2604 nestret[ttranslen += 2] = '\0';
2606 nestlen = ttranslen;
2607 retind -= 2; /* back up before the $" */
2611 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2612 strcpy (ret + retind, nestret);
2618 /* Parse an old-style command substitution within double quotes as a
2620 /* XXX - sh and ksh93 don't do this - XXX */
2621 else if (open == '"' && ch == '`')
2623 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
2624 if (nestret == &matched_pair_error)
2627 return &matched_pair_error;
2631 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2632 strcpy (ret + retind, nestret);
2637 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
2638 /* check for $(), $[], or ${} inside quoted string. */
2640 if (open == ch) /* undo previous increment */
2642 if (ch == '(') /* ) */
2643 nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
2644 else if (ch == '{') /* } */
2645 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE);
2646 else if (ch == '[') /* ] */
2647 nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
2648 if (nestret == &matched_pair_error)
2651 return &matched_pair_error;
2655 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2656 strcpy (ret + retind, nestret);
2661 was_dollar = (ch == '$');
2670 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
2671 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
2672 If not, assume it's a nested subshell for backwards compatibility and
2673 return 0. In any case, put the characters we've consumed into a locally-
2674 allocated buffer and make *ep point to that buffer. Return -1 on an
2675 error, for example EOF. */
2677 parse_arith_cmd (ep)
2680 int exp_lineno, rval, c;
2684 exp_lineno = line_number;
2685 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
2687 if (ttok == &matched_pair_error)
2689 /* Check that the next character is the closing right paren. If
2690 not, this is a syntax error. ( */
2691 if ((c = shell_getc (0)) != ')')
2694 token = xmalloc (ttoklen + 4);
2696 /* (( ... )) -> "..." */
2697 token[0] = (rval == 1) ? '"' : '(';
2698 strncpy (token + 1, ttok, ttoklen - 1); /* don't copy the final `)' */
2701 token[ttoklen] = '"';
2702 token[ttoklen+1] = '\0';
2706 token[ttoklen] = ')';
2707 token[ttoklen+1] = c;
2708 token[ttoklen+2] = '\0';
2714 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
2716 #if defined (COND_COMMAND)
2717 static COND_COM *cond_term ();
2718 static COND_COM *cond_and ();
2719 static COND_COM *cond_or ();
2720 static COND_COM *cond_expr ();
2725 return (cond_or ());
2734 if (cond_token == OR_OR)
2737 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
2748 if (cond_token == AND_AND)
2751 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
2757 cond_skip_newlines ()
2759 while ((cond_token = read_token (READ)) == '\n')
2761 if (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
2764 return (cond_token);
2767 #define COND_RETURN_ERROR() \
2768 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
2774 COND_COM *term, *tleft, *tright;
2777 /* Read a token. It can be a left paren, a `!', a unary operator, or a
2778 word that should be the first argument of a binary operator. Start by
2779 skipping newlines, since this is a compound command. */
2780 tok = cond_skip_newlines ();
2781 lineno = line_number;
2782 if (tok == COND_END)
2784 COND_RETURN_ERROR ();
2786 else if (tok == '(')
2788 term = cond_expr ();
2789 if (cond_token != ')')
2792 dispose_cond_node (term); /* ( */
2793 parser_error (lineno, "expected `)'");
2794 COND_RETURN_ERROR ();
2796 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
2797 (void)cond_skip_newlines ();
2799 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
2802 dispose_word (yylval.word); /* not needed */
2803 term = cond_term ();
2805 term->flags |= CMD_INVERT_RETURN;
2807 else if (tok == WORD && test_unop (yylval.word->word))
2810 tok = read_token (READ);
2813 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
2814 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
2819 parser_error (line_number, "unexpected argument to conditional unary operator");
2820 COND_RETURN_ERROR ();
2823 (void)cond_skip_newlines ();
2825 else if (tok == WORD) /* left argument to binary operator */
2828 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
2831 tok = read_token (READ);
2832 if (tok == WORD && test_binop (yylval.word->word))
2834 else if (tok == '<' || tok == '>')
2835 op = make_word_from_token (tok); /* ( */
2836 /* There should be a check before blindly accepting the `)' that we have
2837 seen the opening `('. */
2838 else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
2840 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
2841 the test command. Similarly for [[ x && expr ]] or
2842 [[ x || expr ]] or [[ (x) ]]. */
2843 op = make_word ("-n");
2844 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
2850 parser_error (line_number, "conditional binary operator expected");
2851 dispose_cond_node (tleft);
2852 COND_RETURN_ERROR ();
2856 tok = read_token (READ);
2859 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
2860 term = make_cond_node (COND_BINARY, op, tleft, tright);
2864 parser_error (line_number, "unexpected argument to conditional binary operator");
2865 dispose_cond_node (tleft);
2867 COND_RETURN_ERROR ();
2870 (void)cond_skip_newlines ();
2875 parser_error (line_number, "unexpected token `%c' in conditional command", tok);
2877 parser_error (line_number, "unexpected token %d in conditional command", tok);
2878 COND_RETURN_ERROR ();
2883 /* This is kind of bogus -- we slip a mini recursive-descent parser in
2884 here to handle the conditional statement syntax. */
2886 parse_cond_command ()
2890 cexp = cond_expr ();
2891 return (make_cond_command (cexp));
2896 read_token_word (character)
2899 /* The value for YYLVAL when a WORD is read. */
2900 WORD_DESC *the_word;
2902 /* Index into the token that we are building. */
2905 /* ALL_DIGITS becomes zero when we see a non-digit. */
2908 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
2911 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
2914 /* Non-zero means to ignore the value of the next character, and just
2915 to add it no matter what. */
2916 int pass_next_character;
2918 /* The current delimiting character. */
2920 int result, peek_char;
2921 char *ttok, *ttrans;
2922 int ttoklen, ttranslen;
2924 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
2925 token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
2928 all_digits = isdigit (character);
2929 dollar_present = quoted = pass_next_character = 0;
2933 if (character == EOF)
2936 if (pass_next_character)
2938 pass_next_character = 0;
2942 cd = current_delimiter (dstack);
2944 /* Handle backslashes. Quote lots of things when not inside of
2945 double-quotes, quote some things inside of double-quotes. */
2946 if (character == '\\')
2948 peek_char = shell_getc (0);
2950 /* Backslash-newline is ignored in all cases except
2951 when quoted with single quotes. */
2952 if (peek_char == '\n')
2955 goto next_character;
2959 shell_ungetc (peek_char);
2961 /* If the next character is to be quoted, note it now. */
2962 if (cd == 0 || cd == '`' ||
2963 (cd == '"' && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
2964 pass_next_character++;
2971 /* Parse a matched pair of quote characters. */
2972 if (shellquote (character))
2974 push_delimiter (dstack, character);
2975 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
2976 pop_delimiter (dstack);
2977 if (ttok == &matched_pair_error)
2978 return -1; /* Bail immediately. */
2979 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
2980 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
2981 token[token_index++] = character;
2982 strcpy (token + token_index, ttok);
2983 token_index += ttoklen;
2986 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
2988 goto next_character;
2991 #ifdef EXTENDED_GLOB
2992 /* Parse a ksh-style extended pattern matching specification. */
2993 if (extended_glob && PATTERN_CHAR (character))
2995 peek_char = shell_getc (1);
2996 if (peek_char == '(') /* ) */
2998 push_delimiter (dstack, peek_char);
2999 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3000 pop_delimiter (dstack);
3001 if (ttok == &matched_pair_error)
3002 return -1; /* Bail immediately. */
3003 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3005 TOKEN_DEFAULT_GROW_SIZE);
3006 token[token_index++] = character;
3007 token[token_index++] = peek_char;
3008 strcpy (token + token_index, ttok);
3009 token_index += ttoklen;
3011 dollar_present = all_digits = 0;
3012 goto next_character;
3015 shell_ungetc (peek_char);
3017 #endif /* EXTENDED_GLOB */
3019 /* If the delimiter character is not single quote, parse some of
3020 the shell expansions that must be read as a single word. */
3021 if (shellexp (character))
3023 peek_char = shell_getc (1);
3024 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
3025 if (peek_char == '(' ||
3026 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
3028 if (peek_char == '{') /* } */
3029 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
3030 else if (peek_char == '(') /* ) */
3032 /* XXX - push and pop the `(' as a delimiter for use by
3033 the command-oriented-history code. This way newlines
3034 appearing in the $(...) string get added to the
3035 history literally rather than causing a possibly-
3036 incorrect `;' to be added. ) */
3037 push_delimiter (dstack, peek_char);
3038 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3039 pop_delimiter (dstack);
3042 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3043 if (ttok == &matched_pair_error)
3044 return -1; /* Bail immediately. */
3045 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3047 TOKEN_DEFAULT_GROW_SIZE);
3048 token[token_index++] = character;
3049 token[token_index++] = peek_char;
3050 strcpy (token + token_index, ttok);
3051 token_index += ttoklen;
3055 goto next_character;
3057 /* This handles $'...' and $"..." new-style quoted strings. */
3058 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
3062 first_line = line_number;
3063 push_delimiter (dstack, peek_char);
3064 ttok = parse_matched_pair (peek_char, peek_char, peek_char,
3066 (peek_char == '\'') ? P_ALLOWESC : 0);
3067 pop_delimiter (dstack);
3068 if (ttok == &matched_pair_error)
3070 if (peek_char == '\'')
3072 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
3074 /* Insert the single quotes and correctly quote any
3075 embedded single quotes (allowed because P_ALLOWESC was
3076 passed to parse_matched_pair). */
3077 ttok = sh_single_quote (ttrans);
3080 ttranslen = strlen (ttrans);
3084 /* Try to locale-expand the converted string. */
3085 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
3088 /* Add the double quotes back */
3089 ttok = xmalloc (ttranslen + 3);
3091 strcpy (ttok + 1, ttrans);
3092 ttok[ttranslen + 1] = '"';
3093 ttok[ttranslen += 2] = '\0';
3098 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
3100 TOKEN_DEFAULT_GROW_SIZE);
3101 strcpy (token + token_index, ttrans);
3102 token_index += ttranslen;
3106 goto next_character;
3108 /* This could eventually be extended to recognize all of the
3109 shell's single-character parameter expansions, and set flags.*/
3110 else if (character == '$' && peek_char == '$')
3113 ttok[0] = ttok[1] = '$';
3115 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
3117 TOKEN_DEFAULT_GROW_SIZE);
3118 strcpy (token + token_index, ttok);
3123 goto next_character;
3126 shell_ungetc (peek_char);
3129 #if defined (ARRAY_VARS)
3130 /* Identify possible compound array variable assignment. */
3131 else if (character == '=' && token_index > 0)
3133 peek_char = shell_getc (1);
3134 if (peek_char == '(') /* ) */
3136 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3137 if (ttok == &matched_pair_error)
3138 return -1; /* Bail immediately. */
3139 if (ttok[0] == '(') /* ) */
3144 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3146 TOKEN_DEFAULT_GROW_SIZE);
3147 token[token_index++] = character;
3148 token[token_index++] = peek_char;
3149 strcpy (token + token_index, ttok);
3150 token_index += ttoklen;
3153 goto next_character;
3156 shell_ungetc (peek_char);
3160 /* When not parsing a multi-character word construct, shell meta-
3161 characters break words. */
3162 if (shellbreak (character))
3164 shell_ungetc (character);
3170 all_digits &= isdigit (character);
3171 dollar_present |= character == '$';
3173 if (character == CTLESC || character == CTLNUL)
3174 token[token_index++] = CTLESC;
3176 token[token_index++] = character;
3178 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
3179 TOKEN_DEFAULT_GROW_SIZE);
3182 if (character == '\n' && interactive &&
3183 (bash_input.type == st_stdin || bash_input.type == st_stream))
3186 /* We want to remove quoted newlines (that is, a \<newline> pair)
3187 unless we are within single quotes or pass_next_character is
3188 set (the shell equivalent of literal-next). */
3189 cd = current_delimiter (dstack);
3190 character = shell_getc (cd != '\'' && pass_next_character == 0);
3191 } /* end for (;;) */
3195 token[token_index] = '\0';
3197 /* Check to see what thing we should return. If the last_read_token
3198 is a `<', or a `&', or the character which ended this token is
3199 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
3200 Otherwise, it is just a word, and should be returned as such. */
3201 if (all_digits && (character == '<' || character == '>' ||
3202 last_read_token == LESS_AND ||
3203 last_read_token == GREATER_AND))
3205 yylval.number = atoi (token);
3209 /* Check for special case tokens. */
3210 result = special_case_tokens (token);
3215 /* Posix.2 does not allow reserved words to be aliased, so check for all
3216 of them, including special cases, before expanding the current token
3218 if (posixly_correct)
3219 CHECK_FOR_RESERVED_WORD (token);
3221 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
3222 inhibits alias expansion. */
3223 if (expand_aliases && quoted == 0)
3225 result = alias_expand_token (token);
3226 if (result == RE_READ_TOKEN)
3227 return (RE_READ_TOKEN);
3228 else if (result == NO_EXPANSION)
3229 parser_state &= ~PST_ALEXPNEXT;
3232 /* If not in Posix.2 mode, check for reserved words after alias
3234 if (posixly_correct == 0)
3236 CHECK_FOR_RESERVED_WORD (token);
3238 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
3239 the_word->word = xmalloc (1 + token_index);
3240 the_word->flags = 0;
3241 strcpy (the_word->word, token);
3243 the_word->flags |= W_HASDOLLAR;
3245 the_word->flags |= W_QUOTED;
3246 /* A word is an assignment if it appears at the beginning of a
3247 simple command, or after another assignment word. This is
3248 context-dependent, so it cannot be handled in the grammar. */
3249 if (assignment (token))
3251 the_word->flags |= W_ASSIGNMENT;
3252 /* Don't perform word splitting on assignment statements. */
3253 if (assignment_acceptable (last_read_token))
3254 the_word->flags |= W_NOSPLIT;
3257 yylval.word = the_word;
3259 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
3260 ? ASSIGNMENT_WORD : WORD;
3262 if (last_read_token == FUNCTION)
3264 parser_state |= PST_ALLOWOPNBRC;
3265 function_dstart = line_number;
3271 /* $'...' ANSI-C expand the portion of STRING between START and END and
3272 return the result. The result cannot be longer than the input string. */
3274 ansiexpand (string, start, end, lenp)
3276 int start, end, *lenp;
3281 temp = xmalloc (end - start + 1);
3282 for (tlen = 0, len = start; len < end; )
3283 temp[tlen++] = string[len++];
3288 t = ansicstr (temp, tlen, 0, (int *)NULL, lenp);
3300 /* Change a bash string into a string suitable for inclusion in a `po' file.
3301 This backslash-escapes `"' and `\' and changes newlines into \\\n"\n". */
3303 mk_msgstr (string, foundnlp)
3307 register int c, len;
3308 char *result, *r, *s;
3310 for (len = 0, s = string; s && *s; s++)
3313 if (*s == '"' || *s == '\\')
3315 else if (*s == '\n')
3319 r = result = xmalloc (len + 3);
3322 for (s = string; s && (c = *s); s++)
3324 if (c == '\n') /* <NL> -> \n"<NL>" */
3335 if (c == '"' || c == '\\')
3346 /* $"..." -- Translate the portion of STRING between START and END
3347 according to current locale using gettext (if available) and return
3348 the result. The caller will take care of leaving the quotes intact.
3349 The string will be left without the leading `$' by the caller.
3350 If translation is performed, the translated string will be double-quoted
3351 by the caller. The length of the translated string is returned in LENP,
3354 localeexpand (string, start, end, lineno, lenp)
3356 int start, end, lineno, *lenp;
3358 int len, tlen, foundnl;
3359 char *temp, *t, *t2;
3361 temp = xmalloc (end - start + 1);
3362 for (tlen = 0, len = start; len < end; )
3363 temp[tlen++] = string[len++];
3366 /* If we're just dumping translatable strings, don't do anything with the
3367 string itself, but if we're dumping in `po' file format, convert it into a form more palatable to gettext(3)
3368 and friends by quoting `"' and `\' with backslashes and converting <NL>
3369 into `\n"<NL>"'. If we find a newline in TEMP, we first output a
3370 `msgid ""' line and then the translated string; otherwise we output the
3371 `msgid' and translated string all on one line. */
3372 if (dump_translatable_strings)
3374 if (dump_po_strings)
3377 t = mk_msgstr (temp, &foundnl);
3378 t2 = foundnl ? "\"\"\n" : "";
3380 printf ("#: %s:%d\nmsgid %s%s\nmsgstr \"\"\n",
3381 (bash_input.name ? bash_input.name : "stdin"), lineno, t2, t);
3385 printf ("\"%s\"\n", temp);
3393 t = localetrans (temp, tlen, &len);
3407 /* Return 1 if TOKEN is a token that after being read would allow
3408 a reserved word to be seen, else 0. */
3410 reserved_word_acceptable (token)
3413 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
3414 token == '|' || token == '&' || token == '{' ||
3415 token == '}' || /* XXX */
3418 token == TIME || token == TIMEOPT ||
3425 token == SEMI_SEMI ||
3429 token == DONE || /* XXX these two are experimental */
3437 /* Return the index of TOKEN in the alist of reserved words, or -1 if
3438 TOKEN is not a shell reserved word. */
3440 find_reserved_word (token)
3444 for (i = 0; word_token_alist[i].word; i++)
3445 if (STREQ (token, word_token_alist[i].word))
3451 #if defined (READLINE)
3452 /* Called after each time readline is called. This insures that whatever
3453 the new prompt string is gets propagated to readline's local prompt
3456 reset_readline_prompt ()
3460 if (prompt_string_pointer)
3462 temp_prompt = (*prompt_string_pointer)
3463 ? decode_prompt_string (*prompt_string_pointer)
3466 if (temp_prompt == 0)
3468 temp_prompt = xmalloc (1);
3469 temp_prompt[0] = '\0';
3472 FREE (current_readline_prompt);
3473 current_readline_prompt = temp_prompt;
3476 #endif /* READLINE */
3479 #if defined (HISTORY)
3480 /* A list of tokens which can be followed by newlines, but not by
3481 semi-colons. When concatenating multiple lines of history, the
3482 newline separator for such tokens is replaced with a space. */
3483 static int no_semi_successors[] = {
3484 '\n', '{', '(', ')', ';', '&', '|',
3485 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
3489 /* If we are not within a delimited expression, try to be smart
3490 about which separators can be semi-colons and which must be
3491 newlines. Returns the string that should be added into the
3494 history_delimiting_chars ()
3498 if (dstack.delimiter_depth != 0)
3501 /* First, handle some special cases. */
3503 /* If we just read `()', assume it's a function definition, and don't
3504 add a semicolon. If the token before the `)' was not `(', and we're
3505 not in the midst of parsing a case statement, assume it's a
3506 parenthesized command and add the semicolon. */
3508 if (token_before_that == ')')
3510 if (two_tokens_ago == '(') /*)*/ /* function def */
3512 /* This does not work for subshells inside case statement
3513 command lists. It's a suboptimal solution. */
3514 else if (parser_state & PST_CASESTMT) /* case statement pattern */
3517 return "; "; /* (...) subshell */
3519 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
3520 return " "; /* function def using `function name' without `()' */
3522 else if (token_before_that == WORD && two_tokens_ago == FOR)
3524 /* Tricky. `for i\nin ...' should not have a semicolon, but
3525 `for i\ndo ...' should. We do what we can. */
3526 for (i = shell_input_line_index; whitespace(shell_input_line[i]); i++)
3528 if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
3533 for (i = 0; no_semi_successors[i]; i++)
3535 if (token_before_that == no_semi_successors[i])
3541 #endif /* HISTORY */
3543 /* Issue a prompt, or prepare to issue a prompt when the next character
3550 if (!interactive) /* XXX */
3553 ps1_prompt = get_string_value ("PS1");
3554 ps2_prompt = get_string_value ("PS2");
3556 if (!prompt_string_pointer)
3557 prompt_string_pointer = &ps1_prompt;
3559 temp_prompt = *prompt_string_pointer
3560 ? decode_prompt_string (*prompt_string_pointer)
3563 if (temp_prompt == 0)
3565 temp_prompt = xmalloc (1);
3566 temp_prompt[0] = '\0';
3569 current_prompt_string = *prompt_string_pointer;
3570 prompt_string_pointer = &ps2_prompt;
3572 #if defined (READLINE)
3573 if (!no_line_editing)
3575 FREE (current_readline_prompt);
3576 current_readline_prompt = temp_prompt;
3579 #endif /* READLINE */
3581 FREE (current_decoded_prompt);
3582 current_decoded_prompt = temp_prompt;
3587 get_current_prompt_level ()
3589 return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
3593 set_current_prompt_level (x)
3596 prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
3597 current_prompt_string = *prompt_string_pointer;
3603 fprintf (stderr, "%s", current_decoded_prompt);
3607 /* Return a string which will be printed as a prompt. The string
3608 may contain special characters which are decoded as follows:
3611 \e escape (ascii 033)
3612 \d the date in Day Mon Date format
3613 \h the hostname up to the first `.'
3615 \j the number of active jobs
3616 \l the basename of the shell's tty device name
3618 \s the name of the shell
3619 \t the time in 24-hour hh:mm:ss format
3620 \T the time in 12-hour hh:mm:ss format
3621 \@ the time in 12-hour am/pm format
3622 \v the version of bash (e.g., 2.00)
3623 \V the release of bash, version + patchlevel (e.g., 2.00.0)
3624 \w the current working directory
3625 \W the last element of $PWD
3627 \# the command number of this command
3628 \! the history number of this command
3629 \$ a $ or a # if you are root
3630 \nnn character code nnn in octal
3632 \[ begin a sequence of non-printing chars
3633 \] end a sequence of non-printing chars
3635 #define PROMPT_GROWTH 48
3637 decode_prompt_string (string)
3642 struct dstack save_dstack;
3643 #if defined (PROMPT_STRING_DECODE)
3644 int result_size, result_index;
3646 char *temp, octal_string[4];
3649 result = xmalloc (result_size = PROMPT_GROWTH);
3650 result[result_index = 0] = 0;
3651 temp = (char *)NULL;
3653 while (c = *string++)
3655 if (posixly_correct && c == '!')
3659 temp = savestring ("!");
3664 #if !defined (HISTORY)
3665 temp = savestring ("1");
3667 temp = itos (history_number ());
3668 #endif /* HISTORY */
3669 string--; /* add_string increments string again. */
3687 strncpy (octal_string, string, 3);
3688 octal_string[3] = '\0';
3690 n = read_octal (octal_string);
3693 if (n == CTLESC || n == CTLNUL)
3710 for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
3720 /* Make the current time/date into a string. */
3721 the_time = time (0);
3722 temp = ctime (&the_time);
3724 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
3725 temp[(c != 'd') ? 8 : 10] = '\0';
3727 /* quick and dirty conversion to 12-hour time */
3728 if (c == 'T' || c == '@')
3732 temp[5] = 'a'; /* am/pm format */
3743 temp[0] = (n / 10) + '0';
3744 temp[1] = (n % 10) + '0';
3746 if (n >= 0 && temp[5] == 'a')
3759 temp[0] = no_line_editing ? '\n' : '\r';
3760 temp[1] = no_line_editing ? '\0' : '\n';
3765 temp = base_pathname (shell_name);
3766 temp = savestring (temp);
3773 strcpy (temp, dist_version);
3775 sprintf (temp, "%s.%d", dist_version, patch_level);
3781 /* Use the value of PWD because it is much more efficient. */
3782 char t_string[PATH_MAX];
3785 temp = get_string_value ("PWD");
3789 if (getcwd (t_string, sizeof(t_string)) == 0)
3795 tlen = strlen (t_string);
3799 tlen = sizeof (t_string) - 1;
3800 strncpy (t_string, temp, tlen);
3802 t_string[tlen] = '\0';
3804 #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
3805 #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
3808 if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
3810 t = strrchr (t_string, '/');
3812 strcpy (t_string, t + 1);
3816 #undef DOUBLE_SLASH_ROOT
3818 /* polite_directory_format is guaranteed to return a string
3819 no longer than PATH_MAX - 1 characters. */
3820 strcpy (t_string, polite_directory_format (t_string));
3822 /* If we're going to be expanding the prompt string later,
3823 quote the directory name. */
3824 if (promptvars || posixly_correct)
3825 /* Make sure that expand_prompt_string is called with a
3826 second argument of Q_DOUBLE_QUOTE if we use this
3828 temp = sh_backslash_quote_for_double_quotes (t_string);
3830 temp = savestring (t_string);
3836 if (current_user.user_name == 0)
3837 get_current_user_info ();
3838 temp = savestring (current_user.user_name);
3843 temp = savestring (current_host_name);
3844 if (c == 'h' && (t = (char *)strchr (temp, '.')))
3849 temp = itos (current_command_number);
3853 #if !defined (HISTORY)
3854 temp = savestring ("1");
3856 temp = itos (history_number ());
3857 #endif /* HISTORY */
3861 t = temp = xmalloc (3);
3862 if ((promptvars || posixly_correct) && (current_user.euid != 0))
3864 *t++ = current_user.euid == 0 ? '#' : '$';
3869 temp = itos (count_all_jobs ());
3873 #if defined (HAVE_TTYNAME)
3874 temp = (char *)ttyname (fileno (stdin));
3875 t = temp ? base_pathname (temp) : "tty";
3876 temp = savestring (t);
3878 temp = savestring ("tty");
3879 #endif /* !HAVE_TTYNAME */
3882 #if defined (READLINE)
3887 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
3890 #endif /* READLINE */
3901 temp[0] = (c == 'a') ? '\07' : '\033';
3915 sub_append_string (temp, result, &result_index, &result_size);
3916 temp = (char *)NULL; /* Freed in sub_append_string (). */
3917 result[result_index] = '\0';
3923 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
3924 result[result_index++] = c;
3925 result[result_index] = '\0';
3928 #else /* !PROMPT_STRING_DECODE */
3929 result = savestring (string);
3930 #endif /* !PROMPT_STRING_DECODE */
3932 /* Save the delimiter stack and point `dstack' to temp space so any
3933 command substitutions in the prompt string won't result in screwing
3934 up the parser's quoting state. */
3935 save_dstack = dstack;
3936 dstack = temp_dstack;
3937 dstack.delimiter_depth = 0;
3939 /* Perform variable and parameter expansion and command substitution on
3940 the prompt string. */
3941 if (promptvars || posixly_correct)
3943 list = expand_prompt_string (result, Q_DOUBLE_QUOTES);
3945 result = string_list (list);
3946 dispose_words (list);
3950 t = dequote_string (result);
3955 dstack = save_dstack;
3960 /* Report a syntax error, and restart the parser. Call here for fatal
3965 report_syntax_error ((char *)NULL);
3970 /* Report a syntax error with line numbers, etc.
3971 Call here for recoverable errors. If you have a message to print,
3972 then place it in MESSAGE, otherwise pass NULL and this will figure
3973 out an appropriate message for you. */
3975 report_syntax_error (message)
3984 parser_error (line_number, "%s", message);
3985 if (interactive && EOF_Reached)
3987 last_command_exit_value = EX_USAGE;
3991 /* If the line of input we're reading is not null, try to find the
3992 objectionable token. */
3993 if (shell_input_line && *shell_input_line)
3995 t = shell_input_line;
3996 i = shell_input_line_index;
3999 if (i && t[i] == '\0')
4002 while (i && (whitespace (t[i]) || t[i] == '\n'))
4008 while (i && (member (t[i], " \n\t;|&") == 0))
4011 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4014 /* Print the offending token. */
4015 if (token_end || (i == 0 && token_end == 0))
4018 msg = substring (t, i, token_end);
4019 else /* one-character token */
4026 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
4032 /* If not interactive, print the line containing the error. */
4033 if (interactive == 0)
4035 msg = savestring (shell_input_line);
4036 token_end = strlen (msg);
4037 while (token_end && msg[token_end - 1] == '\n')
4038 msg[--token_end] = '\0';
4040 parser_error (line_number, "`%s'", msg);
4046 msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
4047 parser_error (line_number, "%s", msg);
4048 /* When the shell is interactive, this file uses EOF_Reached
4049 only for error reporting. Other mechanisms are used to
4050 decide whether or not to exit. */
4051 if (interactive && EOF_Reached)
4054 last_command_exit_value = EX_USAGE;
4057 /* ??? Needed function. ??? We have to be able to discard the constructs
4058 created during parsing. In the case of error, we want to return
4059 allocated objects to the memory pool. In the case of no error, we want
4060 to throw away the information about where the allocated objects live.
4061 (dispose_command () will actually free the command. */
4063 discard_parser_constructs (error_p)
4068 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4070 /* A flag denoting whether or not ignoreeof is set. */
4073 /* The number of times that we have encountered an EOF character without
4074 another character intervening. When this gets above the limit, the
4075 shell terminates. */
4076 int eof_encountered = 0;
4078 /* The limit for eof_encountered. */
4079 int eof_encountered_limit = 10;
4081 /* If we have EOF as the only input unit, this user wants to leave
4082 the shell. If the shell is not interactive, then just leave.
4083 Otherwise, if ignoreeof is set, and we haven't done this the
4084 required number of times in a row, print a message. */
4086 handle_eof_input_unit ()
4090 /* shell.c may use this to decide whether or not to write out the
4091 history, among other things. We use it only for error reporting
4096 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4099 if (eof_encountered < eof_encountered_limit)
4101 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
4102 login_shell ? "logout" : "exit");
4104 /* Reset the prompt string to be $PS1. */
4105 prompt_string_pointer = (char **)NULL;
4107 last_read_token = current_token = '\n';
4112 /* In this case EOF should exit the shell. Do it now. */
4114 exit_builtin ((WORD_LIST *)NULL);
4118 /* We don't write history files, etc., for non-interactive shells. */
4123 static WORD_LIST parse_string_error;
4125 /* Take a string and run it through the shell parser, returning the
4126 resultant word list. Used by compound array assignment. */
4128 parse_string_to_word_list (s, whom)
4132 int tok, orig_line_number, orig_input_terminator;
4133 int orig_line_count;
4134 #if defined (HISTORY)
4135 int old_remember_on_history, old_history_expansion_inhibited;
4138 #if defined (HISTORY)
4139 old_remember_on_history = remember_on_history;
4140 # if defined (BANG_HISTORY)
4141 old_history_expansion_inhibited = history_expansion_inhibited;
4143 bash_history_disable ();
4146 orig_line_number = line_number;
4147 orig_line_count = current_command_line_count;
4148 orig_input_terminator = shell_input_line_terminator;
4151 last_read_token = '\n';
4152 current_command_line_count = 0;
4154 with_input_from_string (s, whom);
4155 wl = (WORD_LIST *)NULL;
4156 while ((tok = read_token (READ)) != yacc_EOF)
4158 if (tok == '\n' && *bash_input.location.string == '\0')
4160 if (tok == '\n') /* Allow newlines in compound assignments */
4162 if (tok != WORD && tok != ASSIGNMENT_WORD)
4164 line_number = orig_line_number + line_number - 1;
4165 yyerror (); /* does the right thing */
4168 wl = &parse_string_error;
4171 wl = make_word_list (yylval.word, wl);
4174 last_read_token = '\n';
4177 #if defined (HISTORY)
4178 remember_on_history = old_remember_on_history;
4179 # if defined (BANG_HISTORY)
4180 history_expansion_inhibited = old_history_expansion_inhibited;
4181 # endif /* BANG_HISTORY */
4182 #endif /* HISTORY */
4184 current_command_line_count = orig_line_count;
4185 shell_input_line_terminator = orig_input_terminator;
4187 if (wl == &parse_string_error)
4189 last_command_exit_value = EXECUTION_FAILURE;
4190 if (interactive_shell == 0 && posixly_correct)
4191 jump_to_top_level (FORCE_EOF);
4193 jump_to_top_level (DISCARD);
4196 return (REVERSE_LIST (wl, WORD_LIST *));
4198 #line 4199 "y.tab.c"
4199 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
4200 static int yygrowstack()
4206 if ((newsize = yystacksize) == 0)
4207 newsize = YYINITSTACKSIZE;
4208 else if (newsize >= YYMAXDEPTH)
4210 else if ((newsize *= 2) > YYMAXDEPTH)
4211 newsize = YYMAXDEPTH;
4213 newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
4214 (short *)malloc(newsize * sizeof *newss);
4219 newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
4220 (YYSTYPE *)malloc(newsize * sizeof *newvs);
4225 yystacksize = newsize;
4226 yysslim = yyss + newsize - 1;
4230 #define YYABORT goto yyabort
4231 #define YYREJECT goto yyabort
4232 #define YYACCEPT goto yyaccept
4233 #define YYERROR goto yyerrlab
4235 #ifndef YYPARSE_PARAM
4236 #if defined(__cplusplus) || __STDC__
4237 #define YYPARSE_PARAM_ARG void
4238 #define YYPARSE_PARAM_DECL
4239 #else /* ! ANSI-C/C++ */
4240 #define YYPARSE_PARAM_ARG
4241 #define YYPARSE_PARAM_DECL
4242 #endif /* ANSI-C/C++ */
4243 #else /* YYPARSE_PARAM */
4244 #ifndef YYPARSE_PARAM_TYPE
4245 #define YYPARSE_PARAM_TYPE void *
4247 #if defined(__cplusplus) || __STDC__
4248 #define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM
4249 #define YYPARSE_PARAM_DECL
4250 #else /* ! ANSI-C/C++ */
4251 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
4252 #define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM;
4253 #endif /* ANSI-C/C++ */
4254 #endif /* ! YYPARSE_PARAM */
4257 yyparse (YYPARSE_PARAM_ARG)
4260 register int yym, yyn, yystate;
4262 register const char *yys;
4264 if ((yys = getenv("YYDEBUG")))
4267 if (yyn >= '0' && yyn <= '9')
4268 yydebug = yyn - '0';
4276 if (yyss == NULL && yygrowstack()) goto yyoverflow;
4279 *yyssp = yystate = 0;
4282 if ((yyn = yydefred[yystate])) goto yyreduce;
4285 if ((yychar = yylex()) < 0) yychar = 0;
4290 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
4291 if (!yys) yys = "illegal-symbol";
4292 printf("%sdebug: state %d, reading %d (%s)\n",
4293 YYPREFIX, yystate, yychar, yys);
4297 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
4298 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
4302 printf("%sdebug: state %d, shifting to state %d\n",
4303 YYPREFIX, yystate, yytable[yyn]);
4305 if (yyssp >= yysslim && yygrowstack())
4309 *++yyssp = yystate = yytable[yyn];
4312 if (yyerrflag > 0) --yyerrflag;
4315 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
4316 yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
4321 if (yyerrflag) goto yyinrecovery;
4322 #if defined(lint) || defined(__GNUC__)
4326 yyerror("syntax error");
4327 #if defined(lint) || defined(__GNUC__)
4338 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
4339 yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
4343 printf("%sdebug: state %d, error recovery shifting\
4344 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
4346 if (yyssp >= yysslim && yygrowstack())
4350 *++yyssp = yystate = yytable[yyn];
4358 printf("%sdebug: error recovery discarding state %d\n",
4361 if (yyssp <= yyss) goto yyabort;
4369 if (yychar == 0) goto yyabort;
4374 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
4375 if (!yys) yys = "illegal-symbol";
4376 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
4377 YYPREFIX, yystate, yychar, yys);
4386 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
4387 YYPREFIX, yystate, yyn, yyrule[yyn]);
4390 yyval = yyvsp[1-yym];
4394 #line 241 "/usr/homes/chet/src/bash/src/parse.y"
4396 /* Case of regular command. Discard the error
4397 safety net,and return the command just parsed. */
4398 global_command = yyvsp[-1].command;
4399 eof_encountered = 0;
4400 discard_parser_constructs (0);
4405 #line 250 "/usr/homes/chet/src/bash/src/parse.y"
4407 /* Case of regular command, but not a very
4408 interesting one. Return a NULL command. */
4409 global_command = (COMMAND *)NULL;
4414 #line 257 "/usr/homes/chet/src/bash/src/parse.y"
4416 /* Error during parsing. Return NULL command. */
4417 global_command = (COMMAND *)NULL;
4418 eof_encountered = 0;
4419 discard_parser_constructs (1);
4431 #line 272 "/usr/homes/chet/src/bash/src/parse.y"
4433 /* Case of EOF seen by itself. Do ignoreeof or
4435 global_command = (COMMAND *)NULL;
4436 handle_eof_input_unit ();
4441 #line 282 "/usr/homes/chet/src/bash/src/parse.y"
4442 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); }
4445 #line 284 "/usr/homes/chet/src/bash/src/parse.y"
4446 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); }
4449 #line 288 "/usr/homes/chet/src/bash/src/parse.y"
4451 redir.filename = yyvsp[0].word;
4452 yyval.redirect = make_redirection (1, r_output_direction, redir);
4456 #line 293 "/usr/homes/chet/src/bash/src/parse.y"
4458 redir.filename = yyvsp[0].word;
4459 yyval.redirect = make_redirection (0, r_input_direction, redir);
4463 #line 298 "/usr/homes/chet/src/bash/src/parse.y"
4465 redir.filename = yyvsp[0].word;
4466 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
4470 #line 303 "/usr/homes/chet/src/bash/src/parse.y"
4472 redir.filename = yyvsp[0].word;
4473 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
4477 #line 308 "/usr/homes/chet/src/bash/src/parse.y"
4479 redir.filename = yyvsp[0].word;
4480 yyval.redirect = make_redirection (1, r_appending_to, redir);
4484 #line 313 "/usr/homes/chet/src/bash/src/parse.y"
4486 redir.filename = yyvsp[0].word;
4487 yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
4491 #line 318 "/usr/homes/chet/src/bash/src/parse.y"
4493 redir.filename = yyvsp[0].word;
4494 yyval.redirect = make_redirection (0, r_reading_until, redir);
4495 redir_stack[need_here_doc++] = yyval.redirect;
4499 #line 324 "/usr/homes/chet/src/bash/src/parse.y"
4501 redir.filename = yyvsp[0].word;
4502 yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, redir);
4503 redir_stack[need_here_doc++] = yyval.redirect;
4507 #line 330 "/usr/homes/chet/src/bash/src/parse.y"
4509 redir.dest = yyvsp[0].number;
4510 yyval.redirect = make_redirection (0, r_duplicating_input, redir);
4514 #line 335 "/usr/homes/chet/src/bash/src/parse.y"
4516 redir.dest = yyvsp[0].number;
4517 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
4521 #line 340 "/usr/homes/chet/src/bash/src/parse.y"
4523 redir.dest = yyvsp[0].number;
4524 yyval.redirect = make_redirection (1, r_duplicating_output, redir);
4528 #line 345 "/usr/homes/chet/src/bash/src/parse.y"
4530 redir.dest = yyvsp[0].number;
4531 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
4535 #line 350 "/usr/homes/chet/src/bash/src/parse.y"
4537 redir.filename = yyvsp[0].word;
4538 yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
4542 #line 355 "/usr/homes/chet/src/bash/src/parse.y"
4544 redir.filename = yyvsp[0].word;
4545 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
4549 #line 360 "/usr/homes/chet/src/bash/src/parse.y"
4551 redir.filename = yyvsp[0].word;
4552 yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
4556 #line 365 "/usr/homes/chet/src/bash/src/parse.y"
4558 redir.filename = yyvsp[0].word;
4559 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
4563 #line 370 "/usr/homes/chet/src/bash/src/parse.y"
4565 redir.filename = yyvsp[0].word;
4566 yyval.redirect = make_redirection
4567 (0, r_deblank_reading_until, redir);
4568 redir_stack[need_here_doc++] = yyval.redirect;
4572 #line 377 "/usr/homes/chet/src/bash/src/parse.y"
4574 redir.filename = yyvsp[0].word;
4575 yyval.redirect = make_redirection
4576 (yyvsp[-2].number, r_deblank_reading_until, redir);
4577 redir_stack[need_here_doc++] = yyval.redirect;
4581 #line 384 "/usr/homes/chet/src/bash/src/parse.y"
4584 yyval.redirect = make_redirection (1, r_close_this, redir);
4588 #line 389 "/usr/homes/chet/src/bash/src/parse.y"
4591 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
4595 #line 394 "/usr/homes/chet/src/bash/src/parse.y"
4598 yyval.redirect = make_redirection (0, r_close_this, redir);
4602 #line 399 "/usr/homes/chet/src/bash/src/parse.y"
4605 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
4609 #line 404 "/usr/homes/chet/src/bash/src/parse.y"
4611 redir.filename = yyvsp[0].word;
4612 yyval.redirect = make_redirection (1, r_err_and_out, redir);
4616 #line 409 "/usr/homes/chet/src/bash/src/parse.y"
4618 redir.filename = yyvsp[0].word;
4619 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
4623 #line 414 "/usr/homes/chet/src/bash/src/parse.y"
4625 redir.filename = yyvsp[0].word;
4626 yyval.redirect = make_redirection (0, r_input_output, redir);
4630 #line 419 "/usr/homes/chet/src/bash/src/parse.y"
4632 redir.filename = yyvsp[0].word;
4633 yyval.redirect = make_redirection (1, r_output_force, redir);
4637 #line 424 "/usr/homes/chet/src/bash/src/parse.y"
4639 redir.filename = yyvsp[0].word;
4640 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
4644 #line 431 "/usr/homes/chet/src/bash/src/parse.y"
4645 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; }
4648 #line 433 "/usr/homes/chet/src/bash/src/parse.y"
4649 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; }
4652 #line 435 "/usr/homes/chet/src/bash/src/parse.y"
4653 { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; }
4656 #line 439 "/usr/homes/chet/src/bash/src/parse.y"
4658 yyval.redirect = yyvsp[0].redirect;
4662 #line 443 "/usr/homes/chet/src/bash/src/parse.y"
4664 register REDIRECT *t;
4666 for (t = yyvsp[-1].redirect; t->next; t = t->next)
4668 t->next = yyvsp[0].redirect;
4669 yyval.redirect = yyvsp[-1].redirect;
4673 #line 454 "/usr/homes/chet/src/bash/src/parse.y"
4674 { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); }
4677 #line 456 "/usr/homes/chet/src/bash/src/parse.y"
4678 { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); }
4681 #line 460 "/usr/homes/chet/src/bash/src/parse.y"
4682 { yyval.command = clean_simple_command (yyvsp[0].command); }
4685 #line 462 "/usr/homes/chet/src/bash/src/parse.y"
4686 { yyval.command = yyvsp[0].command; }
4689 #line 464 "/usr/homes/chet/src/bash/src/parse.y"
4693 tc = yyvsp[-1].command;
4696 register REDIRECT *t;
4697 for (t = tc->redirects; t->next; t = t->next)
4699 t->next = yyvsp[0].redirect;
4702 tc->redirects = yyvsp[0].redirect;
4703 yyval.command = yyvsp[-1].command;
4707 #line 480 "/usr/homes/chet/src/bash/src/parse.y"
4708 { yyval.command = yyvsp[0].command; }
4711 #line 484 "/usr/homes/chet/src/bash/src/parse.y"
4712 { yyval.command = yyvsp[0].command; }
4715 #line 486 "/usr/homes/chet/src/bash/src/parse.y"
4716 { yyval.command = yyvsp[0].command; }
4719 #line 488 "/usr/homes/chet/src/bash/src/parse.y"
4720 { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); }
4723 #line 490 "/usr/homes/chet/src/bash/src/parse.y"
4724 { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); }
4727 #line 492 "/usr/homes/chet/src/bash/src/parse.y"
4728 { yyval.command = yyvsp[0].command; }
4731 #line 494 "/usr/homes/chet/src/bash/src/parse.y"
4732 { yyval.command = yyvsp[0].command; }
4735 #line 496 "/usr/homes/chet/src/bash/src/parse.y"
4736 { yyval.command = yyvsp[0].command; }
4739 #line 498 "/usr/homes/chet/src/bash/src/parse.y"
4740 { yyval.command = yyvsp[0].command; }
4743 #line 500 "/usr/homes/chet/src/bash/src/parse.y"
4744 { yyval.command = yyvsp[0].command; }
4747 #line 502 "/usr/homes/chet/src/bash/src/parse.y"
4748 { yyval.command = yyvsp[0].command; }
4751 #line 504 "/usr/homes/chet/src/bash/src/parse.y"
4752 { yyval.command = yyvsp[0].command; }
4755 #line 508 "/usr/homes/chet/src/bash/src/parse.y"
4756 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); }
4759 #line 510 "/usr/homes/chet/src/bash/src/parse.y"
4760 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); }
4763 #line 512 "/usr/homes/chet/src/bash/src/parse.y"
4764 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); }
4767 #line 514 "/usr/homes/chet/src/bash/src/parse.y"
4768 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); }
4771 #line 516 "/usr/homes/chet/src/bash/src/parse.y"
4772 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); }
4775 #line 518 "/usr/homes/chet/src/bash/src/parse.y"
4776 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); }
4779 #line 522 "/usr/homes/chet/src/bash/src/parse.y"
4780 { yyval.command = make_arith_for_command (yyvsp[-5].word_list, yyvsp[-1].command, arith_for_lineno); }
4783 #line 524 "/usr/homes/chet/src/bash/src/parse.y"
4784 { yyval.command = make_arith_for_command (yyvsp[-5].word_list, yyvsp[-1].command, arith_for_lineno); }
4787 #line 526 "/usr/homes/chet/src/bash/src/parse.y"
4788 { yyval.command = make_arith_for_command (yyvsp[-3].word_list, yyvsp[-1].command, arith_for_lineno); }
4791 #line 528 "/usr/homes/chet/src/bash/src/parse.y"
4792 { yyval.command = make_arith_for_command (yyvsp[-3].word_list, yyvsp[-1].command, arith_for_lineno); }
4795 #line 532 "/usr/homes/chet/src/bash/src/parse.y"
4797 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
4801 #line 536 "/usr/homes/chet/src/bash/src/parse.y"
4803 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command);
4807 #line 540 "/usr/homes/chet/src/bash/src/parse.y"
4809 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
4813 #line 544 "/usr/homes/chet/src/bash/src/parse.y"
4815 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
4819 #line 548 "/usr/homes/chet/src/bash/src/parse.y"
4821 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
4825 #line 552 "/usr/homes/chet/src/bash/src/parse.y"
4827 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
4831 #line 558 "/usr/homes/chet/src/bash/src/parse.y"
4832 { yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL); }
4835 #line 560 "/usr/homes/chet/src/bash/src/parse.y"
4836 { yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern); }
4839 #line 562 "/usr/homes/chet/src/bash/src/parse.y"
4840 { yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern); }
4843 #line 566 "/usr/homes/chet/src/bash/src/parse.y"
4844 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); }
4847 #line 569 "/usr/homes/chet/src/bash/src/parse.y"
4848 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); }
4851 #line 572 "/usr/homes/chet/src/bash/src/parse.y"
4852 { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command, function_dstart, function_bstart); }
4855 #line 577 "/usr/homes/chet/src/bash/src/parse.y"
4856 { yyval.command = yyvsp[0].command; }
4859 #line 579 "/usr/homes/chet/src/bash/src/parse.y"
4863 tc = yyvsp[-1].command;
4864 /* According to Posix.2 3.9.5, redirections
4865 specified after the body of a function should
4866 be attached to the function and performed when
4867 the function is executed, not as part of the
4868 function definition command. */
4869 /* XXX - I don't think it matters, but we might
4870 want to change this in the future to avoid
4871 problems differentiating between a function
4872 definition with a redirection and a function
4873 definition containing a single command with a
4874 redirection. The two are semantically equivalent,
4875 though -- the only difference is in how the
4876 command printing code displays the redirections. */
4879 register REDIRECT *t;
4880 for (t = tc->redirects; t->next; t = t->next)
4882 t->next = yyvsp[0].redirect;
4885 tc->redirects = yyvsp[0].redirect;
4886 yyval.command = yyvsp[-1].command;
4890 #line 610 "/usr/homes/chet/src/bash/src/parse.y"
4892 yyval.command = make_subshell_command (yyvsp[-1].command);
4893 yyval.command->flags |= CMD_WANT_SUBSHELL;
4897 #line 617 "/usr/homes/chet/src/bash/src/parse.y"
4898 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); }
4901 #line 619 "/usr/homes/chet/src/bash/src/parse.y"
4902 { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); }
4905 #line 621 "/usr/homes/chet/src/bash/src/parse.y"
4906 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); }
4909 #line 626 "/usr/homes/chet/src/bash/src/parse.y"
4910 { yyval.command = make_group_command (yyvsp[-1].command); }
4913 #line 630 "/usr/homes/chet/src/bash/src/parse.y"
4914 { yyval.command = make_arith_command (yyvsp[0].word_list); }
4917 #line 634 "/usr/homes/chet/src/bash/src/parse.y"
4918 { yyval.command = yyvsp[-1].command; }
4921 #line 638 "/usr/homes/chet/src/bash/src/parse.y"
4922 { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); }
4925 #line 640 "/usr/homes/chet/src/bash/src/parse.y"
4926 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); }
4929 #line 642 "/usr/homes/chet/src/bash/src/parse.y"
4930 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); }
4933 #line 647 "/usr/homes/chet/src/bash/src/parse.y"
4934 { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; }
4937 #line 651 "/usr/homes/chet/src/bash/src/parse.y"
4938 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); }
4941 #line 653 "/usr/homes/chet/src/bash/src/parse.y"
4942 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); }
4945 #line 655 "/usr/homes/chet/src/bash/src/parse.y"
4946 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); }
4949 #line 657 "/usr/homes/chet/src/bash/src/parse.y"
4950 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); }
4953 #line 662 "/usr/homes/chet/src/bash/src/parse.y"
4954 { yyvsp[-1].pattern->next = yyvsp[-2].pattern; yyval.pattern = yyvsp[-1].pattern; }
4957 #line 666 "/usr/homes/chet/src/bash/src/parse.y"
4958 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); }
4961 #line 668 "/usr/homes/chet/src/bash/src/parse.y"
4962 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); }
4965 #line 677 "/usr/homes/chet/src/bash/src/parse.y"
4967 yyval.command = yyvsp[0].command;
4969 gather_here_documents ();
4973 #line 686 "/usr/homes/chet/src/bash/src/parse.y"
4975 yyval.command = yyvsp[0].command;
4979 #line 693 "/usr/homes/chet/src/bash/src/parse.y"
4981 if (yyvsp[-2].command->type == cm_connection)
4982 yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
4984 yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
4988 #line 704 "/usr/homes/chet/src/bash/src/parse.y"
4989 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); }
4992 #line 706 "/usr/homes/chet/src/bash/src/parse.y"
4993 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); }
4996 #line 708 "/usr/homes/chet/src/bash/src/parse.y"
4998 if (yyvsp[-3].command->type == cm_connection)
4999 yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
5001 yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
5005 #line 715 "/usr/homes/chet/src/bash/src/parse.y"
5006 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); }
5009 #line 717 "/usr/homes/chet/src/bash/src/parse.y"
5010 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); }
5013 #line 719 "/usr/homes/chet/src/bash/src/parse.y"
5014 { yyval.command = yyvsp[0].command; }
5017 #line 738 "/usr/homes/chet/src/bash/src/parse.y"
5019 yyval.command = yyvsp[0].command;
5021 gather_here_documents ();
5025 #line 744 "/usr/homes/chet/src/bash/src/parse.y"
5027 if (yyvsp[-1].command->type == cm_connection)
5028 yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
5030 yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
5032 gather_here_documents ();
5036 #line 753 "/usr/homes/chet/src/bash/src/parse.y"
5038 yyval.command = yyvsp[-1].command;
5040 gather_here_documents ();
5044 #line 761 "/usr/homes/chet/src/bash/src/parse.y"
5045 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); }
5048 #line 763 "/usr/homes/chet/src/bash/src/parse.y"
5049 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); }
5052 #line 765 "/usr/homes/chet/src/bash/src/parse.y"
5054 if (yyvsp[-2].command->type == cm_connection)
5055 yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
5057 yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
5061 #line 772 "/usr/homes/chet/src/bash/src/parse.y"
5062 { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); }
5065 #line 775 "/usr/homes/chet/src/bash/src/parse.y"
5066 { yyval.command = yyvsp[0].command; }
5069 #line 779 "/usr/homes/chet/src/bash/src/parse.y"
5070 { yyval.command = yyvsp[0].command; }
5073 #line 781 "/usr/homes/chet/src/bash/src/parse.y"
5075 yyvsp[0].command->flags |= CMD_INVERT_RETURN;
5076 yyval.command = yyvsp[0].command;
5080 #line 786 "/usr/homes/chet/src/bash/src/parse.y"
5082 yyvsp[0].command->flags |= yyvsp[-1].number;
5083 yyval.command = yyvsp[0].command;
5087 #line 791 "/usr/homes/chet/src/bash/src/parse.y"
5089 yyvsp[0].command->flags |= yyvsp[-2].number|CMD_INVERT_RETURN;
5090 yyval.command = yyvsp[0].command;
5094 #line 796 "/usr/homes/chet/src/bash/src/parse.y"
5096 yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
5097 yyval.command = yyvsp[0].command;
5101 #line 804 "/usr/homes/chet/src/bash/src/parse.y"
5102 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); }
5105 #line 806 "/usr/homes/chet/src/bash/src/parse.y"
5106 { yyval.command = yyvsp[0].command; }
5109 #line 810 "/usr/homes/chet/src/bash/src/parse.y"
5110 { yyval.number = CMD_TIME_PIPELINE; }
5113 #line 812 "/usr/homes/chet/src/bash/src/parse.y"
5114 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
5116 #line 5117 "y.tab.c"
5122 if (yystate == 0 && yym == 0)
5126 printf("%sdebug: after reduction, shifting from state 0 to\
5127 state %d\n", YYPREFIX, YYFINAL);
5134 if ((yychar = yylex()) < 0) yychar = 0;
5139 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
5140 if (!yys) yys = "illegal-symbol";
5141 printf("%sdebug: state %d, reading %d (%s)\n",
5142 YYPREFIX, YYFINAL, yychar, yys);
5146 if (yychar == 0) goto yyaccept;
5149 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
5150 yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
5151 yystate = yytable[yyn];
5153 yystate = yydgoto[yym];
5156 printf("%sdebug: after reduction, shifting from state %d \
5157 to state %d\n", YYPREFIX, *yyssp, yystate);
5159 if (yyssp >= yysslim && yygrowstack())
5167 yyerror("yacc stack overflow");