2 /* A Bison parser, made from /usr/homes/chet/src/bash/bash-2.01.1/parse.y
3 by GNU Bison version 1.25
6 #define YYBISON 1 /* Identify Bison output. */
27 #define ASSIGNMENT_WORD 277
31 #define GREATER_GREATER 281
34 #define GREATER_AND 284
36 #define LESS_LESS_MINUS 286
37 #define AND_GREATER 287
38 #define LESS_GREATER 288
39 #define GREATER_BAR 289
42 #line 21 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
46 #include "bashtypes.h"
49 #if defined (HAVE_UNISTD_H)
53 #if defined (HAVE_LOCALE_H)
66 #include "mailcheck.h"
67 #include "builtins/common.h"
68 #include "builtins/builtext.h"
70 #if defined (READLINE)
71 # include "bashline.h"
72 # include <readline/readline.h>
76 # include "bashhist.h"
77 # include <readline/history.h>
80 #if defined (JOB_CONTROL)
82 #endif /* JOB_CONTROL */
88 #if defined (PROMPT_STRING_DECODE)
89 #include <sys/param.h>
92 #endif /* PROMPT_STRING_DECODE */
94 #define RE_READ_TOKEN -99
95 #define NO_EXPANSION -100
99 extern int eof_encountered;
100 extern int no_line_editing, running_under_emacs;
101 extern int current_command_number;
102 extern int interactive, interactive_shell, login_shell;
103 extern int sourcelevel;
104 extern int posixly_correct;
105 extern int last_command_exit_value;
106 extern int interrupt_immediately;
107 extern char *shell_name, *current_host_name;
108 extern char *dist_version;
109 extern int patch_level;
110 extern int dump_translatable_strings;
111 extern Function *last_shell_builtin, *this_shell_builtin;
112 #if defined (BUFFERED_INPUT)
113 extern int bash_input_fd_changed;
116 /* **************************************************************** */
118 /* "Forward" declarations */
120 /* **************************************************************** */
122 static char *ansiexpand ();
123 static char *localeexpand ();
124 static int reserved_word_acceptable ();
125 static int read_token ();
127 static int parse_arith_cmd ();
128 static int read_token_word ();
129 static void discard_parser_constructs ();
131 static void report_syntax_error ();
132 static void handle_eof_input_unit ();
133 static void prompt_again ();
135 static void reset_readline_prompt ();
137 static void print_prompt ();
139 extern int yyerror ();
141 /* Default prompt strings */
142 char *primary_prompt = PPROMPT;
143 char *secondary_prompt = SPROMPT;
145 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
146 char *ps1_prompt, *ps2_prompt;
148 /* Handle on the current prompt string. Indirectly points through
149 ps1_ or ps2_prompt. */
150 char **prompt_string_pointer = (char **)NULL;
151 char *current_prompt_string;
153 /* Non-zero means we expand aliases in commands. */
154 int expand_aliases = 0;
156 /* If non-zero, the decoded prompt string undergoes parameter and
157 variable substitution, command substitution, arithmetic substitution,
158 string expansion, process substitution, and quote removal in
159 decode_prompt_string. */
162 /* The decoded prompt string. Used if READLINE is not defined or if
163 editing is turned off. Analogous to current_readline_prompt. */
164 static char *current_decoded_prompt;
166 /* The number of lines read from input while creating the current command. */
167 int current_command_line_count;
169 /* Variables to manage the task of reading here documents, because we need to
170 defer the reading until after a complete command has been collected. */
171 static REDIRECT *redir_stack[10];
174 /* Where shell input comes from. History expansion is performed on each
175 line when the shell is interactive. */
176 static char *shell_input_line = (char *)NULL;
177 static int shell_input_line_index;
178 static int shell_input_line_size; /* Amount allocated for shell_input_line. */
179 static int shell_input_line_len; /* strlen (shell_input_line) */
181 /* Either zero or EOF. */
182 static int shell_input_line_terminator;
184 /* The line number in a script on which a function definition starts. */
185 static int function_dstart;
187 /* The line number in a script on which a function body starts. */
188 static int function_bstart;
190 static REDIRECTEE redir;
192 #line 171 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
194 WORD_DESC *word; /* the word that we read. */
195 int number; /* the number that we read. */
196 WORD_LIST *word_list;
200 PATTERN_LIST *pattern;
213 #define YYFLAG -32768
216 #define YYTRANSLATE(x) ((unsigned)(x) <= 290 ? yytranslate[x] : 78)
218 static const char yytranslate[] = { 0,
219 2, 2, 2, 2, 2, 2, 2, 2, 2, 37,
220 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
221 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
222 2, 2, 2, 2, 2, 2, 2, 35, 2, 45,
223 46, 2, 2, 2, 42, 2, 2, 2, 2, 2,
224 2, 2, 2, 2, 2, 2, 2, 2, 36, 41,
225 2, 40, 2, 2, 2, 2, 2, 2, 2, 2,
226 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
227 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
228 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
229 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
230 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
231 2, 2, 43, 39, 44, 2, 2, 2, 2, 2,
232 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
233 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
234 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
235 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
236 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
237 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
238 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
239 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
240 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
241 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
242 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
243 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
244 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
245 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
246 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
247 26, 27, 28, 29, 30, 31, 32, 33, 34, 38
251 static const short yyprhs[] = { 0,
252 0, 3, 5, 8, 10, 12, 15, 18, 21, 25,
253 29, 32, 36, 39, 43, 46, 50, 53, 57, 60,
254 64, 67, 71, 74, 78, 81, 85, 88, 92, 95,
255 99, 102, 105, 109, 111, 113, 115, 117, 120, 122,
256 125, 127, 129, 132, 134, 136, 142, 148, 150, 152,
257 154, 156, 158, 165, 172, 180, 188, 199, 210, 217,
258 224, 232, 240, 251, 262, 269, 277, 284, 290, 297,
259 302, 306, 312, 320, 327, 331, 336, 343, 349, 351,
260 354, 359, 364, 370, 376, 379, 383, 385, 389, 392,
261 394, 397, 401, 405, 409, 414, 419, 424, 429, 434,
262 436, 438, 440, 442, 443, 446, 448, 451, 454, 459,
263 464, 468, 472, 474, 476, 479, 482, 486, 490, 495,
267 static const short yyrhs[] = { 73,
268 37, 0, 37, 0, 1, 37, 0, 38, 0, 21,
269 0, 48, 21, 0, 40, 21, 0, 41, 21, 0,
270 23, 40, 21, 0, 23, 41, 21, 0, 26, 21,
271 0, 23, 26, 21, 0, 27, 21, 0, 23, 27,
272 21, 0, 28, 23, 0, 23, 28, 23, 0, 29,
273 23, 0, 23, 29, 23, 0, 28, 21, 0, 23,
274 28, 21, 0, 29, 21, 0, 23, 29, 21, 0,
275 31, 21, 0, 23, 31, 21, 0, 29, 42, 0,
276 23, 29, 42, 0, 28, 42, 0, 23, 28, 42,
277 0, 32, 21, 0, 23, 33, 21, 0, 33, 21,
278 0, 34, 21, 0, 23, 34, 21, 0, 21, 0,
279 22, 0, 49, 0, 49, 0, 51, 49, 0, 50,
280 0, 52, 50, 0, 52, 0, 54, 0, 54, 51,
281 0, 55, 0, 57, 0, 12, 68, 14, 68, 15,
282 0, 13, 68, 14, 68, 15, 0, 56, 0, 60,
283 0, 59, 0, 61, 0, 58, 0, 10, 21, 72,
284 14, 68, 15, 0, 10, 21, 72, 43, 68, 44,
285 0, 10, 21, 36, 72, 14, 68, 15, 0, 10,
286 21, 36, 72, 43, 68, 44, 0, 10, 21, 72,
287 17, 48, 71, 72, 14, 68, 15, 0, 10, 21,
288 72, 17, 48, 71, 72, 43, 68, 44, 0, 11,
289 21, 72, 14, 67, 15, 0, 11, 21, 72, 43,
290 67, 44, 0, 11, 21, 36, 72, 14, 67, 15,
291 0, 11, 21, 36, 72, 43, 67, 44, 0, 11,
292 21, 72, 17, 48, 71, 72, 14, 67, 15, 0,
293 11, 21, 72, 17, 48, 71, 72, 43, 67, 44,
294 0, 8, 21, 72, 17, 72, 9, 0, 8, 21,
295 72, 17, 65, 72, 9, 0, 8, 21, 72, 17,
296 63, 9, 0, 21, 45, 46, 72, 61, 0, 16,
297 21, 45, 46, 72, 61, 0, 16, 21, 72, 61,
298 0, 45, 68, 46, 0, 3, 68, 4, 68, 7,
299 0, 3, 68, 4, 68, 5, 68, 7, 0, 3,
300 68, 4, 68, 62, 7, 0, 43, 67, 44, 0,
301 6, 68, 4, 68, 0, 6, 68, 4, 68, 5,
302 68, 0, 6, 68, 4, 68, 62, 0, 64, 0,
303 65, 64, 0, 72, 66, 46, 68, 0, 72, 66,
304 46, 72, 0, 72, 45, 66, 46, 68, 0, 72,
305 45, 66, 46, 72, 0, 64, 30, 0, 65, 64,
306 30, 0, 21, 0, 66, 39, 21, 0, 72, 69,
307 0, 67, 0, 72, 70, 0, 70, 37, 72, 0,
308 70, 35, 72, 0, 70, 36, 72, 0, 70, 24,
309 72, 70, 0, 70, 25, 72, 70, 0, 70, 35,
310 72, 70, 0, 70, 36, 72, 70, 0, 70, 37,
311 72, 70, 0, 75, 0, 37, 0, 36, 0, 38,
312 0, 0, 72, 37, 0, 74, 0, 74, 35, 0,
313 74, 36, 0, 74, 24, 72, 74, 0, 74, 25,
314 72, 74, 0, 74, 35, 74, 0, 74, 36, 74,
315 0, 75, 0, 76, 0, 18, 76, 0, 77, 76,
316 0, 77, 18, 76, 0, 18, 77, 76, 0, 76,
317 39, 72, 76, 0, 53, 0, 19, 0, 19, 20,
324 static const short yyrline[] = { 0,
325 214, 223, 230, 245, 255, 257, 261, 266, 271, 276,
326 281, 286, 291, 297, 303, 308, 313, 318, 323, 328,
327 333, 338, 343, 350, 357, 362, 367, 372, 377, 382,
328 387, 392, 397, 404, 406, 408, 412, 416, 427, 429,
329 433, 435, 437, 466, 468, 470, 472, 474, 476, 478,
330 480, 482, 486, 488, 490, 492, 494, 496, 500, 504,
331 508, 512, 516, 520, 526, 528, 530, 534, 538, 541,
332 545, 549, 551, 553, 558, 562, 564, 566, 570, 571,
333 575, 577, 579, 581, 585, 586, 590, 592, 601, 609,
334 610, 616, 617, 624, 628, 630, 632, 639, 641, 643,
335 647, 648, 649, 652, 653, 662, 668, 677, 685, 687,
336 689, 696, 699, 703, 705, 710, 715, 720, 727, 730,
342 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
344 static const char * const yytname[] = { "$","error","$undefined.","IF","THEN",
345 "ELSE","ELIF","FI","CASE","ESAC","FOR","SELECT","WHILE","UNTIL","DO","DONE",
346 "FUNCTION","IN","BANG","TIME","TIMEOPT","WORD","ASSIGNMENT_WORD","NUMBER","AND_AND",
347 "OR_OR","GREATER_GREATER","LESS_LESS","LESS_AND","GREATER_AND","SEMI_SEMI","LESS_LESS_MINUS",
348 "AND_GREATER","LESS_GREATER","GREATER_BAR","'&'","';'","'\\n'","yacc_EOF","'|'",
349 "'>'","'<'","'-'","'{'","'}'","'('","')'","inputunit","word_list","redirection",
350 "simple_command_element","redirection_list","simple_command","command","shell_command",
351 "for_command","select_command","case_command","function_def","subshell","if_command",
352 "group_command","elif_clause","case_clause","pattern_list","case_clause_sequence",
353 "pattern","list","compound_list","list0","list1","list_terminator","newline_list",
354 "simple_list","simple_list1","pipeline_command","pipeline","timespec", NULL
358 static const short yyr1[] = { 0,
359 47, 47, 47, 47, 48, 48, 49, 49, 49, 49,
360 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
361 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
362 49, 49, 49, 50, 50, 50, 51, 51, 52, 52,
363 53, 53, 53, 54, 54, 54, 54, 54, 54, 54,
364 54, 54, 55, 55, 55, 55, 55, 55, 56, 56,
365 56, 56, 56, 56, 57, 57, 57, 58, 58, 58,
366 59, 60, 60, 60, 61, 62, 62, 62, 63, 63,
367 64, 64, 64, 64, 65, 65, 66, 66, 67, 68,
368 68, 69, 69, 69, 70, 70, 70, 70, 70, 70,
369 71, 71, 71, 72, 72, 73, 73, 73, 74, 74,
370 74, 74, 74, 75, 75, 75, 75, 75, 76, 76,
374 static const short yyr2[] = { 0,
375 2, 1, 2, 1, 1, 2, 2, 2, 3, 3,
376 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
377 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
378 2, 2, 3, 1, 1, 1, 1, 2, 1, 2,
379 1, 1, 2, 1, 1, 5, 5, 1, 1, 1,
380 1, 1, 6, 6, 7, 7, 10, 10, 6, 6,
381 7, 7, 10, 10, 6, 7, 6, 5, 6, 4,
382 3, 5, 7, 6, 3, 4, 6, 5, 1, 2,
383 4, 4, 5, 5, 2, 3, 1, 3, 2, 1,
384 2, 3, 3, 3, 4, 4, 4, 4, 4, 1,
385 1, 1, 1, 0, 2, 1, 2, 2, 4, 4,
386 3, 3, 1, 1, 2, 2, 3, 3, 4, 1,
390 static const short yydefact[] = { 0,
391 0, 104, 0, 0, 0, 104, 104, 0, 0, 121,
392 34, 35, 0, 0, 0, 0, 0, 0, 0, 0,
393 0, 2, 4, 0, 0, 104, 104, 36, 39, 41,
394 120, 42, 44, 48, 45, 52, 50, 49, 51, 0,
395 106, 113, 114, 0, 3, 90, 0, 0, 104, 104,
396 104, 0, 0, 104, 115, 0, 122, 0, 0, 0,
397 0, 0, 0, 0, 0, 0, 0, 11, 13, 19,
398 15, 27, 21, 17, 25, 23, 29, 31, 32, 7,
399 8, 0, 0, 0, 34, 40, 37, 43, 1, 104,
400 104, 107, 108, 104, 0, 116, 104, 105, 89, 91,
401 100, 0, 104, 0, 104, 0, 104, 104, 0, 0,
402 118, 104, 12, 14, 20, 16, 28, 22, 18, 26,
403 24, 30, 33, 9, 10, 75, 0, 71, 38, 0,
404 0, 111, 112, 0, 117, 0, 104, 104, 104, 104,
405 104, 104, 0, 104, 0, 104, 0, 104, 0, 104,
406 0, 0, 104, 70, 0, 109, 110, 0, 0, 119,
407 104, 104, 72, 0, 0, 0, 93, 94, 92, 0,
408 79, 104, 0, 104, 104, 0, 5, 0, 0, 104,
409 104, 0, 0, 0, 46, 47, 0, 68, 0, 0,
410 74, 95, 96, 97, 98, 99, 67, 85, 80, 0,
411 65, 87, 0, 0, 0, 0, 53, 6, 102, 101,
412 103, 104, 54, 0, 0, 59, 104, 60, 69, 73,
413 104, 104, 104, 104, 86, 66, 0, 0, 104, 55,
414 56, 0, 61, 62, 0, 76, 0, 0, 0, 104,
415 88, 81, 82, 104, 104, 104, 104, 104, 78, 83,
416 84, 0, 0, 0, 0, 77, 57, 58, 63, 64,
420 static const short yydefgoto[] = { 261,
421 178, 28, 29, 88, 30, 31, 32, 33, 34, 35,
422 36, 37, 38, 39, 164, 170, 171, 172, 204, 46,
423 47, 99, 100, 212, 48, 40, 132, 101, 43, 44
426 static const short yypact[] = { 240,
427 -25,-32768, -4, 41, 44,-32768,-32768, 49, 348, 0,
428 -31,-32768, 476, 53, 55, 3, 29, 61, 63, 66,
429 71,-32768,-32768, 76, 79,-32768,-32768,-32768,-32768, 165,
430 -32768, 120,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -12,
431 89,-32768, 12, 384,-32768,-32768, 99, 276,-32768, 93,
432 103, 98, 143, 126, 12, 456,-32768, 127, 151, 153,
433 35, 43, 154, 155, 159, 160, 161,-32768,-32768,-32768,
434 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
435 -32768, 140, 276, 137,-32768,-32768,-32768, 120,-32768,-32768,
436 -32768, 312, 312,-32768, 456, 12,-32768,-32768,-32768, 86,
437 -32768, 38,-32768, -1,-32768, 16,-32768,-32768, 157, -28,
438 12,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
439 -32768,-32768,-32768,-32768,-32768,-32768, 86,-32768,-32768, 276,
440 276, 15, 15, 420, 12, 128,-32768,-32768,-32768,-32768,
441 -32768,-32768, 4,-32768, 164,-32768, 17,-32768, 164,-32768,
442 174, 189,-32768,-32768, -28,-32768,-32768, 312, 312, 12,
443 -32768,-32768,-32768, 201, 276, 276, 276, 276, 276, 200,
444 180,-32768, -2,-32768,-32768, 196,-32768, 57, 168,-32768,
445 -32768, 198, 57, 170,-32768,-32768, -28,-32768, 209, 213,
446 -32768,-32768,-32768, 142, 142, 142,-32768,-32768, 190, 1,
447 -32768,-32768, 205, 40, 204, 177,-32768,-32768,-32768,-32768,
448 -32768,-32768,-32768, 207, 183,-32768,-32768,-32768,-32768,-32768,
449 -32768,-32768,-32768,-32768,-32768,-32768, 50, 210,-32768,-32768,
450 -32768, 20,-32768,-32768, 30, 139, 276, 276, 276,-32768,
451 -32768,-32768, 276,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
452 276, 215, 188, 218, 191,-32768,-32768,-32768,-32768,-32768,
456 static const short yypgoto[] = {-32768,
457 91, -27, 214,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
458 -32768,-32768,-32768, -107, 9,-32768, 74,-32768, 46, -18,
459 -6,-32768, -60, 64, -22,-32768, 11, 6, -7, 245
466 static const short yytable[] = { 52,
467 53, 55, 154, 83, 87, 42, 201, 82, 98, 226,
468 41, 45, 144, 58, 26, 145, 49, 174, 202, 57,
469 84, 202, 127, 70, 89, 71, 102, 104, 106, 148,
470 180, 110, 149, 244, 98, 98, 96, 98, 90, 91,
471 98, 146, 203, 246, 72, 203, 175, 188, 111, 73,
472 94, 74, 98, 98, 142, 115, 98, 116, 150, 181,
473 129, 50, 245, 118, 51, 119, 98, 130, 131, 54,
474 75, 134, 247, 68, 98, 69, 117, 208, 228, 219,
475 143, 76, 147, 77, 120, 229, 78, 135, 228, 155,
476 136, 79, 209, 210, 211, 240, 80, 42, 42, 81,
477 151, 152, 97, 133, 192, 193, 194, 195, 196, 137,
478 138, 107, 90, 91, 165, 166, 167, 168, 169, 173,
479 139, 140, 141, 92, 93, 83, 160, 83, 103, 182,
480 187, 184, 161, 162, 163, 42, 42, 176, 105, 179,
481 156, 157, 13, 248, 162, 14, 15, 16, 17, 200,
482 18, 19, 20, 21, 189, 190, 108, 83, 83, 24,
483 25, 214, 215, 42, 42, 137, 138, 205, 206, 133,
484 109, 113, 112, 114, 121, 122, 194, 195, 196, 123,
485 124, 125, 128, 126, 177, 85, 12, 13, 185, 232,
486 14, 15, 16, 17, 235, 18, 19, 20, 21, 237,
487 238, 239, 153, 186, 24, 25, 243, 191, 197, 198,
488 207, 213, 216, 218, 236, 220, 221, 251, 230, 225,
489 231, 233, 242, 83, 83, 202, 234, 254, 255, 257,
490 241, 258, 259, 250, 260, 262, 263, 252, 253, 183,
491 1, 256, 2, 86, 249, 199, 217, 3, 227, 4,
492 5, 6, 7, 56, 0, 8, 0, 9, 10, 0,
493 11, 12, 13, 0, 0, 14, 15, 16, 17, 0,
494 18, 19, 20, 21, 0, 0, 22, 23, 2, 24,
495 25, 0, 26, 3, 27, 4, 5, 6, 7, 0,
496 0, 8, 0, 9, 10, 0, 11, 12, 13, 0,
497 0, 14, 15, 16, 17, 0, 18, 19, 20, 21,
498 0, 0, 98, 0, 2, 24, 25, 0, 26, 3,
499 27, 4, 5, 6, 7, 0, 0, 8, 0, 9,
500 10, 0, 11, 12, 13, 0, 0, 14, 15, 16,
501 17, 0, 18, 19, 20, 21, 0, 0, 0, 0,
502 2, 24, 25, 0, 26, 3, 27, 4, 5, 6,
503 7, 0, 0, 8, 0, 0, 10, 0, 11, 12,
504 13, 0, 0, 14, 15, 16, 17, 0, 18, 19,
505 20, 21, 0, 0, 0, 0, 2, 24, 25, 0,
506 26, 3, 27, 4, 5, 6, 7, 0, 0, 8,
507 0, 95, 0, 0, 11, 12, 13, 0, 0, 14,
508 15, 16, 17, 0, 18, 19, 20, 21, 0, 0,
509 0, 0, 2, 24, 25, 0, 26, 3, 27, 4,
510 5, 6, 7, 0, 0, 8, 0, 0, 0, 0,
511 11, 12, 13, 0, 0, 14, 15, 16, 17, 0,
512 18, 19, 20, 21, 0, 0, 98, 0, 2, 24,
513 25, 0, 26, 3, 27, 4, 5, 6, 7, 0,
514 0, 8, 0, 0, 0, 0, 11, 12, 13, 0,
515 0, 14, 15, 16, 17, 0, 18, 19, 20, 21,
516 0, 0, 0, 0, 0, 24, 25, 0, 26, 0,
517 27, 59, 60, 61, 62, 0, 63, 0, 64, 65,
518 0, 0, 0, 0, 0, 66, 67
521 static const short yycheck[] = { 6,
522 7, 9, 110, 26, 32, 0, 9, 26, 37, 9,
523 0, 37, 14, 45, 43, 17, 21, 14, 21, 20,
524 27, 21, 83, 21, 37, 23, 49, 50, 51, 14,
525 14, 54, 17, 14, 37, 37, 44, 37, 24, 25,
526 37, 43, 45, 14, 42, 45, 43, 155, 56, 21,
527 39, 23, 37, 37, 17, 21, 37, 23, 43, 43,
528 88, 21, 43, 21, 21, 23, 37, 90, 91, 21,
529 42, 94, 43, 21, 37, 21, 42, 21, 39, 187,
530 103, 21, 105, 21, 42, 46, 21, 95, 39, 112,
531 97, 21, 36, 37, 38, 46, 21, 92, 93, 21,
532 107, 108, 4, 93, 165, 166, 167, 168, 169, 24,
533 25, 14, 24, 25, 137, 138, 139, 140, 141, 142,
534 35, 36, 37, 35, 36, 148, 134, 150, 36, 148,
535 153, 150, 5, 6, 7, 130, 131, 144, 36, 146,
536 130, 131, 23, 5, 6, 26, 27, 28, 29, 172,
537 31, 32, 33, 34, 161, 162, 14, 180, 181, 40,
538 41, 180, 181, 158, 159, 24, 25, 174, 175, 159,
539 45, 21, 46, 21, 21, 21, 237, 238, 239, 21,
540 21, 21, 46, 44, 21, 21, 22, 23, 15, 212,
541 26, 27, 28, 29, 217, 31, 32, 33, 34, 222,
542 223, 224, 46, 15, 40, 41, 229, 7, 9, 30,
543 15, 44, 15, 44, 221, 7, 4, 240, 15, 30,
544 44, 15, 229, 246, 247, 21, 44, 246, 247, 15,
545 21, 44, 15, 240, 44, 0, 0, 244, 245, 149,
546 1, 248, 3, 30, 236, 172, 183, 8, 203, 10,
547 11, 12, 13, 9, -1, 16, -1, 18, 19, -1,
548 21, 22, 23, -1, -1, 26, 27, 28, 29, -1,
549 31, 32, 33, 34, -1, -1, 37, 38, 3, 40,
550 41, -1, 43, 8, 45, 10, 11, 12, 13, -1,
551 -1, 16, -1, 18, 19, -1, 21, 22, 23, -1,
552 -1, 26, 27, 28, 29, -1, 31, 32, 33, 34,
553 -1, -1, 37, -1, 3, 40, 41, -1, 43, 8,
554 45, 10, 11, 12, 13, -1, -1, 16, -1, 18,
555 19, -1, 21, 22, 23, -1, -1, 26, 27, 28,
556 29, -1, 31, 32, 33, 34, -1, -1, -1, -1,
557 3, 40, 41, -1, 43, 8, 45, 10, 11, 12,
558 13, -1, -1, 16, -1, -1, 19, -1, 21, 22,
559 23, -1, -1, 26, 27, 28, 29, -1, 31, 32,
560 33, 34, -1, -1, -1, -1, 3, 40, 41, -1,
561 43, 8, 45, 10, 11, 12, 13, -1, -1, 16,
562 -1, 18, -1, -1, 21, 22, 23, -1, -1, 26,
563 27, 28, 29, -1, 31, 32, 33, 34, -1, -1,
564 -1, -1, 3, 40, 41, -1, 43, 8, 45, 10,
565 11, 12, 13, -1, -1, 16, -1, -1, -1, -1,
566 21, 22, 23, -1, -1, 26, 27, 28, 29, -1,
567 31, 32, 33, 34, -1, -1, 37, -1, 3, 40,
568 41, -1, 43, 8, 45, 10, 11, 12, 13, -1,
569 -1, 16, -1, -1, -1, -1, 21, 22, 23, -1,
570 -1, 26, 27, 28, 29, -1, 31, 32, 33, 34,
571 -1, -1, -1, -1, -1, 40, 41, -1, 43, -1,
572 45, 26, 27, 28, 29, -1, 31, -1, 33, 34,
573 -1, -1, -1, -1, -1, 40, 41
575 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
576 #line 3 "/usr/local/lib/bison.simple"
578 /* Skeleton output parser for bison,
579 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
581 This program is free software; you can redistribute it and/or modify
582 it under the terms of the GNU General Public License as published by
583 the Free Software Foundation; either version 2, or (at your option)
586 This program is distributed in the hope that it will be useful,
587 but WITHOUT ANY WARRANTY; without even the implied warranty of
588 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
589 GNU General Public License for more details.
591 You should have received a copy of the GNU General Public License
592 along with this program; if not, write to the Free Software
593 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
595 /* As a special exception, when this file is copied by Bison into a
596 Bison output file, you may use that output file without restriction.
597 This special exception was added by the Free Software Foundation
598 in version 1.24 of Bison. */
602 #define alloca __builtin_alloca
603 #else /* not GNU C. */
604 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
606 #else /* not sparc */
607 #if defined (MSDOS) && !defined (__TURBOC__)
609 #else /* not MSDOS, or __TURBOC__ */
613 #else /* not MSDOS, __TURBOC__, or _AIX */
617 void *alloca (unsigned int);
619 #else /* not __cplusplus */
621 #endif /* not __cplusplus */
623 #endif /* not _AIX */
624 #endif /* not MSDOS, or __TURBOC__ */
625 #endif /* not sparc. */
626 #endif /* not GNU C. */
627 #endif /* alloca not defined. */
629 /* This is the parser code that is written into each bison parser
630 when the %semantic_parser declaration is not specified in the grammar.
631 It was written by Richard Stallman by simplifying the hairy parser
632 used when %semantic_parser is specified. */
634 /* Note: there must be only one dollar sign in this file.
635 It is replaced by the list of actions, each action
636 as one case of the switch. */
638 #define yyerrok (yyerrstatus = 0)
639 #define yyclearin (yychar = YYEMPTY)
642 #define YYACCEPT return(0)
643 #define YYABORT return(1)
644 #define YYERROR goto yyerrlab1
645 /* Like YYERROR except do call yyerror.
646 This remains here temporarily to ease the
647 transition to the new meaning of YYERROR, for GCC.
648 Once GCC version 2 has supplanted version 1, this can go. */
649 #define YYFAIL goto yyerrlab
650 #define YYRECOVERING() (!!yyerrstatus)
651 #define YYBACKUP(token, value) \
653 if (yychar == YYEMPTY && yylen == 1) \
654 { yychar = (token), yylval = (value); \
655 yychar1 = YYTRANSLATE (yychar); \
660 { yyerror ("syntax error: cannot back up"); YYERROR; } \
664 #define YYERRCODE 256
667 #define YYLEX yylex()
673 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
675 #define YYLEX yylex(&yylval, &yylloc)
677 #else /* not YYLSP_NEEDED */
679 #define YYLEX yylex(&yylval, YYLEX_PARAM)
681 #define YYLEX yylex(&yylval)
683 #endif /* not YYLSP_NEEDED */
686 /* If nonreentrant, generate the variables here */
690 int yychar; /* the lookahead symbol */
691 YYSTYPE yylval; /* the semantic value of the */
692 /* lookahead symbol */
695 YYLTYPE yylloc; /* location data for the lookahead */
699 int yynerrs; /* number of parse errors so far */
700 #endif /* not YYPURE */
703 int yydebug; /* nonzero means print parse trace */
704 /* Since this is uninitialized, it does not stop multiple parsers
708 /* YYINITDEPTH indicates the initial size of the parser's stacks */
711 #define YYINITDEPTH 200
714 /* YYMAXDEPTH is the maximum size the stacks can grow to
715 (effective only if the built-in stack extension method is used). */
722 #define YYMAXDEPTH 10000
725 /* Prevent warning if -Wstrict-prototypes. */
730 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
731 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
732 #else /* not GNU C or C++ */
735 /* This is the most reliable way to avoid incompatibilities
736 in available built-in functions on various systems. */
738 __yy_memcpy (to, from, count)
743 register char *f = from;
744 register char *t = to;
745 register int i = count;
751 #else /* __cplusplus */
753 /* This is the most reliable way to avoid incompatibilities
754 in available built-in functions on various systems. */
756 __yy_memcpy (char *to, char *from, int count)
758 register char *f = from;
759 register char *t = to;
760 register int i = count;
769 #line 196 "/usr/local/lib/bison.simple"
771 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
772 into yyparse. The argument should have type void *.
773 It should actually point to an object.
774 Grammar actions can access the variable by casting it
775 to the proper pointer type. */
779 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
780 #define YYPARSE_PARAM_DECL
781 #else /* not __cplusplus */
782 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
783 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
784 #endif /* not __cplusplus */
785 #else /* not YYPARSE_PARAM */
786 #define YYPARSE_PARAM_ARG
787 #define YYPARSE_PARAM_DECL
788 #endif /* not YYPARSE_PARAM */
791 yyparse(YYPARSE_PARAM_ARG)
794 register int yystate;
796 register short *yyssp;
797 register YYSTYPE *yyvsp;
798 int yyerrstatus; /* number of tokens to shift before error messages enabled */
799 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
801 short yyssa[YYINITDEPTH]; /* the state stack */
802 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
804 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
805 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
808 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
809 YYLTYPE *yyls = yylsa;
812 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
814 #define YYPOPSTACK (yyvsp--, yyssp--)
817 int yystacksize = YYINITDEPTH;
828 YYSTYPE yyval; /* the variable used to return */
829 /* semantic values from the action */
836 fprintf(stderr, "Starting parse\n");
842 yychar = YYEMPTY; /* Cause a token to be read. */
844 /* Initialize stack pointers.
845 Waste one element of value and location stack
846 so that they stay on the same level as the state stack.
847 The wasted elements are never initialized. */
855 /* Push a new state, which is found in yystate . */
856 /* In all cases, when you get here, the value and location stacks
857 have just been pushed. so pushing a state here evens the stacks. */
862 if (yyssp >= yyss + yystacksize - 1)
864 /* Give user a chance to reallocate the stack */
865 /* Use copies of these so that the &'s don't force the real ones into memory. */
866 YYSTYPE *yyvs1 = yyvs;
869 YYLTYPE *yyls1 = yyls;
872 /* Get the current used size of the three stacks, in elements. */
873 int size = yyssp - yyss + 1;
876 /* Each stack pointer address is followed by the size of
877 the data in use in that stack, in bytes. */
879 /* This used to be a conditional around just the two extra args,
880 but that might be undefined if yyoverflow is a macro. */
881 yyoverflow("parser stack overflow",
882 &yyss1, size * sizeof (*yyssp),
883 &yyvs1, size * sizeof (*yyvsp),
884 &yyls1, size * sizeof (*yylsp),
887 yyoverflow("parser stack overflow",
888 &yyss1, size * sizeof (*yyssp),
889 &yyvs1, size * sizeof (*yyvsp),
893 yyss = yyss1; yyvs = yyvs1;
897 #else /* no yyoverflow */
898 /* Extend the stack our own way. */
899 if (yystacksize >= YYMAXDEPTH)
901 yyerror("parser stack overflow");
905 if (yystacksize > YYMAXDEPTH)
906 yystacksize = YYMAXDEPTH;
907 yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
908 __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
909 yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
910 __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
912 yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
913 __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
915 #endif /* no yyoverflow */
917 yyssp = yyss + size - 1;
918 yyvsp = yyvs + size - 1;
920 yylsp = yyls + size - 1;
925 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
928 if (yyssp >= yyss + yystacksize - 1)
934 fprintf(stderr, "Entering state %d\n", yystate);
940 /* Do appropriate processing given the current state. */
941 /* Read a lookahead token if we need one and don't already have one. */
944 /* First try to decide what to do without reference to lookahead token. */
946 yyn = yypact[yystate];
950 /* Not known => get a lookahead token if don't already have one. */
952 /* yychar is either YYEMPTY or YYEOF
953 or a valid token in external form. */
955 if (yychar == YYEMPTY)
959 fprintf(stderr, "Reading a token: ");
964 /* Convert token to internal form (in yychar1) for indexing tables with */
966 if (yychar <= 0) /* This means end of input. */
969 yychar = YYEOF; /* Don't call YYLEX any more */
973 fprintf(stderr, "Now at end of input.\n");
978 yychar1 = YYTRANSLATE(yychar);
983 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
984 /* Give the individual parser a way to print the precise meaning
985 of a token, for further debugging info. */
987 YYPRINT (stderr, yychar, yylval);
989 fprintf (stderr, ")\n");
995 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
1000 /* yyn is what to do for this token type in this state.
1001 Negative => reduce, -yyn is rule number.
1002 Positive => shift, yyn is new state.
1003 New state is final state => don't bother to shift,
1004 just return success.
1005 0, or most negative number => error. */
1020 /* Shift the lookahead token. */
1024 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
1027 /* Discard the token being shifted unless it is eof. */
1028 if (yychar != YYEOF)
1036 /* count tokens shifted since error; after three, turn off error status. */
1037 if (yyerrstatus) yyerrstatus--;
1042 /* Do the default action for the current state. */
1045 yyn = yydefact[yystate];
1049 /* Do a reduction. yyn is the number of a rule to reduce with. */
1053 yyval = yyvsp[1-yylen]; /* implement default value of the action */
1060 fprintf (stderr, "Reducing via rule %d (line %d), ",
1063 /* Print the symbols being reduced, and their result. */
1064 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
1065 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
1066 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
1074 #line 215 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1076 /* Case of regular command. Discard the error
1077 safety net,and return the command just parsed. */
1078 global_command = yyvsp[-1].command;
1079 eof_encountered = 0;
1080 discard_parser_constructs (0);
1085 #line 224 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1087 /* Case of regular command, but not a very
1088 interesting one. Return a NULL command. */
1089 global_command = (COMMAND *)NULL;
1094 #line 231 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1096 /* Error during parsing. Return NULL command. */
1097 global_command = (COMMAND *)NULL;
1098 eof_encountered = 0;
1099 discard_parser_constructs (1);
1111 #line 246 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1113 /* Case of EOF seen by itself. Do ignoreeof or
1115 global_command = (COMMAND *)NULL;
1116 handle_eof_input_unit ();
1121 #line 256 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1122 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1125 #line 258 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1126 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); ;
1129 #line 262 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1131 redir.filename = yyvsp[0].word;
1132 yyval.redirect = make_redirection (1, r_output_direction, redir);
1136 #line 267 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1138 redir.filename = yyvsp[0].word;
1139 yyval.redirect = make_redirection (0, r_input_direction, redir);
1143 #line 272 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1145 redir.filename = yyvsp[0].word;
1146 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
1150 #line 277 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1152 redir.filename = yyvsp[0].word;
1153 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
1157 #line 282 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1159 redir.filename = yyvsp[0].word;
1160 yyval.redirect = make_redirection (1, r_appending_to, redir);
1164 #line 287 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1166 redir.filename = yyvsp[0].word;
1167 yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
1171 #line 292 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1173 redir.filename = yyvsp[0].word;
1174 yyval.redirect = make_redirection (0, r_reading_until, redir);
1175 redir_stack[need_here_doc++] = yyval.redirect;
1179 #line 298 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1181 redir.filename = yyvsp[0].word;
1182 yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, redir);
1183 redir_stack[need_here_doc++] = yyval.redirect;
1187 #line 304 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1189 redir.dest = yyvsp[0].number;
1190 yyval.redirect = make_redirection (0, r_duplicating_input, redir);
1194 #line 309 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1196 redir.dest = yyvsp[0].number;
1197 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
1201 #line 314 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1203 redir.dest = yyvsp[0].number;
1204 yyval.redirect = make_redirection (1, r_duplicating_output, redir);
1208 #line 319 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1210 redir.dest = yyvsp[0].number;
1211 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
1215 #line 324 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1217 redir.filename = yyvsp[0].word;
1218 yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
1222 #line 329 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1224 redir.filename = yyvsp[0].word;
1225 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
1229 #line 334 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1231 redir.filename = yyvsp[0].word;
1232 yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
1236 #line 339 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1238 redir.filename = yyvsp[0].word;
1239 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
1243 #line 344 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1245 redir.filename = yyvsp[0].word;
1246 yyval.redirect = make_redirection
1247 (0, r_deblank_reading_until, redir);
1248 redir_stack[need_here_doc++] = yyval.redirect;
1252 #line 351 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1254 redir.filename = yyvsp[0].word;
1255 yyval.redirect = make_redirection
1256 (yyvsp[-2].number, r_deblank_reading_until, redir);
1257 redir_stack[need_here_doc++] = yyval.redirect;
1261 #line 358 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1264 yyval.redirect = make_redirection (1, r_close_this, redir);
1268 #line 363 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1271 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1275 #line 368 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1278 yyval.redirect = make_redirection (0, r_close_this, redir);
1282 #line 373 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1285 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1289 #line 378 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1291 redir.filename = yyvsp[0].word;
1292 yyval.redirect = make_redirection (1, r_err_and_out, redir);
1296 #line 383 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1298 redir.filename = yyvsp[0].word;
1299 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
1303 #line 388 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1305 redir.filename = yyvsp[0].word;
1306 yyval.redirect = make_redirection (0, r_input_output, redir);
1310 #line 393 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1312 redir.filename = yyvsp[0].word;
1313 yyval.redirect = make_redirection (1, r_output_force, redir);
1317 #line 398 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1319 redir.filename = yyvsp[0].word;
1320 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
1324 #line 405 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1325 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1328 #line 407 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1329 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1332 #line 409 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1333 { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; ;
1336 #line 413 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1338 yyval.redirect = yyvsp[0].redirect;
1342 #line 417 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1344 register REDIRECT *t;
1346 for (t = yyvsp[-1].redirect; t->next; t = t->next)
1348 t->next = yyvsp[0].redirect;
1349 yyval.redirect = yyvsp[-1].redirect;
1353 #line 428 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1354 { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); ;
1357 #line 430 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1358 { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); ;
1361 #line 434 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1362 { yyval.command = clean_simple_command (yyvsp[0].command); ;
1365 #line 436 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1366 { yyval.command = yyvsp[0].command; ;
1369 #line 438 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1373 tc = yyvsp[-1].command;
1374 /* According to Posix.2 3.9.5, redirections
1375 specified after the body of a function should
1376 be attached to the function and performed when
1377 the function is executed, not as part of the
1378 function definition command. */
1379 if (tc->type == cm_function_def)
1381 tc = tc->value.Function_def->command;
1382 if (tc->type == cm_group)
1383 tc = tc->value.Group->command;
1387 register REDIRECT *t;
1388 for (t = tc->redirects; t->next; t = t->next)
1390 t->next = yyvsp[0].redirect;
1393 tc->redirects = yyvsp[0].redirect;
1394 yyval.command = yyvsp[-1].command;
1398 #line 467 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1399 { yyval.command = yyvsp[0].command; ;
1402 #line 469 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1403 { yyval.command = yyvsp[0].command; ;
1406 #line 471 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1407 { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); ;
1410 #line 473 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1411 { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); ;
1414 #line 475 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1415 { yyval.command = yyvsp[0].command; ;
1418 #line 477 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1419 { yyval.command = yyvsp[0].command; ;
1422 #line 479 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1423 { yyval.command = yyvsp[0].command; ;
1426 #line 481 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1427 { yyval.command = yyvsp[0].command; ;
1430 #line 483 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1431 { yyval.command = yyvsp[0].command; ;
1434 #line 487 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1435 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1438 #line 489 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1439 { yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1442 #line 491 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1443 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1446 #line 493 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1447 { yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command); ;
1450 #line 495 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1451 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1454 #line 497 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1455 { yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command); ;
1458 #line 501 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1460 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1464 #line 505 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1466 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command);
1470 #line 509 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1472 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1476 #line 513 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1478 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1482 #line 517 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1484 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1488 #line 521 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1490 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1494 #line 527 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1495 { yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL); ;
1498 #line 529 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1499 { yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern); ;
1502 #line 531 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1503 { yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern); ;
1506 #line 535 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1507 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1510 #line 539 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1511 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1514 #line 542 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1515 { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command, function_dstart, function_bstart); ;
1518 #line 546 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1519 { yyvsp[-1].command->flags |= CMD_WANT_SUBSHELL; yyval.command = yyvsp[-1].command; ;
1522 #line 550 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1523 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); ;
1526 #line 552 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1527 { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); ;
1530 #line 554 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1531 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); ;
1534 #line 559 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1535 { yyval.command = make_group_command (yyvsp[-1].command); ;
1538 #line 563 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1539 { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); ;
1542 #line 565 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1543 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); ;
1546 #line 567 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1547 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); ;
1550 #line 572 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1551 { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
1554 #line 576 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1555 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1558 #line 578 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1559 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1562 #line 580 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1563 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1566 #line 582 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1567 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1570 #line 587 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1571 { yyvsp[-1].pattern->next = yyvsp[-2].pattern; yyval.pattern = yyvsp[-1].pattern; ;
1574 #line 591 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1575 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1578 #line 593 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1579 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); ;
1582 #line 602 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1584 yyval.command = yyvsp[0].command;
1586 gather_here_documents ();
1590 #line 611 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1592 yyval.command = yyvsp[0].command;
1596 #line 618 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1598 if (yyvsp[-2].command->type == cm_connection)
1599 yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
1601 yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
1605 #line 629 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1606 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1609 #line 631 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1610 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1613 #line 633 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1615 if (yyvsp[-3].command->type == cm_connection)
1616 yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
1618 yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
1622 #line 640 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1623 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1626 #line 642 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1627 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1630 #line 644 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1631 { yyval.command = yyvsp[0].command; ;
1634 #line 663 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1636 yyval.command = yyvsp[0].command;
1638 gather_here_documents ();
1642 #line 669 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1644 if (yyvsp[-1].command->type == cm_connection)
1645 yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
1647 yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
1649 gather_here_documents ();
1653 #line 678 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1655 yyval.command = yyvsp[-1].command;
1657 gather_here_documents ();
1661 #line 686 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1662 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1665 #line 688 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1666 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1669 #line 690 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1671 if (yyvsp[-2].command->type == cm_connection)
1672 yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
1674 yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
1678 #line 697 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1679 { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); ;
1682 #line 700 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1683 { yyval.command = yyvsp[0].command; ;
1686 #line 704 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1687 { yyval.command = yyvsp[0].command; ;
1690 #line 706 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1692 yyvsp[0].command->flags |= CMD_INVERT_RETURN;
1693 yyval.command = yyvsp[0].command;
1697 #line 711 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1699 yyvsp[0].command->flags |= yyvsp[-1].number;
1700 yyval.command = yyvsp[0].command;
1704 #line 716 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1706 yyvsp[0].command->flags |= yyvsp[-2].number;
1707 yyval.command = yyvsp[0].command;
1711 #line 721 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1713 yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
1714 yyval.command = yyvsp[0].command;
1718 #line 729 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1719 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); ;
1722 #line 731 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1723 { yyval.command = yyvsp[0].command; ;
1726 #line 735 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1727 { yyval.number = CMD_TIME_PIPELINE; ;
1730 #line 737 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1731 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; ;
1734 /* the action file gets copied in in place of this dollarsign */
1735 #line 498 "/usr/local/lib/bison.simple"
1746 short *ssp1 = yyss - 1;
1747 fprintf (stderr, "state stack now");
1748 while (ssp1 != yyssp)
1749 fprintf (stderr, " %d", *++ssp1);
1750 fprintf (stderr, "\n");
1760 yylsp->first_line = yylloc.first_line;
1761 yylsp->first_column = yylloc.first_column;
1762 yylsp->last_line = (yylsp-1)->last_line;
1763 yylsp->last_column = (yylsp-1)->last_column;
1768 yylsp->last_line = (yylsp+yylen-1)->last_line;
1769 yylsp->last_column = (yylsp+yylen-1)->last_column;
1773 /* Now "shift" the result of the reduction.
1774 Determine what state that goes to,
1775 based on the state we popped back to
1776 and the rule number reduced by. */
1780 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1781 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1782 yystate = yytable[yystate];
1784 yystate = yydefgoto[yyn - YYNTBASE];
1788 yyerrlab: /* here on detecting error */
1791 /* If not already recovering from an error, report this error. */
1795 #ifdef YYERROR_VERBOSE
1796 yyn = yypact[yystate];
1798 if (yyn > YYFLAG && yyn < YYLAST)
1805 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1806 for (x = (yyn < 0 ? -yyn : 0);
1807 x < (sizeof(yytname) / sizeof(char *)); x++)
1808 if (yycheck[x + yyn] == x)
1809 size += strlen(yytname[x]) + 15, count++;
1810 msg = (char *) malloc(size + 15);
1813 strcpy(msg, "parse error");
1818 for (x = (yyn < 0 ? -yyn : 0);
1819 x < (sizeof(yytname) / sizeof(char *)); x++)
1820 if (yycheck[x + yyn] == x)
1822 strcat(msg, count == 0 ? ", expecting `" : " or `");
1823 strcat(msg, yytname[x]);
1832 yyerror ("parse error; also virtual memory exceeded");
1835 #endif /* YYERROR_VERBOSE */
1836 yyerror("parse error");
1840 yyerrlab1: /* here on error raised explicitly by an action */
1842 if (yyerrstatus == 3)
1844 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1846 /* return failure if at end of input */
1847 if (yychar == YYEOF)
1852 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1858 /* Else will try to reuse lookahead token
1859 after shifting the error token. */
1861 yyerrstatus = 3; /* Each real token shifted decrements this */
1865 yyerrdefault: /* current state does not do anything special for the error token. */
1868 /* This is wrong; only states that explicitly want error tokens
1869 should shift them. */
1870 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1871 if (yyn) goto yydefault;
1874 yyerrpop: /* pop the current state because it cannot handle the error token */
1876 if (yyssp == yyss) YYABORT;
1886 short *ssp1 = yyss - 1;
1887 fprintf (stderr, "Error: state stack now");
1888 while (ssp1 != yyssp)
1889 fprintf (stderr, " %d", *++ssp1);
1890 fprintf (stderr, "\n");
1896 yyn = yypact[yystate];
1901 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1920 fprintf(stderr, "Shifting error token, ");
1931 #line 739 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1934 /* Possible states for the parser that require it to do special things. */
1935 #define PST_CASEPAT 0x001 /* in a case pattern list */
1936 #define PST_ALEXPNEXT 0x002 /* expand next word for aliases */
1937 #define PST_ALLOWOPNBRC 0x004 /* allow open brace for function def */
1938 #define PST_NEEDCLOSBRC 0x008 /* need close brace */
1939 #define PST_DBLPAREN 0x010 /* double-paren parsing */
1940 #define PST_SUBSHELL 0x020 /* ( ... ) subshell */
1941 #define PST_CMDSUBST 0x040 /* $( ... ) command substitution */
1942 #define PST_CASESTMT 0x080 /* parsing a case statement */
1944 /* Initial size to allocate for tokens, and the
1945 amount to grow them by. */
1946 #define TOKEN_DEFAULT_INITIAL_SIZE 496
1947 #define TOKEN_DEFAULT_GROW_SIZE 512
1949 /* Shell meta-characters that, when unquoted, separate words. */
1950 #define shellmeta(c) (strchr ("()<>;&|", (c)) != 0)
1951 #define shellbreak(c) (strchr ("()<>;&| \t\n", (c)) != 0)
1952 #define shellquote(c) ((c) == '"' || (c) == '`' || (c) == '\'')
1953 #define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>')
1955 /* The token currently being read. */
1956 static int current_token;
1958 /* The last read token, or NULL. read_token () uses this for context
1960 static int last_read_token;
1962 /* The token read prior to last_read_token. */
1963 static int token_before_that;
1965 /* The token read prior to token_before_that. */
1966 static int two_tokens_ago;
1968 /* If non-zero, it is the token that we want read_token to return
1969 regardless of what text is (or isn't) present to be read. This
1970 is reset by read_token. If token_to_read == WORD or
1971 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
1972 static int token_to_read;
1973 static WORD_DESC *word_desc_to_read;
1975 /* The current parser state. */
1976 static int parser_state;
1978 /* Global var is non-zero when end of file has been reached. */
1979 int EOF_Reached = 0;
1990 /* yy_getc () returns the next available character from input or EOF.
1991 yy_ungetc (c) makes `c' the next character to read.
1992 init_yy_io (get, unget, type, location) makes the function GET the
1993 installed function for getting the next character, makes UNGET the
1994 installed function for un-getting a character, sets the type of stream
1995 (either string or file) from TYPE, and makes LOCATION point to where
1996 the input is coming from. */
1998 /* Unconditionally returns end-of-file. */
2005 /* Variable containing the current get and unget functions.
2006 See ./input.h for a clearer description. */
2007 BASH_INPUT bash_input;
2009 /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
2010 is non-null, avoiding a memory leak. */
2012 initialize_bash_input ()
2014 bash_input.type = st_none;
2015 FREE (bash_input.name);
2016 bash_input.name = (char *)NULL;
2017 bash_input.location.file = (FILE *)NULL;
2018 bash_input.location.string = (char *)NULL;
2019 bash_input.getter = (Function *)NULL;
2020 bash_input.ungetter = (Function *)NULL;
2023 /* Set the contents of the current bash input stream from
2024 GET, UNGET, TYPE, NAME, and LOCATION. */
2026 init_yy_io (get, unget, type, name, location)
2027 Function *get, *unget;
2028 enum stream_type type;
2030 INPUT_STREAM location;
2032 bash_input.type = type;
2033 FREE (bash_input.name);
2034 bash_input.name = name ? savestring (name) : (char *)NULL;
2038 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
2040 bash_input.location = location;
2042 bash_input.getter = get;
2043 bash_input.ungetter = unget;
2046 /* Call this to get the next character of input. */
2050 return (*(bash_input.getter)) ();
2053 /* Call this to unget C. That is, to make C the next character
2059 return (*(bash_input.ungetter)) (c);
2062 #if defined (BUFFERED_INPUT)
2064 input_file_descriptor ()
2066 switch (bash_input.type)
2069 return (fileno (bash_input.location.file));
2071 return (bash_input.location.buffered_fd);
2074 return (fileno (stdin));
2077 #endif /* BUFFERED_INPUT */
2079 /* **************************************************************** */
2081 /* Let input be read from readline (). */
2083 /* **************************************************************** */
2085 #if defined (READLINE)
2086 char *current_readline_prompt = (char *)NULL;
2087 char *current_readline_line = (char *)NULL;
2088 int current_readline_line_index = 0;
2093 SigHandler *old_sigint;
2096 if (!current_readline_line)
2098 if (!bash_readline_initialized)
2099 initialize_readline ();
2101 #if defined (JOB_CONTROL)
2103 give_terminal_to (shell_pgrp);
2104 #endif /* JOB_CONTROL */
2106 if (signal_is_ignored (SIGINT) == 0)
2108 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
2109 interrupt_immediately++;
2112 current_readline_line = readline (current_readline_prompt ?
2113 current_readline_prompt : "");
2115 if (signal_is_ignored (SIGINT) == 0)
2117 interrupt_immediately--;
2118 set_signal_handler (SIGINT, old_sigint);
2122 /* Reset the prompt to the decoded value of prompt_string_pointer. */
2123 reset_readline_prompt ();
2126 if (current_readline_line == 0)
2129 current_readline_line_index = 0;
2130 line_len = strlen (current_readline_line);
2132 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
2133 current_readline_line[line_len++] = '\n';
2134 current_readline_line[line_len] = '\0';
2137 if (current_readline_line[current_readline_line_index] == 0)
2139 free (current_readline_line);
2140 current_readline_line = (char *)NULL;
2141 return (yy_readline_get ());
2145 c = (unsigned char)current_readline_line[current_readline_line_index++];
2151 yy_readline_unget (c)
2154 if (current_readline_line_index && current_readline_line)
2155 current_readline_line[--current_readline_line_index] = c;
2160 with_input_from_stdin ()
2162 INPUT_STREAM location;
2164 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
2166 location.string = current_readline_line;
2167 init_yy_io (yy_readline_get, yy_readline_unget,
2168 st_stdin, "readline stdin", location);
2172 #else /* !READLINE */
2175 with_input_from_stdin ()
2177 with_input_from_stream (stdin, "stdin");
2179 #endif /* !READLINE */
2181 /* **************************************************************** */
2183 /* Let input come from STRING. STRING is zero terminated. */
2185 /* **************************************************************** */
2190 register char *string;
2193 string = bash_input.location.string;
2196 /* If the string doesn't exist, or is empty, EOF found. */
2197 if (string && *string)
2199 c = *(unsigned char *)string++;
2200 bash_input.location.string = string;
2209 *(--bash_input.location.string) = c;
2214 with_input_from_string (string, name)
2215 char *string, *name;
2217 INPUT_STREAM location;
2219 location.string = string;
2220 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
2223 /* **************************************************************** */
2225 /* Let input come from STREAM. */
2227 /* **************************************************************** */
2234 if (bash_input.location.file)
2236 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2237 result = getc_with_restart (bash_input.location.file);
2238 #else /* HAVE_RESTARTABLE_SYSCALLS */
2239 result = getc (bash_input.location.file);
2240 result = (feof (bash_input.location.file)) ? EOF : (unsigned char)result;
2241 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2250 #if !defined (HAVE_RESTARTABLE_SYSCALLS)
2251 return (ungetc_with_restart (c, bash_input.location.file));
2252 #else /* HAVE_RESTARTABLE_SYSCALLS */
2253 return (ungetc (c, bash_input.location.file));
2254 #endif /* HAVE_RESTARTABLE_SYSCALLS */
2258 with_input_from_stream (stream, name)
2262 INPUT_STREAM location;
2264 location.file = stream;
2265 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
2268 typedef struct stream_saver {
2269 struct stream_saver *next;
2270 BASH_INPUT bash_input;
2272 #if defined (BUFFERED_INPUT)
2273 BUFFERED_STREAM *bstream;
2274 #endif /* BUFFERED_INPUT */
2277 /* The globally known line number. */
2278 int line_number = 0;
2280 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
2283 push_stream (reset_lineno)
2286 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
2288 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
2290 #if defined (BUFFERED_INPUT)
2291 saver->bstream = (BUFFERED_STREAM *)NULL;
2292 /* If we have a buffered stream, clear out buffers[fd]. */
2293 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2295 saver->bstream = buffers[bash_input.location.buffered_fd];
2296 buffers[bash_input.location.buffered_fd] = (BUFFERED_STREAM *)NULL;
2298 #endif /* BUFFERED_INPUT */
2300 saver->line = line_number;
2301 bash_input.name = (char *)NULL;
2302 saver->next = stream_list;
2303 stream_list = saver;
2316 STREAM_SAVER *saver = stream_list;
2319 stream_list = stream_list->next;
2321 init_yy_io (saver->bash_input.getter,
2322 saver->bash_input.ungetter,
2323 saver->bash_input.type,
2324 saver->bash_input.name,
2325 saver->bash_input.location);
2327 #if defined (BUFFERED_INPUT)
2328 /* If we have a buffered stream, restore buffers[fd]. */
2329 /* If the input file descriptor was changed while this was on the
2330 save stack, update the buffered fd to the new file descriptor and
2331 re-establish the buffer <-> bash_input fd correspondence. */
2332 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2334 if (bash_input_fd_changed)
2336 bash_input_fd_changed = 0;
2337 if (default_buffered_input >= 0)
2339 bash_input.location.buffered_fd = default_buffered_input;
2340 saver->bstream->b_fd = default_buffered_input;
2343 buffers[bash_input.location.buffered_fd] = saver->bstream;
2345 #endif /* BUFFERED_INPUT */
2347 line_number = saver->line;
2349 FREE (saver->bash_input.name);
2354 /* Return 1 if a stream of type TYPE is saved on the stack. */
2356 stream_on_stack (type)
2357 enum stream_type type;
2359 register STREAM_SAVER *s;
2361 for (s = stream_list; s; s = s->next)
2362 if (s->bash_input.type == type)
2368 * This is used to inhibit alias expansion and reserved word recognition
2369 * inside case statement pattern lists. A `case statement pattern list' is:
2371 * everything between the `in' in a `case word in' and the next ')'
2373 * everything between a `;;' and the next `)' or `esac'
2378 #define END_OF_ALIAS 0
2381 * Pseudo-global variables used in implementing token-wise alias expansion.
2385 * Pushing and popping strings. This works together with shell_getc to
2386 * implement alias expansion on a per-token basis.
2389 typedef struct string_saver {
2390 struct string_saver *next;
2391 int expand_alias; /* Value to set expand_alias to when string is popped. */
2393 alias_t *expander; /* alias that caused this line to be pushed. */
2394 int saved_line_size, saved_line_index, saved_line_terminator;
2397 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
2400 * Push the current shell_input_line onto a stack of such lines and make S
2401 * the current input. Used when expanding aliases. EXPAND is used to set
2402 * the value of expand_next_token when the string is popped, so that the
2403 * word after the alias in the original line is handled correctly when the
2404 * alias expands to multiple words. TOKEN is the token that was expanded
2405 * into S; it is saved and used to prevent infinite recursive expansion.
2408 push_string (s, expand, ap)
2413 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
2415 temp->expand_alias = expand;
2416 temp->saved_line = shell_input_line;
2417 temp->saved_line_size = shell_input_line_size;
2418 temp->saved_line_index = shell_input_line_index;
2419 temp->saved_line_terminator = shell_input_line_terminator;
2420 temp->expander = ap;
2421 temp->next = pushed_string_list;
2422 pushed_string_list = temp;
2425 ap->flags |= AL_BEINGEXPANDED;
2427 shell_input_line = s;
2428 shell_input_line_size = strlen (s);
2429 shell_input_line_index = 0;
2430 shell_input_line_terminator = '\0';
2431 parser_state &= ~PST_ALEXPNEXT;
2435 * Make the top of the pushed_string stack be the current shell input.
2436 * Only called when there is something on the stack. Called from shell_getc
2437 * when it thinks it has consumed the string generated by an alias expansion
2438 * and needs to return to the original input line.
2445 FREE (shell_input_line);
2446 shell_input_line = pushed_string_list->saved_line;
2447 shell_input_line_index = pushed_string_list->saved_line_index;
2448 shell_input_line_size = pushed_string_list->saved_line_size;
2449 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
2451 if (pushed_string_list->expand_alias)
2452 parser_state |= PST_ALEXPNEXT;
2454 parser_state &= ~PST_ALEXPNEXT;
2456 t = pushed_string_list;
2457 pushed_string_list = pushed_string_list->next;
2460 t->expander->flags &= ~AL_BEINGEXPANDED;
2468 register STRING_SAVER *t, *t1;
2470 for (t = pushed_string_list; t; )
2473 FREE (t->saved_line);
2474 t->expander->flags &= ~AL_BEINGEXPANDED;
2478 pushed_string_list = (STRING_SAVER *)NULL;
2483 /* Return a line of text, taken from wherever yylex () reads input.
2484 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
2485 is non-zero, we remove unquoted \<newline> pairs. This is used by
2486 read_secondary_line to read here documents. */
2488 read_a_line (remove_quoted_newline)
2489 int remove_quoted_newline;
2491 static char *line_buffer = (char *)NULL;
2492 static int buffer_size = 0;
2493 int indx = 0, c, peekc, pass_next;
2495 #if defined (READLINE)
2496 if (interactive && bash_input.type != st_string && no_line_editing)
2498 if (interactive && bash_input.type != st_string)
2507 /* Allow immediate exit if interrupted during input. */
2513 /* If there is no more input, then we return NULL. */
2516 if (interactive && bash_input.type == st_stream)
2519 return ((char *)NULL);
2523 /* `+2' in case the final character in the buffer is a newline. */
2524 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
2526 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
2527 here document with an unquoted delimiter. In this case,
2528 the line will be expanded as if it were in double quotes.
2529 We allow a backslash to escape the next character, but we
2530 need to treat the backslash specially only if a backslash
2531 quoting a backslash-newline pair appears in the line. */
2534 line_buffer[indx++] = c;
2537 else if (c == '\\' && remove_quoted_newline)
2541 continue; /* Make the unquoted \<newline> pair disappear. */
2546 line_buffer[indx++] = c; /* Preserve the backslash. */
2550 line_buffer[indx++] = c;
2554 line_buffer[indx] = '\0';
2555 return (line_buffer);
2560 /* Return a line as in read_a_line (), but insure that the prompt is
2561 the secondary prompt. This is used to read the lines of a here
2562 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2563 newlines quoted with backslashes while reading the line. It is
2564 non-zero unless the delimiter of the here document was quoted. */
2566 read_secondary_line (remove_quoted_newline)
2567 int remove_quoted_newline;
2569 prompt_string_pointer = &ps2_prompt;
2571 return (read_a_line (remove_quoted_newline));
2574 /* **************************************************************** */
2578 /* **************************************************************** */
2580 /* Reserved words. These are only recognized as the first word of a
2582 STRING_INT_ALIST word_token_alist[] = {
2591 #if defined (SELECT_COMMAND)
2592 { "select", SELECT },
2599 { "function", FUNCTION },
2600 #if defined (COMMAND_TIMING)
2609 /* These are used by read_token_word, but appear up here so that shell_getc
2610 can use them to decide when to add otherwise blank lines to the history. */
2612 /* The primary delimiter stack. */
2613 struct dstack dstack = { (char *)NULL, 0, 0 };
2615 /* A temporary delimiter stack to be used when decoding prompt strings.
2616 This is needed because command substitutions in prompt strings (e.g., PS2)
2617 can screw up the parser's quoting state. */
2618 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2620 /* Macro for accessing the top delimiter on the stack. Returns the
2621 delimiter or zero if none. */
2622 #define current_delimiter(ds) \
2623 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2625 #define push_delimiter(ds, character) \
2628 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
2629 ds.delimiters = xrealloc \
2630 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2631 ds.delimiters[ds.delimiter_depth] = character; \
2632 ds.delimiter_depth++; \
2636 #define pop_delimiter(ds) ds.delimiter_depth--
2638 /* Return the next shell input character. This always reads characters
2639 from shell_input_line; when that line is exhausted, it is time to
2640 read the next line. This is called by read_token when the shell is
2641 processing normal command input. */
2644 shell_getc (remove_quoted_newline)
2645 int remove_quoted_newline;
2649 static int mustpop = 0;
2654 /* If shell_input_line[shell_input_line_index] == 0, but there is
2655 something on the pushed list of strings, then we don't want to go
2656 off and get another line. We let the code down below handle it. */
2658 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2659 (pushed_string_list == (STRING_SAVER *)NULL)))
2661 if (!shell_input_line || !shell_input_line[shell_input_line_index])
2668 /* Allow immediate exit if interrupted during input. */
2672 shell_input_line_terminator = 0;
2674 #if defined (JOB_CONTROL)
2675 /* This can cause a problem when reading a command as the result
2676 of a trap, when the trap is called from flush_child. This call
2677 had better not cause jobs to disappear from the job table in
2678 that case, or we will have big trouble. */
2679 notify_and_cleanup ();
2680 #else /* !JOB_CONTROL */
2681 cleanup_dead_jobs ();
2682 #endif /* !JOB_CONTROL */
2684 #if defined (READLINE)
2685 if (interactive && bash_input.type != st_string && no_line_editing)
2687 if (interactive && bash_input.type != st_string)
2691 if (bash_input.type == st_stream)
2694 while (c = yy_getc ())
2696 /* Allow immediate exit if interrupted during input. */
2699 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2703 if (bash_input.type == st_stream)
2707 shell_input_line_terminator = EOF;
2709 shell_input_line[i] = '\0';
2713 shell_input_line[i++] = c;
2717 shell_input_line[--i] = '\0';
2718 current_command_line_count++;
2722 shell_input_line_index = 0;
2723 shell_input_line_len = i; /* == strlen (shell_input_line) */
2725 #if defined (HISTORY)
2726 if (remember_on_history && shell_input_line && shell_input_line[0])
2729 # if defined (BANG_HISTORY)
2732 /* If the current delimiter is a single quote, we should not be
2733 performing history expansion, even if we're on a different
2734 line from the original single quote. */
2735 old_hist = history_expansion_inhibited;
2736 if (current_delimiter (dstack) == '\'')
2737 history_expansion_inhibited = 1;
2739 expansions = pre_process_line (shell_input_line, 1, 1);
2740 # if defined (BANG_HISTORY)
2741 history_expansion_inhibited = old_hist;
2743 if (expansions != shell_input_line)
2745 free (shell_input_line);
2746 shell_input_line = expansions;
2747 shell_input_line_len = shell_input_line ?
2748 strlen (shell_input_line) : 0;
2749 if (!shell_input_line_len)
2750 current_command_line_count--;
2752 /* We have to force the xrealloc below because we don't know
2753 the true allocated size of shell_input_line anymore. */
2754 shell_input_line_size = shell_input_line_len;
2757 /* XXX - this is grotesque */
2758 else if (remember_on_history && shell_input_line &&
2759 shell_input_line[0] == '\0' &&
2760 current_command_line_count > 1 && current_delimiter (dstack))
2762 /* We know shell_input_line[0] == 0 and we're reading some sort of
2763 quoted string. This means we've got a line consisting of only
2764 a newline in a quoted string. We want to make sure this line
2765 gets added to the history. */
2766 maybe_add_history (shell_input_line);
2769 #endif /* HISTORY */
2771 if (shell_input_line)
2773 /* Lines that signify the end of the shell's input should not be
2775 if (echo_input_at_read && (shell_input_line[0] ||
2776 shell_input_line_terminator != EOF))
2777 fprintf (stderr, "%s\n", shell_input_line);
2781 shell_input_line_size = 0;
2782 prompt_string_pointer = ¤t_prompt_string;
2787 /* Add the newline to the end of this string, iff the string does
2788 not already end in an EOF character. */
2789 if (shell_input_line_terminator != EOF)
2791 if (shell_input_line_len + 3 > shell_input_line_size)
2792 shell_input_line = xrealloc (shell_input_line,
2793 1 + (shell_input_line_size += 2));
2795 shell_input_line[shell_input_line_len] = '\n';
2796 shell_input_line[shell_input_line_len + 1] = '\0';
2800 c = shell_input_line[shell_input_line_index];
2803 shell_input_line_index++;
2805 if (c == '\\' && remove_quoted_newline &&
2806 shell_input_line[shell_input_line_index] == '\n')
2814 /* If C is NULL, we have reached the end of the current input string. If
2815 pushed_string_list is non-empty, it's time to pop to the previous string
2816 because we have fully consumed the result of the last alias expansion.
2817 Do it transparently; just return the next character of the string popped
2819 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
2824 c = shell_input_line[shell_input_line_index];
2826 shell_input_line_index++;
2837 if (!c && shell_input_line_terminator == EOF)
2838 return ((shell_input_line_index != 0) ? '\n' : EOF);
2840 return ((unsigned char)c);
2843 /* Put C back into the input for the shell. */
2848 if (shell_input_line && shell_input_line_index)
2849 shell_input_line[--shell_input_line_index] = c;
2855 if (shell_input_line && shell_input_line_index)
2856 shell_input_line_index--;
2859 /* Discard input until CHARACTER is seen, then push that character back
2860 onto the input stream. */
2862 discard_until (character)
2867 while ((c = shell_getc (0)) != EOF && c != character)
2875 execute_prompt_command (command)
2878 Function *temp_last, *temp_this;
2880 int temp_exit_value, temp_eof_encountered;
2882 temp_last = last_shell_builtin;
2883 temp_this = this_shell_builtin;
2884 temp_exit_value = last_command_exit_value;
2885 temp_eof_encountered = eof_encountered;
2886 last_lastarg = get_string_value ("_");
2888 last_lastarg = savestring (last_lastarg);
2890 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
2892 last_shell_builtin = temp_last;
2893 this_shell_builtin = temp_this;
2894 last_command_exit_value = temp_exit_value;
2895 eof_encountered = temp_eof_encountered;
2897 bind_variable ("_", last_lastarg);
2898 FREE (last_lastarg);
2900 if (token_to_read == '\n') /* reset_parser was called */
2904 /* Place to remember the token. We try to keep the buffer
2905 at a reasonable size, but it can grow. */
2906 static char *token = (char *)NULL;
2908 /* Current size of the token buffer. */
2909 static int token_buffer_size;
2911 /* Command to read_token () explaining what we want it to do. */
2914 #define prompt_is_ps1 \
2915 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2917 /* Function for yyparse to call. yylex keeps track of
2918 the last two tokens read, and calls read_token. */
2922 if (interactive && (current_token == 0 || current_token == '\n'))
2924 /* Before we print a prompt, we might have to check mailboxes.
2925 We do this only if it is time to do so. Notice that only here
2926 is the mail alarm reset; nothing takes place in check_mail ()
2927 except the checking of mail. Please don't change this. */
2928 if (prompt_is_ps1 && time_to_check_mail ())
2931 reset_mail_timer ();
2934 /* Avoid printing a prompt if we're not going to read anything, e.g.
2935 after resetting the parser with read_token (RESET). */
2936 if (token_to_read == 0 && interactive)
2940 two_tokens_ago = token_before_that;
2941 token_before_that = last_read_token;
2942 last_read_token = current_token;
2943 current_token = read_token (READ);
2944 return (current_token);
2947 /* When non-zero, we have read the required tokens
2948 which allow ESAC to be the next one read. */
2949 static int esacs_needed_count;
2952 gather_here_documents ()
2955 while (need_here_doc)
2957 make_here_document (redir_stack[r++]);
2962 /* When non-zero, an open-brace used to create a group is awaiting a close
2964 static int open_brace_count;
2966 #define command_token_position(token) \
2967 (((token) == ASSIGNMENT_WORD) || \
2968 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
2970 #define assignment_acceptable(token) command_token_position(token) && \
2971 ((parser_state & PST_CASEPAT) == 0)
2973 /* Check to see if TOKEN is a reserved word and return the token
2975 #define CHECK_FOR_RESERVED_WORD(tok) \
2977 if (!dollar_present && !quoted && \
2978 reserved_word_acceptable (last_read_token)) \
2981 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2982 if (STREQ (tok, word_token_alist[i].word)) \
2984 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
2986 if (word_token_alist[i].token == ESAC) \
2987 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2988 else if (word_token_alist[i].token == CASE) \
2989 parser_state |= PST_CASESTMT; \
2990 else if (word_token_alist[i].token == '{') \
2991 open_brace_count++; \
2992 else if (word_token_alist[i].token == '}' && open_brace_count) \
2993 open_brace_count--; \
2994 return (word_token_alist[i].token); \
3001 /* OK, we have a token. Let's try to alias expand it, if (and only if)
3004 It is eligible for expansion if the shell is in interactive mode, and
3005 the token is unquoted and the last token read was a command
3006 separator (or expand_next_token is set), and we are currently
3007 processing an alias (pushed_string_list is non-empty) and this
3008 token is not the same as the current or any previously
3011 Special cases that disqualify:
3012 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
3014 alias_expand_token (token)
3020 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
3021 (parser_state & PST_CASEPAT) == 0)
3023 ap = find_alias (token);
3025 /* Currently expanding this token. */
3026 if (ap && (ap->flags & AL_BEINGEXPANDED))
3027 return (NO_EXPANSION);
3029 expanded = ap ? savestring (ap->value) : (char *)NULL;
3032 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
3033 return (RE_READ_TOKEN);
3036 /* This is an eligible token that does not have an expansion. */
3037 return (NO_EXPANSION);
3039 return (NO_EXPANSION);
3043 /* Handle special cases of token recognition:
3044 IN is recognized if the last token was WORD and the token
3045 before that was FOR or CASE or SELECT.
3047 DO is recognized if the last token was WORD and the token
3048 before that was FOR or SELECT.
3050 ESAC is recognized if the last token caused `esacs_needed_count'
3053 `{' is recognized if the last token as WORD and the token
3054 before that was FUNCTION.
3056 `}' is recognized if there is an unclosed `{' prsent.
3060 special_case_tokens (token)
3063 if ((last_read_token == WORD) &&
3064 #if defined (SELECT_COMMAND)
3065 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3067 ((token_before_that == FOR) || (token_before_that == CASE)) &&
3069 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
3071 if (token_before_that == CASE)
3073 parser_state |= PST_CASEPAT;
3074 esacs_needed_count++;
3079 if (last_read_token == WORD &&
3080 #if defined (SELECT_COMMAND)
3081 (token_before_that == FOR || token_before_that == SELECT) &&
3083 (token_before_that == FOR) &&
3085 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
3088 /* Ditto for ESAC in the CASE case.
3089 Specifically, this handles "case word in esac", which is a legal
3090 construct, certainly because someone will pass an empty arg to the
3091 case construct, and we don't want it to barf. Of course, we should
3092 insist that the case construct has at least one pattern in it, but
3093 the designers disagree. */
3094 if (esacs_needed_count)
3096 esacs_needed_count--;
3097 if (STREQ (token, "esac"))
3099 parser_state &= ~PST_CASEPAT;
3104 /* The start of a shell function definition. */
3105 if (parser_state & PST_ALLOWOPNBRC)
3107 parser_state &= ~PST_ALLOWOPNBRC;
3108 if (token[0] == '{' && token[1] == '\0') /* } */
3111 function_bstart = line_number;
3112 return ('{'); /* } */
3116 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
3118 open_brace_count--; /* { */
3122 /* Handle -p after `time'. */
3123 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
3129 /* Called from shell.c when Control-C is typed at top level. Or
3130 by the error rule at top level. */
3134 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3135 open_brace_count = 0;
3140 if (pushed_string_list)
3142 free_string_list ();
3143 pushed_string_list = (STRING_SAVER *)NULL;
3147 if (shell_input_line)
3149 free (shell_input_line);
3150 shell_input_line = (char *)NULL;
3151 shell_input_line_size = shell_input_line_index = 0;
3154 FREE (word_desc_to_read);
3155 word_desc_to_read = (WORD_DESC *)NULL;
3157 last_read_token = '\n';
3158 token_to_read = '\n';
3161 /* Read the next token. Command can be READ (normal operation) or
3162 RESET (to normalize state). */
3164 read_token (command)
3167 int character; /* Current character. */
3168 int peek_char; /* Temporary look-ahead character. */
3169 int result; /* The thing to return. */
3171 if (command == RESET)
3179 result = token_to_read;
3180 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3182 yylval.word = word_desc_to_read;
3183 word_desc_to_read = (WORD_DESC *)NULL;
3190 /* This is a place to jump back to once we have successfully expanded a
3191 token with an alias and pushed the string with push_string () */
3195 /* Read a single word from input. Start by skipping blanks. */
3196 while ((character = shell_getc (1)) != EOF && whitespace (character))
3199 if (character == EOF)
3205 if (character == '#' && (!interactive || interactive_comments))
3207 /* A comment. Discard until EOL or EOF, and then return a newline. */
3208 discard_until ('\n');
3210 character = '\n'; /* this will take the next if statement and return. */
3213 if (character == '\n')
3215 /* If we're about to return an unquoted newline, we can go and collect
3216 the text of any pending here document. */
3218 gather_here_documents ();
3221 parser_state &= ~PST_ALEXPNEXT;
3227 /* Shell meta-characters. */
3228 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3231 /* Turn off alias tokenization iff this character sequence would
3232 not leave us ready to read a command. */
3233 if (character == '<' || character == '>')
3234 parser_state &= ~PST_ALEXPNEXT;
3237 peek_char = shell_getc (1);
3238 if (character == peek_char)
3243 /* If '<' then we could be at "<<" or at "<<-". We have to
3244 look ahead one more character. */
3245 peek_char = shell_getc (1);
3246 if (peek_char == '-')
3247 return (LESS_LESS_MINUS);
3250 shell_ungetc (peek_char);
3255 return (GREATER_GREATER);
3258 parser_state |= PST_CASEPAT;
3260 parser_state &= ~PST_ALEXPNEXT;
3270 #if defined (DPAREN_ARITHMETIC)
3272 if (reserved_word_acceptable (last_read_token))
3277 sline = line_number;
3278 cmdtyp = parse_arith_cmd (&wval);
3279 if (cmdtyp == 1) /* arithmetic command */
3281 word_desc_to_read = make_word (wval);
3282 word_desc_to_read->flags = W_QUOTED;
3283 token_to_read = WORD;
3285 yylval.word = make_word ("let");
3288 else if (cmdtyp == 0) /* nested subshell */
3290 push_string (wval, 0, (alias_t *)NULL);
3291 if ((parser_state & PST_CASEPAT) == 0)
3292 parser_state |= PST_SUBSHELL;
3302 else if (character == '<' && peek_char == '&')
3304 else if (character == '>' && peek_char == '&')
3305 return (GREATER_AND);
3306 else if (character == '<' && peek_char == '>')
3307 return (LESS_GREATER);
3308 else if (character == '>' && peek_char == '|')
3309 return (GREATER_BAR);
3310 else if (peek_char == '>' && character == '&')
3311 return (AND_GREATER);
3313 shell_ungetc (peek_char);
3315 /* If we look like we are reading the start of a function
3316 definition, then let the reader know about it so that
3317 we will do the right thing with `{'. */
3318 if (character == ')' && last_read_token == '(' && token_before_that == WORD)
3320 parser_state |= PST_ALLOWOPNBRC;
3322 parser_state &= ~PST_ALEXPNEXT;
3324 function_dstart = line_number;
3327 /* case pattern lists may be preceded by an optional left paren. If
3328 we're not trying to parse a case pattern list, the left paren
3329 indicates a subshell. */
3330 if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
3331 parser_state |= PST_SUBSHELL;
3333 else if ((parser_state & PST_CASEPAT) && character == ')')
3334 parser_state &= ~PST_CASEPAT;
3336 else if ((parser_state & PST_SUBSHELL) && character == ')')
3337 parser_state &= ~PST_SUBSHELL;
3339 #if defined (PROCESS_SUBSTITUTION)
3340 /* Check for the constructs which introduce process substitution.
3341 Shells running in `posix mode' don't do process substitution. */
3342 if (posixly_correct ||
3343 ((character != '>' && character != '<') || peek_char != '('))
3344 #endif /* PROCESS_SUBSTITUTION */
3348 /* Hack <&- (close stdin) case. */
3349 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3352 /* Okay, if we got this far, we have to read a word. Read one,
3353 and then check it against the known ones. */
3354 result = read_token_word (character);
3356 if (result == RE_READ_TOKEN)
3362 /* Match a $(...) or other grouping construct. This has to handle embedded
3363 quoted strings ('', ``, "") and nested constructs. It also must handle
3364 reprompting the user, if necessary, after reading a newline, and returning
3365 correct error values if it reads EOF. */
3366 static char matched_pair_error;
3368 parse_matched_pair (qc, open, close, lenp, flags)
3369 int qc; /* `"' if this construct is within double quotes */
3373 int count, ch, was_dollar;
3374 int pass_next_character, nestlen, start_lineno;
3375 char *ret, *nestret;
3376 int retind, retsize;
3379 pass_next_character = was_dollar = 0;
3381 ret = xmalloc (retsize = 64);
3384 start_lineno = line_number;
3387 ch = shell_getc (qc != '\'' && pass_next_character == 0);
3391 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
3392 EOF_Reached = 1; /* XXX */
3393 return (&matched_pair_error);
3396 /* Possible reprompting. */
3397 if (ch == '\n' && interactive &&
3398 (bash_input.type == st_stdin || bash_input.type == st_stream))
3401 if (pass_next_character) /* last char was backslash */
3403 pass_next_character = 0;
3404 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3406 if (retind > 0) retind--; /* swallow previously-added backslash */
3410 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3411 if (ch == CTLESC || ch == CTLNUL)
3412 ret[retind++] = CTLESC;
3416 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3418 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3419 ret[retind++] = CTLESC;
3423 else if (ch == close) /* ending delimiter */
3425 else if (ch == open) /* nested begin */
3428 /* Add this character. */
3429 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3432 if (open == '\'') /* '' inside grouping construct */
3435 if (ch == '\\') /* backslashes */
3436 pass_next_character++;
3438 if (open != close) /* a grouping construct */
3440 if (shellquote (ch))
3442 /* '', ``, or "" inside $(...) or other grouping construct. */
3443 push_delimiter (dstack, ch);
3444 nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
3445 pop_delimiter (dstack);
3446 if (nestret == &matched_pair_error)
3449 return &matched_pair_error;
3453 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3454 strcpy (ret + retind, nestret);
3460 /* Parse an old-style command substitution within double quotes as a
3462 /* XXX - sh and ksh93 don't do this - XXX */
3463 else if (open == '"' && ch == '`')
3465 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
3466 if (nestret == &matched_pair_error)
3469 return &matched_pair_error;
3473 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3474 strcpy (ret + retind, nestret);
3479 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3480 /* check for $(), $[], or ${} inside quoted string. */
3482 if (open == ch) /* undo previous increment */
3484 if (ch == '(') /* ) */
3485 nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
3486 else if (ch == '{') /* } */
3487 nestret = parse_matched_pair (0, '{', '}', &nestlen, 0);
3488 else if (ch == '[') /* ] */
3489 nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
3490 if (nestret == &matched_pair_error)
3493 return &matched_pair_error;
3497 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3498 strcpy (ret + retind, nestret);
3503 was_dollar = (ch == '$');
3512 #if defined (DPAREN_ARITHMETIC)
3513 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
3514 If not, assume it's a nested subshell for backwards compatibility and
3515 return 0. In any case, put the characters we've consumed into a locally-
3516 allocated buffer and make *ep point to that buffer. Return -1 on an
3517 error, for example EOF. */
3519 parse_arith_cmd (ep)
3522 int exp_lineno, rval, c;
3526 exp_lineno = line_number;
3527 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3529 if (ttok == &matched_pair_error)
3531 /* Check that the next character is the closing right paren. If
3532 not, this is a syntax error. ( */
3533 if ((c = shell_getc (0)) != ')')
3536 token = xmalloc(ttoklen + 4);
3538 /* (( ... )) -> "..." */
3539 token[0] = (rval == 1) ? '"' : '(';
3540 strncpy (token + 1, ttok, ttoklen - 1); /* don't copy the final `)' */
3543 token[ttoklen] = '"';
3544 token[ttoklen+1] = '\0';
3548 token[ttoklen] = ')';
3549 token[ttoklen+1] = c;
3550 token[ttoklen+2] = '\0';
3556 #endif /* DPAREN_ARITHMETIC */
3559 read_token_word (character)
3562 /* The value for YYLVAL when a WORD is read. */
3563 WORD_DESC *the_word;
3565 /* Index into the token that we are building. */
3568 /* ALL_DIGITS becomes zero when we see a non-digit. */
3571 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3574 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3577 /* Non-zero means to ignore the value of the next character, and just
3578 to add it no matter what. */
3579 int pass_next_character;
3581 /* The current delimiting character. */
3583 int result, peek_char;
3584 char *ttok, *ttrans;
3585 int ttoklen, ttranslen;
3587 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
3588 token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
3591 all_digits = digit (character);
3592 dollar_present = quoted = pass_next_character = 0;
3596 if (character == EOF)
3599 if (pass_next_character)
3601 pass_next_character = 0;
3605 cd = current_delimiter (dstack);
3607 /* Handle backslashes. Quote lots of things when not inside of
3608 double-quotes, quote some things inside of double-quotes. */
3609 if (character == '\\')
3611 peek_char = shell_getc (0);
3613 /* Backslash-newline is ignored in all cases except
3614 when quoted with single quotes. */
3615 if (peek_char == '\n')
3618 goto next_character;
3622 shell_ungetc (peek_char);
3624 /* If the next character is to be quoted, note it now. */
3625 if (cd == 0 || cd == '`' ||
3626 (cd == '"' && member (peek_char, slashify_in_quotes)))
3627 pass_next_character++;
3634 /* Parse a matched pair of quote characters. */
3635 if (shellquote (character))
3637 push_delimiter (dstack, character);
3638 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
3639 pop_delimiter (dstack);
3640 if (ttok == &matched_pair_error)
3641 return -1; /* Bail immediately. */
3642 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3643 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3644 token[token_index++] = character;
3645 strcpy (token + token_index, ttok);
3646 token_index += ttoklen;
3649 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3651 goto next_character;
3654 /* If the delimiter character is not single quote, parse some of
3655 the shell expansions that must be read as a single word. */
3656 #if defined (PROCESS_SUBSTITUTION)
3657 if (character == '$' || character == '<' || character == '>')
3659 if (character == '$')
3660 #endif /* !PROCESS_SUBSTITUTION */
3662 peek_char = shell_getc (1);
3663 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
3664 if (peek_char == '(' ||
3665 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
3667 if (peek_char == '{') /* } */
3668 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, 0);
3669 else if (peek_char == '(') /* ) */
3671 /* XXX - push and pop the `(' as a delimiter for use by
3672 the command-oriented-history code. This way newlines
3673 appearing in the $(...) string get added to the
3674 history literally rather than causing a possibly-
3675 incorrect `;' to be added. */
3676 push_delimiter (dstack, peek_char);
3677 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3678 pop_delimiter (dstack);
3681 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3682 if (ttok == &matched_pair_error)
3683 return -1; /* Bail immediately. */
3684 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3686 TOKEN_DEFAULT_GROW_SIZE);
3687 token[token_index++] = character;
3688 token[token_index++] = peek_char;
3689 strcpy (token + token_index, ttok);
3690 token_index += ttoklen;
3694 goto next_character;
3696 /* This handles $'...' and $"..." new-style quoted strings. */
3697 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
3699 ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
3700 if (ttok == &matched_pair_error)
3702 if (peek_char == '\'')
3703 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
3705 ttrans = localeexpand (ttok, 0, ttoklen - 1, &ttranslen);
3707 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
3709 TOKEN_DEFAULT_GROW_SIZE);
3710 token[token_index++] = peek_char;
3711 strcpy (token + token_index, ttrans);
3712 token_index += ttranslen;
3713 token[token_index++] = peek_char;
3717 goto next_character;
3720 shell_ungetc (peek_char);
3723 #if defined (ARRAY_VARS)
3724 /* Identify possible compound array variable assignment. */
3725 else if (character == '=' && token_index > 0)
3727 peek_char = shell_getc (1);
3728 if (peek_char == '(') /* ) */
3730 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3731 if (ttok == &matched_pair_error)
3732 return -1; /* Bail immediately. */
3733 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3735 TOKEN_DEFAULT_GROW_SIZE);
3736 token[token_index++] = character;
3737 token[token_index++] = peek_char;
3738 strcpy (token + token_index, ttok);
3739 token_index += ttoklen;
3742 goto next_character;
3745 shell_ungetc (peek_char);
3749 /* When not parsing a multi-character word construct, shell meta-
3750 characters break words. */
3751 if (shellbreak (character))
3753 shell_ungetc (character);
3759 all_digits &= digit (character);
3760 dollar_present |= character == '$';
3762 if (character == CTLESC || character == CTLNUL)
3763 token[token_index++] = CTLESC;
3765 token[token_index++] = character;
3767 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
3768 TOKEN_DEFAULT_GROW_SIZE);
3771 if (character == '\n' && interactive &&
3772 (bash_input.type == st_stdin || bash_input.type == st_stream))
3775 /* We want to remove quoted newlines (that is, a \<newline> pair)
3776 unless we are within single quotes or pass_next_character is
3777 set (the shell equivalent of literal-next). */
3778 cd = current_delimiter (dstack);
3779 character = shell_getc (cd != '\'' && pass_next_character == 0);
3780 } /* end for (;;) */
3784 token[token_index] = '\0';
3786 /* Check to see what thing we should return. If the last_read_token
3787 is a `<', or a `&', or the character which ended this token is
3788 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
3789 Otherwise, it is just a word, and should be returned as such. */
3790 if (all_digits && (character == '<' || character == '>' ||
3791 last_read_token == LESS_AND ||
3792 last_read_token == GREATER_AND))
3794 yylval.number = atoi (token);
3798 /* Check for special case tokens. */
3799 result = special_case_tokens (token);
3804 /* Posix.2 does not allow reserved words to be aliased, so check for all
3805 of them, including special cases, before expanding the current token
3807 if (posixly_correct)
3808 CHECK_FOR_RESERVED_WORD (token);
3810 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
3811 inhibits alias expansion. */
3812 if (expand_aliases && quoted == 0)
3814 result = alias_expand_token (token);
3815 if (result == RE_READ_TOKEN)
3816 return (RE_READ_TOKEN);
3817 else if (result == NO_EXPANSION)
3818 parser_state &= ~PST_ALEXPNEXT;
3821 /* If not in Posix.2 mode, check for reserved words after alias
3823 if (posixly_correct == 0)
3825 CHECK_FOR_RESERVED_WORD (token);
3827 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
3828 the_word->word = xmalloc (1 + token_index);
3829 the_word->flags = 0;
3830 strcpy (the_word->word, token);
3832 the_word->flags |= W_HASDOLLAR;
3834 the_word->flags |= W_QUOTED;
3835 /* A word is an assignment if it appears at the beginning of a
3836 simple command, or after another assignment word. This is
3837 context-dependent, so it cannot be handled in the grammar. */
3838 if (assignment (token))
3840 the_word->flags |= W_ASSIGNMENT;
3841 /* Don't perform word splitting on assignment statements. */
3842 if (assignment_acceptable (last_read_token))
3843 the_word->flags |= W_NOSPLIT;
3846 yylval.word = the_word;
3848 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
3849 ? ASSIGNMENT_WORD : WORD;
3851 if (last_read_token == FUNCTION)
3853 parser_state |= PST_ALLOWOPNBRC;
3854 function_dstart = line_number;
3860 /* $'...' ANSI-C expand the portion of STRING between START and END and
3861 return the result. The result cannot be longer than the input string. */
3863 ansiexpand (string, start, end, lenp)
3865 int start, end, *lenp;
3870 temp = xmalloc (end - start + 1);
3871 for (tlen = 0, len = start; len < end; )
3872 temp[tlen++] = string[len++];
3877 t = ansicstr (temp, tlen, (int *)NULL, lenp);
3889 /* $"..." -- Translate the portion of STRING between START and END
3890 according to current locale using gettext (if available) and return
3891 the result. The caller will take care of leaving the quotes intact.
3892 The string will be left without the leading `$' by the caller.
3893 If translation is performed, the translated string will be double-quoted
3894 by the caller. The length of the translated string is returned in LENP,
3897 localeexpand (string, start, end, lenp)
3899 int start, end, *lenp;
3904 temp = xmalloc (end - start + 1);
3905 for (tlen = 0, len = start; len < end; )
3906 temp[tlen++] = string[len++];
3909 /* If we're just dumping translatable strings, don't do anything. */
3910 if (dump_translatable_strings)
3912 printf ("\"%s\"\n", temp);
3919 t = localetrans (temp, tlen, &len);
3933 /* Return 1 if TOKEN is a token that after being read would allow
3934 a reserved word to be seen, else 0. */
3936 reserved_word_acceptable (token)
3939 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
3940 token == '|' || token == '&' || token == '{' ||
3941 token == '}' || /* XXX */
3944 token == TIME || token == TIMEOPT ||
3951 token == SEMI_SEMI ||
3955 token == DONE || /* XXX these two are experimental */
3963 /* Return the index of TOKEN in the alist of reserved words, or -1 if
3964 TOKEN is not a shell reserved word. */
3966 find_reserved_word (token)
3970 for (i = 0; word_token_alist[i].word; i++)
3971 if (STREQ (token, word_token_alist[i].word))
3977 #if defined (READLINE)
3978 /* Called after each time readline is called. This insures that whatever
3979 the new prompt string is gets propagated to readline's local prompt
3982 reset_readline_prompt ()
3986 if (prompt_string_pointer)
3988 temp_prompt = (*prompt_string_pointer)
3989 ? decode_prompt_string (*prompt_string_pointer)
3992 if (temp_prompt == 0)
3994 temp_prompt = xmalloc (1);
3995 temp_prompt[0] = '\0';
3998 FREE (current_readline_prompt);
3999 current_readline_prompt = temp_prompt;
4002 #endif /* READLINE */
4005 #if defined (HISTORY)
4006 /* A list of tokens which can be followed by newlines, but not by
4007 semi-colons. When concatenating multiple lines of history, the
4008 newline separator for such tokens is replaced with a space. */
4009 static int no_semi_successors[] = {
4010 '\n', '{', '(', ')', ';', '&', '|',
4011 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
4015 /* If we are not within a delimited expression, try to be smart
4016 about which separators can be semi-colons and which must be
4017 newlines. Returns the string that should be added into the
4020 history_delimiting_chars ()
4024 if (dstack.delimiter_depth != 0)
4027 /* First, handle some special cases. */
4029 /* If we just read `()', assume it's a function definition, and don't
4030 add a semicolon. If the token before the `)' was not `(', and we're
4031 not in the midst of parsing a case statement, assume it's a
4032 parenthesized command and add the semicolon. */
4034 if (token_before_that == ')')
4036 if (two_tokens_ago == '(') /*)*/ /* function def */
4038 /* This does not work for subshells inside case statement
4039 command lists. It's a suboptimal solution. */
4040 else if (parser_state & PST_CASESTMT) /* case statement pattern */
4043 return "; "; /* (...) subshell */
4046 for (i = 0; no_semi_successors[i]; i++)
4048 if (token_before_that == no_semi_successors[i])
4054 #endif /* HISTORY */
4056 /* Issue a prompt, or prepare to issue a prompt when the next character
4063 if (!interactive) /* XXX */
4066 ps1_prompt = get_string_value ("PS1");
4067 ps2_prompt = get_string_value ("PS2");
4069 if (!prompt_string_pointer)
4070 prompt_string_pointer = &ps1_prompt;
4072 temp_prompt = *prompt_string_pointer
4073 ? decode_prompt_string (*prompt_string_pointer)
4076 if (temp_prompt == 0)
4078 temp_prompt = xmalloc (1);
4079 temp_prompt[0] = '\0';
4082 current_prompt_string = *prompt_string_pointer;
4083 prompt_string_pointer = &ps2_prompt;
4085 #if defined (READLINE)
4086 if (!no_line_editing)
4088 FREE (current_readline_prompt);
4089 current_readline_prompt = temp_prompt;
4092 #endif /* READLINE */
4094 FREE (current_decoded_prompt);
4095 current_decoded_prompt = temp_prompt;
4102 fprintf (stderr, "%s", current_decoded_prompt);
4106 /* Return a string which will be printed as a prompt. The string
4107 may contain special characters which are decoded as follows:
4110 \e escape (ascii 033)
4111 \d the date in Day Mon Date format
4112 \h the hostname up to the first `.'
4115 \s the name of the shell
4116 \t the time in 24-hour hh:mm:ss format
4117 \T the time in 12-hour hh:mm:ss format
4118 \@ the time in 12-hour am/pm format
4119 \v the version of bash (e.g., 2.00)
4120 \V the release of bash, version + patchlevel (e.g., 2.00.0)
4121 \w the current working directory
4122 \W the last element of $PWD
4124 \# the command number of this command
4125 \! the history number of this command
4126 \$ a $ or a # if you are root
4127 \nnn character code nnn in octal
4129 \[ begin a sequence of non-printing chars
4130 \] end a sequence of non-printing chars
4132 #define PROMPT_GROWTH 48
4134 decode_prompt_string (string)
4139 struct dstack save_dstack;
4140 #if defined (PROMPT_STRING_DECODE)
4141 int result_size, result_index;
4143 char *temp, octal_string[4];
4146 result = xmalloc (result_size = PROMPT_GROWTH);
4147 result[result_index = 0] = 0;
4148 temp = (char *)NULL;
4150 while (c = *string++)
4152 if (posixly_correct && c == '!')
4156 temp = savestring ("!");
4161 #if !defined (HISTORY)
4162 temp = savestring ("1");
4164 temp = itos (history_number ());
4165 #endif /* HISTORY */
4166 string--; /* add_string increments string again. */
4184 strncpy (octal_string, string, 3);
4185 octal_string[3] = '\0';
4187 n = read_octal (octal_string);
4190 if (n == CTLESC || n == CTLNUL)
4216 /* Make the current time/date into a string. */
4217 the_time = time (0);
4218 temp = ctime (&the_time);
4220 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
4221 temp[(c != 'd') ? 8 : 10] = '\0';
4223 /* quick and dirty conversion to 12-hour time */
4224 if (c == 'T' || c == '@')
4228 temp[5] = 'a'; /* am/pm format */
4239 temp[0] = (n / 10) + '0';
4240 temp[1] = (n % 10) + '0';
4242 if (n >= 0 && temp[5] == 'a')
4249 temp[0] = no_line_editing ? '\n' : '\r';
4250 temp[1] = no_line_editing ? '\0' : '\n';
4255 temp = base_pathname (shell_name);
4256 temp = savestring (temp);
4263 strcpy (temp, dist_version);
4265 sprintf (temp, "%s.%d", dist_version, patch_level);
4271 /* Use the value of PWD because it is much more efficient. */
4272 char t_string[PATH_MAX];
4275 temp = get_string_value ("PWD");
4279 if (getcwd (t_string, sizeof(t_string)) == 0)
4285 tlen = strlen (t_string);
4289 tlen = sizeof (t_string) - 1;
4290 strncpy (t_string, temp, tlen);
4292 t_string[tlen] = '\0';
4296 t = strrchr (t_string, '/');
4297 if (t && t != t_string)
4298 strcpy (t_string, t + 1);
4301 /* polite_directory_format is guaranteed to return a string
4302 no longer than PATH_MAX - 1 characters. */
4303 strcpy (t_string, polite_directory_format (t_string));
4305 /* If we're going to be expanding the prompt string later,
4306 quote the directory name. */
4307 if (promptvars || posixly_correct)
4308 temp = backslash_quote (t_string);
4310 temp = savestring (t_string);
4316 temp = savestring (current_user.user_name);
4321 temp = savestring (current_host_name);
4322 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4327 temp = itos (current_command_number);
4331 #if !defined (HISTORY)
4332 temp = savestring ("1");
4334 temp = itos (history_number ());
4335 #endif /* HISTORY */
4340 temp[0] = current_user.euid == 0 ? '#' : '$';
4344 #if defined (READLINE)
4349 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4352 #endif /* READLINE */
4363 temp[0] = (c == 'a') ? '\07' : '\033';
4377 sub_append_string (temp, result, &result_index, &result_size);
4378 temp = (char *)NULL; /* Freed in sub_append_string (). */
4379 result[result_index] = '\0';
4385 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
4386 result[result_index++] = c;
4387 result[result_index] = '\0';
4390 #else /* !PROMPT_STRING_DECODE */
4391 result = savestring (string);
4392 #endif /* !PROMPT_STRING_DECODE */
4394 /* Save the delimiter stack and point `dstack' to temp space so any
4395 command substitutions in the prompt string won't result in screwing
4396 up the parser's quoting state. */
4397 save_dstack = dstack;
4398 dstack = temp_dstack;
4399 dstack.delimiter_depth = 0;
4401 /* Perform variable and parameter expansion and command substitution on
4402 the prompt string. */
4403 if (promptvars || posixly_correct)
4405 list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
4407 result = string_list (list);
4408 dispose_words (list);
4412 t = dequote_string (result);
4417 dstack = save_dstack;
4422 /* Report a syntax error, and restart the parser. Call here for fatal
4427 report_syntax_error ((char *)NULL);
4432 /* Report a syntax error with line numbers, etc.
4433 Call here for recoverable errors. If you have a message to print,
4434 then place it in MESSAGE, otherwise pass NULL and this will figure
4435 out an appropriate message for you. */
4437 report_syntax_error (message)
4446 parser_error (line_number, "%s", message);
4447 if (interactive && EOF_Reached)
4449 last_command_exit_value = EX_USAGE;
4453 /* If the line of input we're reading is not null, try to find the
4454 objectionable token. */
4455 if (shell_input_line && *shell_input_line)
4457 t = shell_input_line;
4458 i = shell_input_line_index;
4461 if (i && t[i] == '\0')
4464 while (i && (whitespace (t[i]) || t[i] == '\n'))
4470 while (i && (member (t[i], " \n\t;|&") == 0))
4473 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4476 /* Print the offending token. */
4477 if (token_end || (i == 0 && token_end == 0))
4481 msg = xmalloc (1 + (token_end - i));
4482 strncpy (msg, t + i, token_end - i);
4483 msg[token_end - i] = '\0';
4485 else /* one-character token */
4492 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
4498 /* If not interactive, print the line containing the error. */
4499 if (interactive == 0)
4501 msg = savestring (shell_input_line);
4502 token_end = strlen (msg);
4503 while (token_end && msg[token_end - 1] == '\n')
4504 msg[--token_end] = '\0';
4506 parser_error (line_number, "`%s'", msg);
4512 msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
4513 parser_error (line_number, "%s", msg);
4514 /* When the shell is interactive, this file uses EOF_Reached
4515 only for error reporting. Other mechanisms are used to
4516 decide whether or not to exit. */
4517 if (interactive && EOF_Reached)
4520 last_command_exit_value = EX_USAGE;
4523 /* ??? Needed function. ??? We have to be able to discard the constructs
4524 created during parsing. In the case of error, we want to return
4525 allocated objects to the memory pool. In the case of no error, we want
4526 to throw away the information about where the allocated objects live.
4527 (dispose_command () will actually free the command. */
4529 discard_parser_constructs (error_p)
4534 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4536 /* A flag denoting whether or not ignoreeof is set. */
4539 /* The number of times that we have encountered an EOF character without
4540 another character intervening. When this gets above the limit, the
4541 shell terminates. */
4542 int eof_encountered = 0;
4544 /* The limit for eof_encountered. */
4545 int eof_encountered_limit = 10;
4547 /* If we have EOF as the only input unit, this user wants to leave
4548 the shell. If the shell is not interactive, then just leave.
4549 Otherwise, if ignoreeof is set, and we haven't done this the
4550 required number of times in a row, print a message. */
4552 handle_eof_input_unit ()
4556 /* shell.c may use this to decide whether or not to write out the
4557 history, among other things. We use it only for error reporting
4562 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4565 if (eof_encountered < eof_encountered_limit)
4567 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
4568 login_shell ? "logout" : "exit");
4570 /* Reset the prompt string to be $PS1. */
4571 prompt_string_pointer = (char **)NULL;
4573 last_read_token = current_token = '\n';
4578 /* In this case EOF should exit the shell. Do it now. */
4580 exit_builtin ((WORD_LIST *)NULL);
4584 /* We don't write history files, etc., for non-interactive shells. */