]> git.ipfire.org Git - thirdparty/bash.git/blob - y.tab.c
Imported from ../bash-2.01.1.tar.gz.
[thirdparty/bash.git] / y.tab.c
1
2 /* A Bison parser, made from /usr/homes/chet/src/bash/bash-2.01.1/parse.y
3 by GNU Bison version 1.25
4 */
5
6 #define YYBISON 1 /* Identify Bison output. */
7
8 #define IF 258
9 #define THEN 259
10 #define ELSE 260
11 #define ELIF 261
12 #define FI 262
13 #define CASE 263
14 #define ESAC 264
15 #define FOR 265
16 #define SELECT 266
17 #define WHILE 267
18 #define UNTIL 268
19 #define DO 269
20 #define DONE 270
21 #define FUNCTION 271
22 #define IN 272
23 #define BANG 273
24 #define TIME 274
25 #define TIMEOPT 275
26 #define WORD 276
27 #define ASSIGNMENT_WORD 277
28 #define NUMBER 278
29 #define AND_AND 279
30 #define OR_OR 280
31 #define GREATER_GREATER 281
32 #define LESS_LESS 282
33 #define LESS_AND 283
34 #define GREATER_AND 284
35 #define SEMI_SEMI 285
36 #define LESS_LESS_MINUS 286
37 #define AND_GREATER 287
38 #define LESS_GREATER 288
39 #define GREATER_BAR 289
40 #define yacc_EOF 290
41
42 #line 21 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
43
44 #include "config.h"
45
46 #include "bashtypes.h"
47 #include "bashansi.h"
48
49 #if defined (HAVE_UNISTD_H)
50 # include <unistd.h>
51 #endif
52
53 #if defined (HAVE_LOCALE_H)
54 # include <locale.h>
55 #endif
56
57 #include <stdio.h>
58 #include <signal.h>
59
60 #include "memalloc.h"
61
62 #include "shell.h"
63 #include "trap.h"
64 #include "flags.h"
65 #include "parser.h"
66 #include "mailcheck.h"
67 #include "builtins/common.h"
68 #include "builtins/builtext.h"
69
70 #if defined (READLINE)
71 # include "bashline.h"
72 # include <readline/readline.h>
73 #endif /* READLINE */
74
75 #if defined (HISTORY)
76 # include "bashhist.h"
77 # include <readline/history.h>
78 #endif /* HISTORY */
79
80 #if defined (JOB_CONTROL)
81 # include "jobs.h"
82 #endif /* JOB_CONTROL */
83
84 #if defined (ALIAS)
85 # include "alias.h"
86 #endif /* ALIAS */
87
88 #if defined (PROMPT_STRING_DECODE)
89 #include <sys/param.h>
90 #include <time.h>
91 #include "maxpath.h"
92 #endif /* PROMPT_STRING_DECODE */
93
94 #define RE_READ_TOKEN -99
95 #define NO_EXPANSION -100
96
97 #define YYDEBUG 0
98
99 extern int eof_encountered;
100 extern int no_line_editing, running_under_emacs;
101 extern int current_command_number;
102 extern int interactive, interactive_shell, login_shell;
103 extern int sourcelevel;
104 extern int posixly_correct;
105 extern int last_command_exit_value;
106 extern int interrupt_immediately;
107 extern char *shell_name, *current_host_name;
108 extern char *dist_version;
109 extern int patch_level;
110 extern int dump_translatable_strings;
111 extern Function *last_shell_builtin, *this_shell_builtin;
112 #if defined (BUFFERED_INPUT)
113 extern int bash_input_fd_changed;
114 #endif
115
116 /* **************************************************************** */
117 /* */
118 /* "Forward" declarations */
119 /* */
120 /* **************************************************************** */
121
122 static char *ansiexpand ();
123 static char *localeexpand ();
124 static int reserved_word_acceptable ();
125 static int read_token ();
126 static int yylex ();
127 static int parse_arith_cmd ();
128 static int read_token_word ();
129 static void discard_parser_constructs ();
130
131 static void report_syntax_error ();
132 static void handle_eof_input_unit ();
133 static void prompt_again ();
134 #if 0
135 static void reset_readline_prompt ();
136 #endif
137 static void print_prompt ();
138
139 extern int yyerror ();
140
141 /* Default prompt strings */
142 char *primary_prompt = PPROMPT;
143 char *secondary_prompt = SPROMPT;
144
145 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
146 char *ps1_prompt, *ps2_prompt;
147
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;
152
153 /* Non-zero means we expand aliases in commands. */
154 int expand_aliases = 0;
155
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. */
160 int promptvars = 1;
161
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;
165
166 /* The number of lines read from input while creating the current command. */
167 int current_command_line_count;
168
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];
172 int need_here_doc;
173
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) */
180
181 /* Either zero or EOF. */
182 static int shell_input_line_terminator;
183
184 /* The line number in a script on which a function definition starts. */
185 static int function_dstart;
186
187 /* The line number in a script on which a function body starts. */
188 static int function_bstart;
189
190 static REDIRECTEE redir;
191
192 #line 171 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
193 typedef union {
194 WORD_DESC *word; /* the word that we read. */
195 int number; /* the number that we read. */
196 WORD_LIST *word_list;
197 COMMAND *command;
198 REDIRECT *redirect;
199 ELEMENT element;
200 PATTERN_LIST *pattern;
201 } YYSTYPE;
202 #include <stdio.h>
203
204 #ifndef __cplusplus
205 #ifndef __STDC__
206 #define const
207 #endif
208 #endif
209
210
211
212 #define YYFINAL 263
213 #define YYFLAG -32768
214 #define YYNTBASE 47
215
216 #define YYTRANSLATE(x) ((unsigned)(x) <= 290 ? yytranslate[x] : 78)
217
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
248 };
249
250 #if YYDEBUG != 0
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,
264 497, 499
265 };
266
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,
318 0
319 };
320
321 #endif
322
323 #if YYDEBUG != 0
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,
337 734, 736
338 };
339 #endif
340
341
342 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
343
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
355 };
356 #endif
357
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,
371 77, 77
372 };
373
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,
387 1, 2
388 };
389
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,
417 0, 0, 0
418 };
419
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
424 };
425
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,
453 236, 237,-32768
454 };
455
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
460 };
461
462
463 #define YYLAST 517
464
465
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
519 };
520
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
574 };
575 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
576 #line 3 "/usr/local/lib/bison.simple"
577
578 /* Skeleton output parser for bison,
579 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
580
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)
584 any later version.
585
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.
590
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. */
594
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. */
599
600 #ifndef alloca
601 #ifdef __GNUC__
602 #define alloca __builtin_alloca
603 #else /* not GNU C. */
604 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
605 #include <alloca.h>
606 #else /* not sparc */
607 #if defined (MSDOS) && !defined (__TURBOC__)
608 #include <malloc.h>
609 #else /* not MSDOS, or __TURBOC__ */
610 #if defined(_AIX)
611 #include <malloc.h>
612 #pragma alloca
613 #else /* not MSDOS, __TURBOC__, or _AIX */
614 #ifdef __hpux
615 #ifdef __cplusplus
616 extern "C" {
617 void *alloca (unsigned int);
618 };
619 #else /* not __cplusplus */
620 void *alloca ();
621 #endif /* not __cplusplus */
622 #endif /* __hpux */
623 #endif /* not _AIX */
624 #endif /* not MSDOS, or __TURBOC__ */
625 #endif /* not sparc. */
626 #endif /* not GNU C. */
627 #endif /* alloca not defined. */
628
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. */
633
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. */
637
638 #define yyerrok (yyerrstatus = 0)
639 #define yyclearin (yychar = YYEMPTY)
640 #define YYEMPTY -2
641 #define YYEOF 0
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) \
652 do \
653 if (yychar == YYEMPTY && yylen == 1) \
654 { yychar = (token), yylval = (value); \
655 yychar1 = YYTRANSLATE (yychar); \
656 YYPOPSTACK; \
657 goto yybackup; \
658 } \
659 else \
660 { yyerror ("syntax error: cannot back up"); YYERROR; } \
661 while (0)
662
663 #define YYTERROR 1
664 #define YYERRCODE 256
665
666 #ifndef YYPURE
667 #define YYLEX yylex()
668 #endif
669
670 #ifdef YYPURE
671 #ifdef YYLSP_NEEDED
672 #ifdef YYLEX_PARAM
673 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
674 #else
675 #define YYLEX yylex(&yylval, &yylloc)
676 #endif
677 #else /* not YYLSP_NEEDED */
678 #ifdef YYLEX_PARAM
679 #define YYLEX yylex(&yylval, YYLEX_PARAM)
680 #else
681 #define YYLEX yylex(&yylval)
682 #endif
683 #endif /* not YYLSP_NEEDED */
684 #endif
685
686 /* If nonreentrant, generate the variables here */
687
688 #ifndef YYPURE
689
690 int yychar; /* the lookahead symbol */
691 YYSTYPE yylval; /* the semantic value of the */
692 /* lookahead symbol */
693
694 #ifdef YYLSP_NEEDED
695 YYLTYPE yylloc; /* location data for the lookahead */
696 /* symbol */
697 #endif
698
699 int yynerrs; /* number of parse errors so far */
700 #endif /* not YYPURE */
701
702 #if YYDEBUG != 0
703 int yydebug; /* nonzero means print parse trace */
704 /* Since this is uninitialized, it does not stop multiple parsers
705 from coexisting. */
706 #endif
707
708 /* YYINITDEPTH indicates the initial size of the parser's stacks */
709
710 #ifndef YYINITDEPTH
711 #define YYINITDEPTH 200
712 #endif
713
714 /* YYMAXDEPTH is the maximum size the stacks can grow to
715 (effective only if the built-in stack extension method is used). */
716
717 #if YYMAXDEPTH == 0
718 #undef YYMAXDEPTH
719 #endif
720
721 #ifndef YYMAXDEPTH
722 #define YYMAXDEPTH 10000
723 #endif
724
725 /* Prevent warning if -Wstrict-prototypes. */
726 #ifdef __GNUC__
727 int yyparse (void);
728 #endif
729 \f
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++ */
733 #ifndef __cplusplus
734
735 /* This is the most reliable way to avoid incompatibilities
736 in available built-in functions on various systems. */
737 static void
738 __yy_memcpy (to, from, count)
739 char *to;
740 char *from;
741 int count;
742 {
743 register char *f = from;
744 register char *t = to;
745 register int i = count;
746
747 while (i-- > 0)
748 *t++ = *f++;
749 }
750
751 #else /* __cplusplus */
752
753 /* This is the most reliable way to avoid incompatibilities
754 in available built-in functions on various systems. */
755 static void
756 __yy_memcpy (char *to, char *from, int count)
757 {
758 register char *f = from;
759 register char *t = to;
760 register int i = count;
761
762 while (i-- > 0)
763 *t++ = *f++;
764 }
765
766 #endif
767 #endif
768 \f
769 #line 196 "/usr/local/lib/bison.simple"
770
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. */
776
777 #ifdef YYPARSE_PARAM
778 #ifdef __cplusplus
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 */
789
790 int
791 yyparse(YYPARSE_PARAM_ARG)
792 YYPARSE_PARAM_DECL
793 {
794 register int yystate;
795 register int yyn;
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 */
800
801 short yyssa[YYINITDEPTH]; /* the state stack */
802 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
803
804 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
805 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
806
807 #ifdef YYLSP_NEEDED
808 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
809 YYLTYPE *yyls = yylsa;
810 YYLTYPE *yylsp;
811
812 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
813 #else
814 #define YYPOPSTACK (yyvsp--, yyssp--)
815 #endif
816
817 int yystacksize = YYINITDEPTH;
818
819 #ifdef YYPURE
820 int yychar;
821 YYSTYPE yylval;
822 int yynerrs;
823 #ifdef YYLSP_NEEDED
824 YYLTYPE yylloc;
825 #endif
826 #endif
827
828 YYSTYPE yyval; /* the variable used to return */
829 /* semantic values from the action */
830 /* routines */
831
832 int yylen;
833
834 #if YYDEBUG != 0
835 if (yydebug)
836 fprintf(stderr, "Starting parse\n");
837 #endif
838
839 yystate = 0;
840 yyerrstatus = 0;
841 yynerrs = 0;
842 yychar = YYEMPTY; /* Cause a token to be read. */
843
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. */
848
849 yyssp = yyss - 1;
850 yyvsp = yyvs;
851 #ifdef YYLSP_NEEDED
852 yylsp = yyls;
853 #endif
854
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. */
858 yynewstate:
859
860 *++yyssp = yystate;
861
862 if (yyssp >= yyss + yystacksize - 1)
863 {
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;
867 short *yyss1 = yyss;
868 #ifdef YYLSP_NEEDED
869 YYLTYPE *yyls1 = yyls;
870 #endif
871
872 /* Get the current used size of the three stacks, in elements. */
873 int size = yyssp - yyss + 1;
874
875 #ifdef yyoverflow
876 /* Each stack pointer address is followed by the size of
877 the data in use in that stack, in bytes. */
878 #ifdef YYLSP_NEEDED
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),
885 &yystacksize);
886 #else
887 yyoverflow("parser stack overflow",
888 &yyss1, size * sizeof (*yyssp),
889 &yyvs1, size * sizeof (*yyvsp),
890 &yystacksize);
891 #endif
892
893 yyss = yyss1; yyvs = yyvs1;
894 #ifdef YYLSP_NEEDED
895 yyls = yyls1;
896 #endif
897 #else /* no yyoverflow */
898 /* Extend the stack our own way. */
899 if (yystacksize >= YYMAXDEPTH)
900 {
901 yyerror("parser stack overflow");
902 return 2;
903 }
904 yystacksize *= 2;
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));
911 #ifdef YYLSP_NEEDED
912 yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
913 __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
914 #endif
915 #endif /* no yyoverflow */
916
917 yyssp = yyss + size - 1;
918 yyvsp = yyvs + size - 1;
919 #ifdef YYLSP_NEEDED
920 yylsp = yyls + size - 1;
921 #endif
922
923 #if YYDEBUG != 0
924 if (yydebug)
925 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
926 #endif
927
928 if (yyssp >= yyss + yystacksize - 1)
929 YYABORT;
930 }
931
932 #if YYDEBUG != 0
933 if (yydebug)
934 fprintf(stderr, "Entering state %d\n", yystate);
935 #endif
936
937 goto yybackup;
938 yybackup:
939
940 /* Do appropriate processing given the current state. */
941 /* Read a lookahead token if we need one and don't already have one. */
942 /* yyresume: */
943
944 /* First try to decide what to do without reference to lookahead token. */
945
946 yyn = yypact[yystate];
947 if (yyn == YYFLAG)
948 goto yydefault;
949
950 /* Not known => get a lookahead token if don't already have one. */
951
952 /* yychar is either YYEMPTY or YYEOF
953 or a valid token in external form. */
954
955 if (yychar == YYEMPTY)
956 {
957 #if YYDEBUG != 0
958 if (yydebug)
959 fprintf(stderr, "Reading a token: ");
960 #endif
961 yychar = YYLEX;
962 }
963
964 /* Convert token to internal form (in yychar1) for indexing tables with */
965
966 if (yychar <= 0) /* This means end of input. */
967 {
968 yychar1 = 0;
969 yychar = YYEOF; /* Don't call YYLEX any more */
970
971 #if YYDEBUG != 0
972 if (yydebug)
973 fprintf(stderr, "Now at end of input.\n");
974 #endif
975 }
976 else
977 {
978 yychar1 = YYTRANSLATE(yychar);
979
980 #if YYDEBUG != 0
981 if (yydebug)
982 {
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. */
986 #ifdef YYPRINT
987 YYPRINT (stderr, yychar, yylval);
988 #endif
989 fprintf (stderr, ")\n");
990 }
991 #endif
992 }
993
994 yyn += yychar1;
995 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
996 goto yydefault;
997
998 yyn = yytable[yyn];
999
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. */
1006
1007 if (yyn < 0)
1008 {
1009 if (yyn == YYFLAG)
1010 goto yyerrlab;
1011 yyn = -yyn;
1012 goto yyreduce;
1013 }
1014 else if (yyn == 0)
1015 goto yyerrlab;
1016
1017 if (yyn == YYFINAL)
1018 YYACCEPT;
1019
1020 /* Shift the lookahead token. */
1021
1022 #if YYDEBUG != 0
1023 if (yydebug)
1024 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
1025 #endif
1026
1027 /* Discard the token being shifted unless it is eof. */
1028 if (yychar != YYEOF)
1029 yychar = YYEMPTY;
1030
1031 *++yyvsp = yylval;
1032 #ifdef YYLSP_NEEDED
1033 *++yylsp = yylloc;
1034 #endif
1035
1036 /* count tokens shifted since error; after three, turn off error status. */
1037 if (yyerrstatus) yyerrstatus--;
1038
1039 yystate = yyn;
1040 goto yynewstate;
1041
1042 /* Do the default action for the current state. */
1043 yydefault:
1044
1045 yyn = yydefact[yystate];
1046 if (yyn == 0)
1047 goto yyerrlab;
1048
1049 /* Do a reduction. yyn is the number of a rule to reduce with. */
1050 yyreduce:
1051 yylen = yyr2[yyn];
1052 if (yylen > 0)
1053 yyval = yyvsp[1-yylen]; /* implement default value of the action */
1054
1055 #if YYDEBUG != 0
1056 if (yydebug)
1057 {
1058 int i;
1059
1060 fprintf (stderr, "Reducing via rule %d (line %d), ",
1061 yyn, yyrline[yyn]);
1062
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]]);
1067 }
1068 #endif
1069
1070
1071 switch (yyn) {
1072
1073 case 1:
1074 #line 215 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1075 {
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);
1081 YYACCEPT;
1082 ;
1083 break;}
1084 case 2:
1085 #line 224 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1086 {
1087 /* Case of regular command, but not a very
1088 interesting one. Return a NULL command. */
1089 global_command = (COMMAND *)NULL;
1090 YYACCEPT;
1091 ;
1092 break;}
1093 case 3:
1094 #line 231 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1095 {
1096 /* Error during parsing. Return NULL command. */
1097 global_command = (COMMAND *)NULL;
1098 eof_encountered = 0;
1099 discard_parser_constructs (1);
1100 if (interactive)
1101 {
1102 YYACCEPT;
1103 }
1104 else
1105 {
1106 YYABORT;
1107 }
1108 ;
1109 break;}
1110 case 4:
1111 #line 246 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1112 {
1113 /* Case of EOF seen by itself. Do ignoreeof or
1114 not. */
1115 global_command = (COMMAND *)NULL;
1116 handle_eof_input_unit ();
1117 YYACCEPT;
1118 ;
1119 break;}
1120 case 5:
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); ;
1123 break;}
1124 case 6:
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); ;
1127 break;}
1128 case 7:
1129 #line 262 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1130 {
1131 redir.filename = yyvsp[0].word;
1132 yyval.redirect = make_redirection (1, r_output_direction, redir);
1133 ;
1134 break;}
1135 case 8:
1136 #line 267 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1137 {
1138 redir.filename = yyvsp[0].word;
1139 yyval.redirect = make_redirection (0, r_input_direction, redir);
1140 ;
1141 break;}
1142 case 9:
1143 #line 272 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1144 {
1145 redir.filename = yyvsp[0].word;
1146 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
1147 ;
1148 break;}
1149 case 10:
1150 #line 277 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1151 {
1152 redir.filename = yyvsp[0].word;
1153 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
1154 ;
1155 break;}
1156 case 11:
1157 #line 282 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1158 {
1159 redir.filename = yyvsp[0].word;
1160 yyval.redirect = make_redirection (1, r_appending_to, redir);
1161 ;
1162 break;}
1163 case 12:
1164 #line 287 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1165 {
1166 redir.filename = yyvsp[0].word;
1167 yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
1168 ;
1169 break;}
1170 case 13:
1171 #line 292 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1172 {
1173 redir.filename = yyvsp[0].word;
1174 yyval.redirect = make_redirection (0, r_reading_until, redir);
1175 redir_stack[need_here_doc++] = yyval.redirect;
1176 ;
1177 break;}
1178 case 14:
1179 #line 298 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1180 {
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;
1184 ;
1185 break;}
1186 case 15:
1187 #line 304 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1188 {
1189 redir.dest = yyvsp[0].number;
1190 yyval.redirect = make_redirection (0, r_duplicating_input, redir);
1191 ;
1192 break;}
1193 case 16:
1194 #line 309 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1195 {
1196 redir.dest = yyvsp[0].number;
1197 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
1198 ;
1199 break;}
1200 case 17:
1201 #line 314 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1202 {
1203 redir.dest = yyvsp[0].number;
1204 yyval.redirect = make_redirection (1, r_duplicating_output, redir);
1205 ;
1206 break;}
1207 case 18:
1208 #line 319 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1209 {
1210 redir.dest = yyvsp[0].number;
1211 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
1212 ;
1213 break;}
1214 case 19:
1215 #line 324 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1216 {
1217 redir.filename = yyvsp[0].word;
1218 yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
1219 ;
1220 break;}
1221 case 20:
1222 #line 329 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1223 {
1224 redir.filename = yyvsp[0].word;
1225 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
1226 ;
1227 break;}
1228 case 21:
1229 #line 334 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1230 {
1231 redir.filename = yyvsp[0].word;
1232 yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
1233 ;
1234 break;}
1235 case 22:
1236 #line 339 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1237 {
1238 redir.filename = yyvsp[0].word;
1239 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
1240 ;
1241 break;}
1242 case 23:
1243 #line 344 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1244 {
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;
1249 ;
1250 break;}
1251 case 24:
1252 #line 351 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1253 {
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;
1258 ;
1259 break;}
1260 case 25:
1261 #line 358 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1262 {
1263 redir.dest = 0L;
1264 yyval.redirect = make_redirection (1, r_close_this, redir);
1265 ;
1266 break;}
1267 case 26:
1268 #line 363 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1269 {
1270 redir.dest = 0L;
1271 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1272 ;
1273 break;}
1274 case 27:
1275 #line 368 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1276 {
1277 redir.dest = 0L;
1278 yyval.redirect = make_redirection (0, r_close_this, redir);
1279 ;
1280 break;}
1281 case 28:
1282 #line 373 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1283 {
1284 redir.dest = 0L;
1285 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1286 ;
1287 break;}
1288 case 29:
1289 #line 378 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1290 {
1291 redir.filename = yyvsp[0].word;
1292 yyval.redirect = make_redirection (1, r_err_and_out, redir);
1293 ;
1294 break;}
1295 case 30:
1296 #line 383 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1297 {
1298 redir.filename = yyvsp[0].word;
1299 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
1300 ;
1301 break;}
1302 case 31:
1303 #line 388 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1304 {
1305 redir.filename = yyvsp[0].word;
1306 yyval.redirect = make_redirection (0, r_input_output, redir);
1307 ;
1308 break;}
1309 case 32:
1310 #line 393 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1311 {
1312 redir.filename = yyvsp[0].word;
1313 yyval.redirect = make_redirection (1, r_output_force, redir);
1314 ;
1315 break;}
1316 case 33:
1317 #line 398 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1318 {
1319 redir.filename = yyvsp[0].word;
1320 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
1321 ;
1322 break;}
1323 case 34:
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; ;
1326 break;}
1327 case 35:
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; ;
1330 break;}
1331 case 36:
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; ;
1334 break;}
1335 case 37:
1336 #line 413 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1337 {
1338 yyval.redirect = yyvsp[0].redirect;
1339 ;
1340 break;}
1341 case 38:
1342 #line 417 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1343 {
1344 register REDIRECT *t;
1345
1346 for (t = yyvsp[-1].redirect; t->next; t = t->next)
1347 ;
1348 t->next = yyvsp[0].redirect;
1349 yyval.redirect = yyvsp[-1].redirect;
1350 ;
1351 break;}
1352 case 39:
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); ;
1355 break;}
1356 case 40:
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); ;
1359 break;}
1360 case 41:
1361 #line 434 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1362 { yyval.command = clean_simple_command (yyvsp[0].command); ;
1363 break;}
1364 case 42:
1365 #line 436 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1366 { yyval.command = yyvsp[0].command; ;
1367 break;}
1368 case 43:
1369 #line 438 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1370 {
1371 COMMAND *tc;
1372
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)
1380 {
1381 tc = tc->value.Function_def->command;
1382 if (tc->type == cm_group)
1383 tc = tc->value.Group->command;
1384 }
1385 if (tc->redirects)
1386 {
1387 register REDIRECT *t;
1388 for (t = tc->redirects; t->next; t = t->next)
1389 ;
1390 t->next = yyvsp[0].redirect;
1391 }
1392 else
1393 tc->redirects = yyvsp[0].redirect;
1394 yyval.command = yyvsp[-1].command;
1395 ;
1396 break;}
1397 case 44:
1398 #line 467 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1399 { yyval.command = yyvsp[0].command; ;
1400 break;}
1401 case 45:
1402 #line 469 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1403 { yyval.command = yyvsp[0].command; ;
1404 break;}
1405 case 46:
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); ;
1408 break;}
1409 case 47:
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); ;
1412 break;}
1413 case 48:
1414 #line 475 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1415 { yyval.command = yyvsp[0].command; ;
1416 break;}
1417 case 49:
1418 #line 477 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1419 { yyval.command = yyvsp[0].command; ;
1420 break;}
1421 case 50:
1422 #line 479 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1423 { yyval.command = yyvsp[0].command; ;
1424 break;}
1425 case 51:
1426 #line 481 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1427 { yyval.command = yyvsp[0].command; ;
1428 break;}
1429 case 52:
1430 #line 483 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1431 { yyval.command = yyvsp[0].command; ;
1432 break;}
1433 case 53:
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); ;
1436 break;}
1437 case 54:
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); ;
1440 break;}
1441 case 55:
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); ;
1444 break;}
1445 case 56:
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); ;
1448 break;}
1449 case 57:
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); ;
1452 break;}
1453 case 58:
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); ;
1456 break;}
1457 case 59:
1458 #line 501 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1459 {
1460 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1461 ;
1462 break;}
1463 case 60:
1464 #line 505 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1465 {
1466 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("$@", (WORD_LIST *)NULL), yyvsp[-1].command);
1467 ;
1468 break;}
1469 case 61:
1470 #line 509 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1471 {
1472 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1473 ;
1474 break;}
1475 case 62:
1476 #line 513 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1477 {
1478 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command);
1479 ;
1480 break;}
1481 case 63:
1482 #line 517 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1483 {
1484 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1485 ;
1486 break;}
1487 case 64:
1488 #line 521 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1489 {
1490 yyval.command = make_select_command (yyvsp[-8].word, (WORD_LIST *)reverse_list (yyvsp[-5].word_list), yyvsp[-1].command);
1491 ;
1492 break;}
1493 case 65:
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); ;
1496 break;}
1497 case 66:
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); ;
1500 break;}
1501 case 67:
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); ;
1504 break;}
1505 case 68:
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); ;
1508 break;}
1509 case 69:
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); ;
1512 break;}
1513 case 70:
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); ;
1516 break;}
1517 case 71:
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; ;
1520 break;}
1521 case 72:
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); ;
1524 break;}
1525 case 73:
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); ;
1528 break;}
1529 case 74:
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); ;
1532 break;}
1533 case 75:
1534 #line 559 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1535 { yyval.command = make_group_command (yyvsp[-1].command); ;
1536 break;}
1537 case 76:
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); ;
1540 break;}
1541 case 77:
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); ;
1544 break;}
1545 case 78:
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); ;
1548 break;}
1549 case 80:
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; ;
1552 break;}
1553 case 81:
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); ;
1556 break;}
1557 case 82:
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); ;
1560 break;}
1561 case 83:
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); ;
1564 break;}
1565 case 84:
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); ;
1568 break;}
1569 case 86:
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; ;
1572 break;}
1573 case 87:
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); ;
1576 break;}
1577 case 88:
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); ;
1580 break;}
1581 case 89:
1582 #line 602 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1583 {
1584 yyval.command = yyvsp[0].command;
1585 if (need_here_doc)
1586 gather_here_documents ();
1587 ;
1588 break;}
1589 case 91:
1590 #line 611 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1591 {
1592 yyval.command = yyvsp[0].command;
1593 ;
1594 break;}
1595 case 93:
1596 #line 618 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1597 {
1598 if (yyvsp[-2].command->type == cm_connection)
1599 yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
1600 else
1601 yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
1602 ;
1603 break;}
1604 case 95:
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); ;
1607 break;}
1608 case 96:
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); ;
1611 break;}
1612 case 97:
1613 #line 633 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1614 {
1615 if (yyvsp[-3].command->type == cm_connection)
1616 yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
1617 else
1618 yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
1619 ;
1620 break;}
1621 case 98:
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, ';'); ;
1624 break;}
1625 case 99:
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, ';'); ;
1628 break;}
1629 case 100:
1630 #line 644 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1631 { yyval.command = yyvsp[0].command; ;
1632 break;}
1633 case 106:
1634 #line 663 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1635 {
1636 yyval.command = yyvsp[0].command;
1637 if (need_here_doc)
1638 gather_here_documents ();
1639 ;
1640 break;}
1641 case 107:
1642 #line 669 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1643 {
1644 if (yyvsp[-1].command->type == cm_connection)
1645 yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
1646 else
1647 yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
1648 if (need_here_doc)
1649 gather_here_documents ();
1650 ;
1651 break;}
1652 case 108:
1653 #line 678 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1654 {
1655 yyval.command = yyvsp[-1].command;
1656 if (need_here_doc)
1657 gather_here_documents ();
1658 ;
1659 break;}
1660 case 109:
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); ;
1663 break;}
1664 case 110:
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); ;
1667 break;}
1668 case 111:
1669 #line 690 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1670 {
1671 if (yyvsp[-2].command->type == cm_connection)
1672 yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
1673 else
1674 yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
1675 ;
1676 break;}
1677 case 112:
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, ';'); ;
1680 break;}
1681 case 113:
1682 #line 700 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1683 { yyval.command = yyvsp[0].command; ;
1684 break;}
1685 case 114:
1686 #line 704 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1687 { yyval.command = yyvsp[0].command; ;
1688 break;}
1689 case 115:
1690 #line 706 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1691 {
1692 yyvsp[0].command->flags |= CMD_INVERT_RETURN;
1693 yyval.command = yyvsp[0].command;
1694 ;
1695 break;}
1696 case 116:
1697 #line 711 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1698 {
1699 yyvsp[0].command->flags |= yyvsp[-1].number;
1700 yyval.command = yyvsp[0].command;
1701 ;
1702 break;}
1703 case 117:
1704 #line 716 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1705 {
1706 yyvsp[0].command->flags |= yyvsp[-2].number;
1707 yyval.command = yyvsp[0].command;
1708 ;
1709 break;}
1710 case 118:
1711 #line 721 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1712 {
1713 yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
1714 yyval.command = yyvsp[0].command;
1715 ;
1716 break;}
1717 case 119:
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, '|'); ;
1720 break;}
1721 case 120:
1722 #line 731 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1723 { yyval.command = yyvsp[0].command; ;
1724 break;}
1725 case 121:
1726 #line 735 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1727 { yyval.number = CMD_TIME_PIPELINE; ;
1728 break;}
1729 case 122:
1730 #line 737 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1731 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; ;
1732 break;}
1733 }
1734 /* the action file gets copied in in place of this dollarsign */
1735 #line 498 "/usr/local/lib/bison.simple"
1736 \f
1737 yyvsp -= yylen;
1738 yyssp -= yylen;
1739 #ifdef YYLSP_NEEDED
1740 yylsp -= yylen;
1741 #endif
1742
1743 #if YYDEBUG != 0
1744 if (yydebug)
1745 {
1746 short *ssp1 = yyss - 1;
1747 fprintf (stderr, "state stack now");
1748 while (ssp1 != yyssp)
1749 fprintf (stderr, " %d", *++ssp1);
1750 fprintf (stderr, "\n");
1751 }
1752 #endif
1753
1754 *++yyvsp = yyval;
1755
1756 #ifdef YYLSP_NEEDED
1757 yylsp++;
1758 if (yylen == 0)
1759 {
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;
1764 yylsp->text = 0;
1765 }
1766 else
1767 {
1768 yylsp->last_line = (yylsp+yylen-1)->last_line;
1769 yylsp->last_column = (yylsp+yylen-1)->last_column;
1770 }
1771 #endif
1772
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. */
1777
1778 yyn = yyr1[yyn];
1779
1780 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1781 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1782 yystate = yytable[yystate];
1783 else
1784 yystate = yydefgoto[yyn - YYNTBASE];
1785
1786 goto yynewstate;
1787
1788 yyerrlab: /* here on detecting error */
1789
1790 if (! yyerrstatus)
1791 /* If not already recovering from an error, report this error. */
1792 {
1793 ++yynerrs;
1794
1795 #ifdef YYERROR_VERBOSE
1796 yyn = yypact[yystate];
1797
1798 if (yyn > YYFLAG && yyn < YYLAST)
1799 {
1800 int size = 0;
1801 char *msg;
1802 int x, count;
1803
1804 count = 0;
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);
1811 if (msg != 0)
1812 {
1813 strcpy(msg, "parse error");
1814
1815 if (count < 5)
1816 {
1817 count = 0;
1818 for (x = (yyn < 0 ? -yyn : 0);
1819 x < (sizeof(yytname) / sizeof(char *)); x++)
1820 if (yycheck[x + yyn] == x)
1821 {
1822 strcat(msg, count == 0 ? ", expecting `" : " or `");
1823 strcat(msg, yytname[x]);
1824 strcat(msg, "'");
1825 count++;
1826 }
1827 }
1828 yyerror(msg);
1829 free(msg);
1830 }
1831 else
1832 yyerror ("parse error; also virtual memory exceeded");
1833 }
1834 else
1835 #endif /* YYERROR_VERBOSE */
1836 yyerror("parse error");
1837 }
1838
1839 goto yyerrlab1;
1840 yyerrlab1: /* here on error raised explicitly by an action */
1841
1842 if (yyerrstatus == 3)
1843 {
1844 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1845
1846 /* return failure if at end of input */
1847 if (yychar == YYEOF)
1848 YYABORT;
1849
1850 #if YYDEBUG != 0
1851 if (yydebug)
1852 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1853 #endif
1854
1855 yychar = YYEMPTY;
1856 }
1857
1858 /* Else will try to reuse lookahead token
1859 after shifting the error token. */
1860
1861 yyerrstatus = 3; /* Each real token shifted decrements this */
1862
1863 goto yyerrhandle;
1864
1865 yyerrdefault: /* current state does not do anything special for the error token. */
1866
1867 #if 0
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;
1872 #endif
1873
1874 yyerrpop: /* pop the current state because it cannot handle the error token */
1875
1876 if (yyssp == yyss) YYABORT;
1877 yyvsp--;
1878 yystate = *--yyssp;
1879 #ifdef YYLSP_NEEDED
1880 yylsp--;
1881 #endif
1882
1883 #if YYDEBUG != 0
1884 if (yydebug)
1885 {
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");
1891 }
1892 #endif
1893
1894 yyerrhandle:
1895
1896 yyn = yypact[yystate];
1897 if (yyn == YYFLAG)
1898 goto yyerrdefault;
1899
1900 yyn += YYTERROR;
1901 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1902 goto yyerrdefault;
1903
1904 yyn = yytable[yyn];
1905 if (yyn < 0)
1906 {
1907 if (yyn == YYFLAG)
1908 goto yyerrpop;
1909 yyn = -yyn;
1910 goto yyreduce;
1911 }
1912 else if (yyn == 0)
1913 goto yyerrpop;
1914
1915 if (yyn == YYFINAL)
1916 YYACCEPT;
1917
1918 #if YYDEBUG != 0
1919 if (yydebug)
1920 fprintf(stderr, "Shifting error token, ");
1921 #endif
1922
1923 *++yyvsp = yylval;
1924 #ifdef YYLSP_NEEDED
1925 *++yylsp = yylloc;
1926 #endif
1927
1928 yystate = yyn;
1929 goto yynewstate;
1930 }
1931 #line 739 "/usr/homes/chet/src/bash/bash-2.01.1/parse.y"
1932
1933
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 */
1943
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
1948
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) == '>')
1954
1955 /* The token currently being read. */
1956 static int current_token;
1957
1958 /* The last read token, or NULL. read_token () uses this for context
1959 checking. */
1960 static int last_read_token;
1961
1962 /* The token read prior to last_read_token. */
1963 static int token_before_that;
1964
1965 /* The token read prior to token_before_that. */
1966 static int two_tokens_ago;
1967
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;
1974
1975 /* The current parser state. */
1976 static int parser_state;
1977
1978 /* Global var is non-zero when end of file has been reached. */
1979 int EOF_Reached = 0;
1980
1981 void
1982 debug_parser (i)
1983 int i;
1984 {
1985 #if YYDEBUG != 0
1986 yydebug = i;
1987 #endif
1988 }
1989
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. */
1997
1998 /* Unconditionally returns end-of-file. */
1999 int
2000 return_EOF ()
2001 {
2002 return (EOF);
2003 }
2004
2005 /* Variable containing the current get and unget functions.
2006 See ./input.h for a clearer description. */
2007 BASH_INPUT bash_input;
2008
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. */
2011 void
2012 initialize_bash_input ()
2013 {
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;
2021 }
2022
2023 /* Set the contents of the current bash input stream from
2024 GET, UNGET, TYPE, NAME, and LOCATION. */
2025 void
2026 init_yy_io (get, unget, type, name, location)
2027 Function *get, *unget;
2028 enum stream_type type;
2029 char *name;
2030 INPUT_STREAM location;
2031 {
2032 bash_input.type = type;
2033 FREE (bash_input.name);
2034 bash_input.name = name ? savestring (name) : (char *)NULL;
2035
2036 /* XXX */
2037 #if defined (CRAY)
2038 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
2039 #else
2040 bash_input.location = location;
2041 #endif
2042 bash_input.getter = get;
2043 bash_input.ungetter = unget;
2044 }
2045
2046 /* Call this to get the next character of input. */
2047 int
2048 yy_getc ()
2049 {
2050 return (*(bash_input.getter)) ();
2051 }
2052
2053 /* Call this to unget C. That is, to make C the next character
2054 to be read. */
2055 int
2056 yy_ungetc (c)
2057 int c;
2058 {
2059 return (*(bash_input.ungetter)) (c);
2060 }
2061
2062 #if defined (BUFFERED_INPUT)
2063 int
2064 input_file_descriptor ()
2065 {
2066 switch (bash_input.type)
2067 {
2068 case st_stream:
2069 return (fileno (bash_input.location.file));
2070 case st_bstream:
2071 return (bash_input.location.buffered_fd);
2072 case st_stdin:
2073 default:
2074 return (fileno (stdin));
2075 }
2076 }
2077 #endif /* BUFFERED_INPUT */
2078
2079 /* **************************************************************** */
2080 /* */
2081 /* Let input be read from readline (). */
2082 /* */
2083 /* **************************************************************** */
2084
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;
2089
2090 static int
2091 yy_readline_get ()
2092 {
2093 SigHandler *old_sigint;
2094 int line_len, c;
2095
2096 if (!current_readline_line)
2097 {
2098 if (!bash_readline_initialized)
2099 initialize_readline ();
2100
2101 #if defined (JOB_CONTROL)
2102 if (job_control)
2103 give_terminal_to (shell_pgrp);
2104 #endif /* JOB_CONTROL */
2105
2106 if (signal_is_ignored (SIGINT) == 0)
2107 {
2108 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
2109 interrupt_immediately++;
2110 }
2111
2112 current_readline_line = readline (current_readline_prompt ?
2113 current_readline_prompt : "");
2114
2115 if (signal_is_ignored (SIGINT) == 0)
2116 {
2117 interrupt_immediately--;
2118 set_signal_handler (SIGINT, old_sigint);
2119 }
2120
2121 #if 0
2122 /* Reset the prompt to the decoded value of prompt_string_pointer. */
2123 reset_readline_prompt ();
2124 #endif
2125
2126 if (current_readline_line == 0)
2127 return (EOF);
2128
2129 current_readline_line_index = 0;
2130 line_len = strlen (current_readline_line);
2131
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';
2135 }
2136
2137 if (current_readline_line[current_readline_line_index] == 0)
2138 {
2139 free (current_readline_line);
2140 current_readline_line = (char *)NULL;
2141 return (yy_readline_get ());
2142 }
2143 else
2144 {
2145 c = (unsigned char)current_readline_line[current_readline_line_index++];
2146 return (c);
2147 }
2148 }
2149
2150 static int
2151 yy_readline_unget (c)
2152 int c;
2153 {
2154 if (current_readline_line_index && current_readline_line)
2155 current_readline_line[--current_readline_line_index] = c;
2156 return (c);
2157 }
2158
2159 void
2160 with_input_from_stdin ()
2161 {
2162 INPUT_STREAM location;
2163
2164 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
2165 {
2166 location.string = current_readline_line;
2167 init_yy_io (yy_readline_get, yy_readline_unget,
2168 st_stdin, "readline stdin", location);
2169 }
2170 }
2171
2172 #else /* !READLINE */
2173
2174 void
2175 with_input_from_stdin ()
2176 {
2177 with_input_from_stream (stdin, "stdin");
2178 }
2179 #endif /* !READLINE */
2180
2181 /* **************************************************************** */
2182 /* */
2183 /* Let input come from STRING. STRING is zero terminated. */
2184 /* */
2185 /* **************************************************************** */
2186
2187 static int
2188 yy_string_get ()
2189 {
2190 register char *string;
2191 register int c;
2192
2193 string = bash_input.location.string;
2194 c = EOF;
2195
2196 /* If the string doesn't exist, or is empty, EOF found. */
2197 if (string && *string)
2198 {
2199 c = *(unsigned char *)string++;
2200 bash_input.location.string = string;
2201 }
2202 return (c);
2203 }
2204
2205 static int
2206 yy_string_unget (c)
2207 int c;
2208 {
2209 *(--bash_input.location.string) = c;
2210 return (c);
2211 }
2212
2213 void
2214 with_input_from_string (string, name)
2215 char *string, *name;
2216 {
2217 INPUT_STREAM location;
2218
2219 location.string = string;
2220 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
2221 }
2222
2223 /* **************************************************************** */
2224 /* */
2225 /* Let input come from STREAM. */
2226 /* */
2227 /* **************************************************************** */
2228
2229 static int
2230 yy_stream_get ()
2231 {
2232 int result = EOF;
2233
2234 if (bash_input.location.file)
2235 {
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 */
2242 }
2243 return (result);
2244 }
2245
2246 static int
2247 yy_stream_unget (c)
2248 int c;
2249 {
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 */
2255 }
2256
2257 void
2258 with_input_from_stream (stream, name)
2259 FILE *stream;
2260 char *name;
2261 {
2262 INPUT_STREAM location;
2263
2264 location.file = stream;
2265 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
2266 }
2267
2268 typedef struct stream_saver {
2269 struct stream_saver *next;
2270 BASH_INPUT bash_input;
2271 int line;
2272 #if defined (BUFFERED_INPUT)
2273 BUFFERED_STREAM *bstream;
2274 #endif /* BUFFERED_INPUT */
2275 } STREAM_SAVER;
2276
2277 /* The globally known line number. */
2278 int line_number = 0;
2279
2280 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
2281
2282 void
2283 push_stream (reset_lineno)
2284 int reset_lineno;
2285 {
2286 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
2287
2288 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
2289
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)
2294 {
2295 saver->bstream = buffers[bash_input.location.buffered_fd];
2296 buffers[bash_input.location.buffered_fd] = (BUFFERED_STREAM *)NULL;
2297 }
2298 #endif /* BUFFERED_INPUT */
2299
2300 saver->line = line_number;
2301 bash_input.name = (char *)NULL;
2302 saver->next = stream_list;
2303 stream_list = saver;
2304 EOF_Reached = 0;
2305 if (reset_lineno)
2306 line_number = 0;
2307 }
2308
2309 void
2310 pop_stream ()
2311 {
2312 if (!stream_list)
2313 EOF_Reached = 1;
2314 else
2315 {
2316 STREAM_SAVER *saver = stream_list;
2317
2318 EOF_Reached = 0;
2319 stream_list = stream_list->next;
2320
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);
2326
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)
2333 {
2334 if (bash_input_fd_changed)
2335 {
2336 bash_input_fd_changed = 0;
2337 if (default_buffered_input >= 0)
2338 {
2339 bash_input.location.buffered_fd = default_buffered_input;
2340 saver->bstream->b_fd = default_buffered_input;
2341 }
2342 }
2343 buffers[bash_input.location.buffered_fd] = saver->bstream;
2344 }
2345 #endif /* BUFFERED_INPUT */
2346
2347 line_number = saver->line;
2348
2349 FREE (saver->bash_input.name);
2350 free (saver);
2351 }
2352 }
2353
2354 /* Return 1 if a stream of type TYPE is saved on the stack. */
2355 int
2356 stream_on_stack (type)
2357 enum stream_type type;
2358 {
2359 register STREAM_SAVER *s;
2360
2361 for (s = stream_list; s; s = s->next)
2362 if (s->bash_input.type == type)
2363 return 1;
2364 return 0;
2365 }
2366
2367 /*
2368 * This is used to inhibit alias expansion and reserved word recognition
2369 * inside case statement pattern lists. A `case statement pattern list' is:
2370 *
2371 * everything between the `in' in a `case word in' and the next ')'
2372 * or `esac'
2373 * everything between a `;;' and the next `)' or `esac'
2374 */
2375
2376 #if defined (ALIAS)
2377
2378 #define END_OF_ALIAS 0
2379
2380 /*
2381 * Pseudo-global variables used in implementing token-wise alias expansion.
2382 */
2383
2384 /*
2385 * Pushing and popping strings. This works together with shell_getc to
2386 * implement alias expansion on a per-token basis.
2387 */
2388
2389 typedef struct string_saver {
2390 struct string_saver *next;
2391 int expand_alias; /* Value to set expand_alias to when string is popped. */
2392 char *saved_line;
2393 alias_t *expander; /* alias that caused this line to be pushed. */
2394 int saved_line_size, saved_line_index, saved_line_terminator;
2395 } STRING_SAVER;
2396
2397 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
2398
2399 /*
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.
2406 */
2407 static void
2408 push_string (s, expand, ap)
2409 char *s;
2410 int expand;
2411 alias_t *ap;
2412 {
2413 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
2414
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;
2423
2424 if (ap)
2425 ap->flags |= AL_BEINGEXPANDED;
2426
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;
2432 }
2433
2434 /*
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.
2439 */
2440 static void
2441 pop_string ()
2442 {
2443 STRING_SAVER *t;
2444
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;
2450
2451 if (pushed_string_list->expand_alias)
2452 parser_state |= PST_ALEXPNEXT;
2453 else
2454 parser_state &= ~PST_ALEXPNEXT;
2455
2456 t = pushed_string_list;
2457 pushed_string_list = pushed_string_list->next;
2458
2459 if (t->expander)
2460 t->expander->flags &= ~AL_BEINGEXPANDED;
2461
2462 free ((char *)t);
2463 }
2464
2465 static void
2466 free_string_list ()
2467 {
2468 register STRING_SAVER *t, *t1;
2469
2470 for (t = pushed_string_list; t; )
2471 {
2472 t1 = t->next;
2473 FREE (t->saved_line);
2474 t->expander->flags &= ~AL_BEINGEXPANDED;
2475 free ((char *)t);
2476 t = t1;
2477 }
2478 pushed_string_list = (STRING_SAVER *)NULL;
2479 }
2480
2481 #endif /* ALIAS */
2482
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. */
2487 static char *
2488 read_a_line (remove_quoted_newline)
2489 int remove_quoted_newline;
2490 {
2491 static char *line_buffer = (char *)NULL;
2492 static int buffer_size = 0;
2493 int indx = 0, c, peekc, pass_next;
2494
2495 #if defined (READLINE)
2496 if (interactive && bash_input.type != st_string && no_line_editing)
2497 #else
2498 if (interactive && bash_input.type != st_string)
2499 #endif
2500 print_prompt ();
2501
2502 pass_next = 0;
2503 while (1)
2504 {
2505 c = yy_getc ();
2506
2507 /* Allow immediate exit if interrupted during input. */
2508 QUIT;
2509
2510 if (c == 0)
2511 continue;
2512
2513 /* If there is no more input, then we return NULL. */
2514 if (c == EOF)
2515 {
2516 if (interactive && bash_input.type == st_stream)
2517 clearerr (stdin);
2518 if (indx == 0)
2519 return ((char *)NULL);
2520 c = '\n';
2521 }
2522
2523 /* `+2' in case the final character in the buffer is a newline. */
2524 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
2525
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. */
2532 if (pass_next)
2533 {
2534 line_buffer[indx++] = c;
2535 pass_next = 0;
2536 }
2537 else if (c == '\\' && remove_quoted_newline)
2538 {
2539 peekc = yy_getc ();
2540 if (peekc == '\n')
2541 continue; /* Make the unquoted \<newline> pair disappear. */
2542 else
2543 {
2544 yy_ungetc (peekc);
2545 pass_next = 1;
2546 line_buffer[indx++] = c; /* Preserve the backslash. */
2547 }
2548 }
2549 else
2550 line_buffer[indx++] = c;
2551
2552 if (c == '\n')
2553 {
2554 line_buffer[indx] = '\0';
2555 return (line_buffer);
2556 }
2557 }
2558 }
2559
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. */
2565 char *
2566 read_secondary_line (remove_quoted_newline)
2567 int remove_quoted_newline;
2568 {
2569 prompt_string_pointer = &ps2_prompt;
2570 prompt_again ();
2571 return (read_a_line (remove_quoted_newline));
2572 }
2573
2574 /* **************************************************************** */
2575 /* */
2576 /* YYLEX () */
2577 /* */
2578 /* **************************************************************** */
2579
2580 /* Reserved words. These are only recognized as the first word of a
2581 command. */
2582 STRING_INT_ALIST word_token_alist[] = {
2583 { "if", IF },
2584 { "then", THEN },
2585 { "else", ELSE },
2586 { "elif", ELIF },
2587 { "fi", FI },
2588 { "case", CASE },
2589 { "esac", ESAC },
2590 { "for", FOR },
2591 #if defined (SELECT_COMMAND)
2592 { "select", SELECT },
2593 #endif
2594 { "while", WHILE },
2595 { "until", UNTIL },
2596 { "do", DO },
2597 { "done", DONE },
2598 { "in", IN },
2599 { "function", FUNCTION },
2600 #if defined (COMMAND_TIMING)
2601 { "time", TIME },
2602 #endif
2603 { "{", '{' },
2604 { "}", '}' },
2605 { "!", BANG },
2606 { (char *)NULL, 0}
2607 };
2608
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. */
2611
2612 /* The primary delimiter stack. */
2613 struct dstack dstack = { (char *)NULL, 0, 0 };
2614
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 };
2619
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)
2624
2625 #define push_delimiter(ds, character) \
2626 do \
2627 { \
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++; \
2633 } \
2634 while (0)
2635
2636 #define pop_delimiter(ds) ds.delimiter_depth--
2637
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. */
2642
2643 static int
2644 shell_getc (remove_quoted_newline)
2645 int remove_quoted_newline;
2646 {
2647 register int i;
2648 int c;
2649 static int mustpop = 0;
2650
2651 QUIT;
2652
2653 #if defined (ALIAS)
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. */
2657
2658 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2659 (pushed_string_list == (STRING_SAVER *)NULL)))
2660 #else /* !ALIAS */
2661 if (!shell_input_line || !shell_input_line[shell_input_line_index])
2662 #endif /* !ALIAS */
2663 {
2664 line_number++;
2665
2666 restart_read:
2667
2668 /* Allow immediate exit if interrupted during input. */
2669 QUIT;
2670
2671 i = 0;
2672 shell_input_line_terminator = 0;
2673
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 */
2683
2684 #if defined (READLINE)
2685 if (interactive && bash_input.type != st_string && no_line_editing)
2686 #else
2687 if (interactive && bash_input.type != st_string)
2688 #endif
2689 print_prompt ();
2690
2691 if (bash_input.type == st_stream)
2692 clearerr (stdin);
2693
2694 while (c = yy_getc ())
2695 {
2696 /* Allow immediate exit if interrupted during input. */
2697 QUIT;
2698
2699 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
2700
2701 if (c == EOF)
2702 {
2703 if (bash_input.type == st_stream)
2704 clearerr (stdin);
2705
2706 if (i == 0)
2707 shell_input_line_terminator = EOF;
2708
2709 shell_input_line[i] = '\0';
2710 break;
2711 }
2712
2713 shell_input_line[i++] = c;
2714
2715 if (c == '\n')
2716 {
2717 shell_input_line[--i] = '\0';
2718 current_command_line_count++;
2719 break;
2720 }
2721 }
2722 shell_input_line_index = 0;
2723 shell_input_line_len = i; /* == strlen (shell_input_line) */
2724
2725 #if defined (HISTORY)
2726 if (remember_on_history && shell_input_line && shell_input_line[0])
2727 {
2728 char *expansions;
2729 # if defined (BANG_HISTORY)
2730 int old_hist;
2731
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;
2738 # endif
2739 expansions = pre_process_line (shell_input_line, 1, 1);
2740 # if defined (BANG_HISTORY)
2741 history_expansion_inhibited = old_hist;
2742 # endif
2743 if (expansions != shell_input_line)
2744 {
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--;
2751
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;
2755 }
2756 }
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))
2761 {
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);
2767 }
2768
2769 #endif /* HISTORY */
2770
2771 if (shell_input_line)
2772 {
2773 /* Lines that signify the end of the shell's input should not be
2774 echoed. */
2775 if (echo_input_at_read && (shell_input_line[0] ||
2776 shell_input_line_terminator != EOF))
2777 fprintf (stderr, "%s\n", shell_input_line);
2778 }
2779 else
2780 {
2781 shell_input_line_size = 0;
2782 prompt_string_pointer = &current_prompt_string;
2783 prompt_again ();
2784 goto restart_read;
2785 }
2786
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)
2790 {
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));
2794
2795 shell_input_line[shell_input_line_len] = '\n';
2796 shell_input_line[shell_input_line_len + 1] = '\0';
2797 }
2798 }
2799
2800 c = shell_input_line[shell_input_line_index];
2801
2802 if (c)
2803 shell_input_line_index++;
2804
2805 if (c == '\\' && remove_quoted_newline &&
2806 shell_input_line[shell_input_line_index] == '\n')
2807 {
2808 prompt_again ();
2809 line_number++;
2810 goto restart_read;
2811 }
2812
2813 #if defined (ALIAS)
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
2818 to. */
2819 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
2820 {
2821 if (mustpop)
2822 {
2823 pop_string ();
2824 c = shell_input_line[shell_input_line_index];
2825 if (c)
2826 shell_input_line_index++;
2827 mustpop--;
2828 }
2829 else
2830 {
2831 mustpop++;
2832 c = ' ';
2833 }
2834 }
2835 #endif /* ALIAS */
2836
2837 if (!c && shell_input_line_terminator == EOF)
2838 return ((shell_input_line_index != 0) ? '\n' : EOF);
2839
2840 return ((unsigned char)c);
2841 }
2842
2843 /* Put C back into the input for the shell. */
2844 static void
2845 shell_ungetc (c)
2846 int c;
2847 {
2848 if (shell_input_line && shell_input_line_index)
2849 shell_input_line[--shell_input_line_index] = c;
2850 }
2851
2852 static void
2853 shell_ungetchar ()
2854 {
2855 if (shell_input_line && shell_input_line_index)
2856 shell_input_line_index--;
2857 }
2858
2859 /* Discard input until CHARACTER is seen, then push that character back
2860 onto the input stream. */
2861 static void
2862 discard_until (character)
2863 int character;
2864 {
2865 int c;
2866
2867 while ((c = shell_getc (0)) != EOF && c != character)
2868 ;
2869
2870 if (c != EOF)
2871 shell_ungetc (c);
2872 }
2873
2874 void
2875 execute_prompt_command (command)
2876 char *command;
2877 {
2878 Function *temp_last, *temp_this;
2879 char *last_lastarg;
2880 int temp_exit_value, temp_eof_encountered;
2881
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 ("_");
2887 if (last_lastarg)
2888 last_lastarg = savestring (last_lastarg);
2889
2890 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
2891
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;
2896
2897 bind_variable ("_", last_lastarg);
2898 FREE (last_lastarg);
2899
2900 if (token_to_read == '\n') /* reset_parser was called */
2901 token_to_read = 0;
2902 }
2903
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;
2907
2908 /* Current size of the token buffer. */
2909 static int token_buffer_size;
2910
2911 /* Command to read_token () explaining what we want it to do. */
2912 #define READ 0
2913 #define RESET 1
2914 #define prompt_is_ps1 \
2915 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2916
2917 /* Function for yyparse to call. yylex keeps track of
2918 the last two tokens read, and calls read_token. */
2919 static int
2920 yylex ()
2921 {
2922 if (interactive && (current_token == 0 || current_token == '\n'))
2923 {
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 ())
2929 {
2930 check_mail ();
2931 reset_mail_timer ();
2932 }
2933
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)
2937 prompt_again ();
2938 }
2939
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);
2945 }
2946
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;
2950
2951 void
2952 gather_here_documents ()
2953 {
2954 int r = 0;
2955 while (need_here_doc)
2956 {
2957 make_here_document (redir_stack[r++]);
2958 need_here_doc--;
2959 }
2960 }
2961
2962 /* When non-zero, an open-brace used to create a group is awaiting a close
2963 brace partner. */
2964 static int open_brace_count;
2965
2966 #define command_token_position(token) \
2967 (((token) == ASSIGNMENT_WORD) || \
2968 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
2969
2970 #define assignment_acceptable(token) command_token_position(token) && \
2971 ((parser_state & PST_CASEPAT) == 0)
2972
2973 /* Check to see if TOKEN is a reserved word and return the token
2974 value if it is. */
2975 #define CHECK_FOR_RESERVED_WORD(tok) \
2976 do { \
2977 if (!dollar_present && !quoted && \
2978 reserved_word_acceptable (last_read_token)) \
2979 { \
2980 int i; \
2981 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2982 if (STREQ (tok, word_token_alist[i].word)) \
2983 { \
2984 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
2985 break; \
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); \
2995 } \
2996 } \
2997 } while (0)
2998
2999 #if defined (ALIAS)
3000
3001 /* OK, we have a token. Let's try to alias expand it, if (and only if)
3002 it's eligible.
3003
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
3009 processed alias.
3010
3011 Special cases that disqualify:
3012 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
3013 static int
3014 alias_expand_token (token)
3015 char *token;
3016 {
3017 char *expanded;
3018 alias_t *ap;
3019
3020 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
3021 (parser_state & PST_CASEPAT) == 0)
3022 {
3023 ap = find_alias (token);
3024
3025 /* Currently expanding this token. */
3026 if (ap && (ap->flags & AL_BEINGEXPANDED))
3027 return (NO_EXPANSION);
3028
3029 expanded = ap ? savestring (ap->value) : (char *)NULL;
3030 if (expanded)
3031 {
3032 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
3033 return (RE_READ_TOKEN);
3034 }
3035 else
3036 /* This is an eligible token that does not have an expansion. */
3037 return (NO_EXPANSION);
3038 }
3039 return (NO_EXPANSION);
3040 }
3041 #endif /* ALIAS */
3042
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.
3046
3047 DO is recognized if the last token was WORD and the token
3048 before that was FOR or SELECT.
3049
3050 ESAC is recognized if the last token caused `esacs_needed_count'
3051 to be set
3052
3053 `{' is recognized if the last token as WORD and the token
3054 before that was FUNCTION.
3055
3056 `}' is recognized if there is an unclosed `{' prsent.
3057 */
3058
3059 static int
3060 special_case_tokens (token)
3061 char *token;
3062 {
3063 if ((last_read_token == WORD) &&
3064 #if defined (SELECT_COMMAND)
3065 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3066 #else
3067 ((token_before_that == FOR) || (token_before_that == CASE)) &&
3068 #endif
3069 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
3070 {
3071 if (token_before_that == CASE)
3072 {
3073 parser_state |= PST_CASEPAT;
3074 esacs_needed_count++;
3075 }
3076 return (IN);
3077 }
3078
3079 if (last_read_token == WORD &&
3080 #if defined (SELECT_COMMAND)
3081 (token_before_that == FOR || token_before_that == SELECT) &&
3082 #else
3083 (token_before_that == FOR) &&
3084 #endif
3085 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
3086 return (DO);
3087
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)
3095 {
3096 esacs_needed_count--;
3097 if (STREQ (token, "esac"))
3098 {
3099 parser_state &= ~PST_CASEPAT;
3100 return (ESAC);
3101 }
3102 }
3103
3104 /* The start of a shell function definition. */
3105 if (parser_state & PST_ALLOWOPNBRC)
3106 {
3107 parser_state &= ~PST_ALLOWOPNBRC;
3108 if (token[0] == '{' && token[1] == '\0') /* } */
3109 {
3110 open_brace_count++;
3111 function_bstart = line_number;
3112 return ('{'); /* } */
3113 }
3114 }
3115
3116 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
3117 {
3118 open_brace_count--; /* { */
3119 return ('}');
3120 }
3121
3122 /* Handle -p after `time'. */
3123 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
3124 return (TIMEOPT);
3125
3126 return (-1);
3127 }
3128
3129 /* Called from shell.c when Control-C is typed at top level. Or
3130 by the error rule at top level. */
3131 void
3132 reset_parser ()
3133 {
3134 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3135 open_brace_count = 0;
3136
3137 parser_state = 0;
3138
3139 #if defined (ALIAS)
3140 if (pushed_string_list)
3141 {
3142 free_string_list ();
3143 pushed_string_list = (STRING_SAVER *)NULL;
3144 }
3145 #endif /* ALIAS */
3146
3147 if (shell_input_line)
3148 {
3149 free (shell_input_line);
3150 shell_input_line = (char *)NULL;
3151 shell_input_line_size = shell_input_line_index = 0;
3152 }
3153
3154 FREE (word_desc_to_read);
3155 word_desc_to_read = (WORD_DESC *)NULL;
3156
3157 last_read_token = '\n';
3158 token_to_read = '\n';
3159 }
3160
3161 /* Read the next token. Command can be READ (normal operation) or
3162 RESET (to normalize state). */
3163 static int
3164 read_token (command)
3165 int command;
3166 {
3167 int character; /* Current character. */
3168 int peek_char; /* Temporary look-ahead character. */
3169 int result; /* The thing to return. */
3170
3171 if (command == RESET)
3172 {
3173 reset_parser ();
3174 return ('\n');
3175 }
3176
3177 if (token_to_read)
3178 {
3179 result = token_to_read;
3180 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3181 {
3182 yylval.word = word_desc_to_read;
3183 word_desc_to_read = (WORD_DESC *)NULL;
3184 }
3185 token_to_read = 0;
3186 return (result);
3187 }
3188
3189 #if defined (ALIAS)
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 () */
3192 re_read_token:
3193 #endif /* ALIAS */
3194
3195 /* Read a single word from input. Start by skipping blanks. */
3196 while ((character = shell_getc (1)) != EOF && whitespace (character))
3197 ;
3198
3199 if (character == EOF)
3200 {
3201 EOF_Reached = 1;
3202 return (yacc_EOF);
3203 }
3204
3205 if (character == '#' && (!interactive || interactive_comments))
3206 {
3207 /* A comment. Discard until EOL or EOF, and then return a newline. */
3208 discard_until ('\n');
3209 shell_getc (0);
3210 character = '\n'; /* this will take the next if statement and return. */
3211 }
3212
3213 if (character == '\n')
3214 {
3215 /* If we're about to return an unquoted newline, we can go and collect
3216 the text of any pending here document. */
3217 if (need_here_doc)
3218 gather_here_documents ();
3219
3220 #if defined (ALIAS)
3221 parser_state &= ~PST_ALEXPNEXT;
3222 #endif /* ALIAS */
3223
3224 return (character);
3225 }
3226
3227 /* Shell meta-characters. */
3228 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3229 {
3230 #if defined (ALIAS)
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;
3235 #endif /* ALIAS */
3236
3237 peek_char = shell_getc (1);
3238 if (character == peek_char)
3239 {
3240 switch (character)
3241 {
3242 case '<':
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);
3248 else
3249 {
3250 shell_ungetc (peek_char);
3251 return (LESS_LESS);
3252 }
3253
3254 case '>':
3255 return (GREATER_GREATER);
3256
3257 case ';':
3258 parser_state |= PST_CASEPAT;
3259 #if defined (ALIAS)
3260 parser_state &= ~PST_ALEXPNEXT;
3261 #endif /* ALIAS */
3262 return (SEMI_SEMI);
3263
3264 case '&':
3265 return (AND_AND);
3266
3267 case '|':
3268 return (OR_OR);
3269
3270 #if defined (DPAREN_ARITHMETIC)
3271 case '(': /* ) */
3272 if (reserved_word_acceptable (last_read_token))
3273 {
3274 int cmdtyp, sline;
3275 char *wval;
3276
3277 sline = line_number;
3278 cmdtyp = parse_arith_cmd (&wval);
3279 if (cmdtyp == 1) /* arithmetic command */
3280 {
3281 word_desc_to_read = make_word (wval);
3282 word_desc_to_read->flags = W_QUOTED;
3283 token_to_read = WORD;
3284 free (wval);
3285 yylval.word = make_word ("let");
3286 return (WORD);
3287 }
3288 else if (cmdtyp == 0) /* nested subshell */
3289 {
3290 push_string (wval, 0, (alias_t *)NULL);
3291 if ((parser_state & PST_CASEPAT) == 0)
3292 parser_state |= PST_SUBSHELL;
3293 return (character);
3294 }
3295 else /* ERROR */
3296 return -1;
3297 }
3298 break;
3299 #endif
3300 }
3301 }
3302 else if (character == '<' && peek_char == '&')
3303 return (LESS_AND);
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);
3312
3313 shell_ungetc (peek_char);
3314
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)
3319 {
3320 parser_state |= PST_ALLOWOPNBRC;
3321 #if defined (ALIAS)
3322 parser_state &= ~PST_ALEXPNEXT;
3323 #endif /* ALIAS */
3324 function_dstart = line_number;
3325 }
3326
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;
3332 /*(*/
3333 else if ((parser_state & PST_CASEPAT) && character == ')')
3334 parser_state &= ~PST_CASEPAT;
3335 /*(*/
3336 else if ((parser_state & PST_SUBSHELL) && character == ')')
3337 parser_state &= ~PST_SUBSHELL;
3338
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 */
3345 return (character);
3346 }
3347
3348 /* Hack <&- (close stdin) case. */
3349 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
3350 return (character);
3351
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);
3355 #if defined (ALIAS)
3356 if (result == RE_READ_TOKEN)
3357 goto re_read_token;
3358 #endif
3359 return result;
3360 }
3361
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;
3367 static char *
3368 parse_matched_pair (qc, open, close, lenp, flags)
3369 int qc; /* `"' if this construct is within double quotes */
3370 int open, close;
3371 int *lenp, flags;
3372 {
3373 int count, ch, was_dollar;
3374 int pass_next_character, nestlen, start_lineno;
3375 char *ret, *nestret;
3376 int retind, retsize;
3377
3378 count = 1;
3379 pass_next_character = was_dollar = 0;
3380
3381 ret = xmalloc (retsize = 64);
3382 retind = 0;
3383
3384 start_lineno = line_number;
3385 while (count)
3386 {
3387 ch = shell_getc (qc != '\'' && pass_next_character == 0);
3388 if (ch == EOF)
3389 {
3390 free (ret);
3391 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
3392 EOF_Reached = 1; /* XXX */
3393 return (&matched_pair_error);
3394 }
3395
3396 /* Possible reprompting. */
3397 if (ch == '\n' && interactive &&
3398 (bash_input.type == st_stdin || bash_input.type == st_stream))
3399 prompt_again ();
3400
3401 if (pass_next_character) /* last char was backslash */
3402 {
3403 pass_next_character = 0;
3404 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3405 {
3406 if (retind > 0) retind--; /* swallow previously-added backslash */
3407 continue;
3408 }
3409
3410 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3411 if (ch == CTLESC || ch == CTLNUL)
3412 ret[retind++] = CTLESC;
3413 ret[retind++] = ch;
3414 continue;
3415 }
3416 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3417 {
3418 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3419 ret[retind++] = CTLESC;
3420 ret[retind++] = ch;
3421 continue;
3422 }
3423 else if (ch == close) /* ending delimiter */
3424 count--;
3425 else if (ch == open) /* nested begin */
3426 count++;
3427
3428 /* Add this character. */
3429 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3430 ret[retind++] = ch;
3431
3432 if (open == '\'') /* '' inside grouping construct */
3433 continue;
3434
3435 if (ch == '\\') /* backslashes */
3436 pass_next_character++;
3437
3438 if (open != close) /* a grouping construct */
3439 {
3440 if (shellquote (ch))
3441 {
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)
3447 {
3448 free (ret);
3449 return &matched_pair_error;
3450 }
3451 if (nestlen)
3452 {
3453 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3454 strcpy (ret + retind, nestret);
3455 retind += nestlen;
3456 }
3457 FREE (nestret);
3458 }
3459 }
3460 /* Parse an old-style command substitution within double quotes as a
3461 single word. */
3462 /* XXX - sh and ksh93 don't do this - XXX */
3463 else if (open == '"' && ch == '`')
3464 {
3465 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
3466 if (nestret == &matched_pair_error)
3467 {
3468 free (ret);
3469 return &matched_pair_error;
3470 }
3471 if (nestlen)
3472 {
3473 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3474 strcpy (ret + retind, nestret);
3475 retind += nestlen;
3476 }
3477 FREE (nestret);
3478 }
3479 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3480 /* check for $(), $[], or ${} inside quoted string. */
3481 {
3482 if (open == ch) /* undo previous increment */
3483 count--;
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)
3491 {
3492 free (ret);
3493 return &matched_pair_error;
3494 }
3495 if (nestlen)
3496 {
3497 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
3498 strcpy (ret + retind, nestret);
3499 retind += nestlen;
3500 }
3501 FREE (nestret);
3502 }
3503 was_dollar = (ch == '$');
3504 }
3505
3506 ret[retind] = '\0';
3507 if (lenp)
3508 *lenp = retind;
3509 return ret;
3510 }
3511
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. */
3518 static int
3519 parse_arith_cmd (ep)
3520 char **ep;
3521 {
3522 int exp_lineno, rval, c;
3523 char *ttok, *token;
3524 int ttoklen;
3525
3526 exp_lineno = line_number;
3527 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3528 rval = 1;
3529 if (ttok == &matched_pair_error)
3530 return -1;
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)) != ')')
3534 rval = 0;
3535
3536 token = xmalloc(ttoklen + 4);
3537
3538 /* (( ... )) -> "..." */
3539 token[0] = (rval == 1) ? '"' : '(';
3540 strncpy (token + 1, ttok, ttoklen - 1); /* don't copy the final `)' */
3541 if (rval == 1)
3542 {
3543 token[ttoklen] = '"';
3544 token[ttoklen+1] = '\0';
3545 }
3546 else
3547 {
3548 token[ttoklen] = ')';
3549 token[ttoklen+1] = c;
3550 token[ttoklen+2] = '\0';
3551 }
3552 *ep = token;
3553 FREE (ttok);
3554 return rval;
3555 }
3556 #endif /* DPAREN_ARITHMETIC */
3557
3558 static int
3559 read_token_word (character)
3560 int character;
3561 {
3562 /* The value for YYLVAL when a WORD is read. */
3563 WORD_DESC *the_word;
3564
3565 /* Index into the token that we are building. */
3566 int token_index;
3567
3568 /* ALL_DIGITS becomes zero when we see a non-digit. */
3569 int all_digits;
3570
3571 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3572 int dollar_present;
3573
3574 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3575 int quoted;
3576
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;
3580
3581 /* The current delimiting character. */
3582 int cd;
3583 int result, peek_char;
3584 char *ttok, *ttrans;
3585 int ttoklen, ttranslen;
3586
3587 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
3588 token = xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
3589
3590 token_index = 0;
3591 all_digits = digit (character);
3592 dollar_present = quoted = pass_next_character = 0;
3593
3594 for (;;)
3595 {
3596 if (character == EOF)
3597 goto got_token;
3598
3599 if (pass_next_character)
3600 {
3601 pass_next_character = 0;
3602 goto got_character;
3603 }
3604
3605 cd = current_delimiter (dstack);
3606
3607 /* Handle backslashes. Quote lots of things when not inside of
3608 double-quotes, quote some things inside of double-quotes. */
3609 if (character == '\\')
3610 {
3611 peek_char = shell_getc (0);
3612
3613 /* Backslash-newline is ignored in all cases except
3614 when quoted with single quotes. */
3615 if (peek_char == '\n')
3616 {
3617 character = '\n';
3618 goto next_character;
3619 }
3620 else
3621 {
3622 shell_ungetc (peek_char);
3623
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++;
3628
3629 quoted = 1;
3630 goto got_character;
3631 }
3632 }
3633
3634 /* Parse a matched pair of quote characters. */
3635 if (shellquote (character))
3636 {
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;
3647 all_digits = 0;
3648 quoted = 1;
3649 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3650 FREE (ttok);
3651 goto next_character;
3652 }
3653
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 == '>')
3658 #else
3659 if (character == '$')
3660 #endif /* !PROCESS_SUBSTITUTION */
3661 {
3662 peek_char = shell_getc (1);
3663 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
3664 if (peek_char == '(' ||
3665 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
3666 {
3667 if (peek_char == '{') /* } */
3668 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, 0);
3669 else if (peek_char == '(') /* ) */
3670 {
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);
3679 }
3680 else
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,
3685 token_buffer_size,
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;
3691 FREE (ttok);
3692 dollar_present = 1;
3693 all_digits = 0;
3694 goto next_character;
3695 }
3696 /* This handles $'...' and $"..." new-style quoted strings. */
3697 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
3698 {
3699 ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
3700 if (ttok == &matched_pair_error)
3701 return -1;
3702 if (peek_char == '\'')
3703 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
3704 else
3705 ttrans = localeexpand (ttok, 0, ttoklen - 1, &ttranslen);
3706 free (ttok);
3707 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
3708 token_buffer_size,
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;
3714 FREE (ttrans);
3715 quoted = 1;
3716 all_digits = 0;
3717 goto next_character;
3718 }
3719 else
3720 shell_ungetc (peek_char);
3721 }
3722
3723 #if defined (ARRAY_VARS)
3724 /* Identify possible compound array variable assignment. */
3725 else if (character == '=' && token_index > 0)
3726 {
3727 peek_char = shell_getc (1);
3728 if (peek_char == '(') /* ) */
3729 {
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,
3734 token_buffer_size,
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;
3740 FREE (ttok);
3741 all_digits = 0;
3742 goto next_character;
3743 }
3744 else
3745 shell_ungetc (peek_char);
3746 }
3747 #endif
3748
3749 /* When not parsing a multi-character word construct, shell meta-
3750 characters break words. */
3751 if (shellbreak (character))
3752 {
3753 shell_ungetc (character);
3754 goto got_token;
3755 }
3756
3757 got_character:
3758
3759 all_digits &= digit (character);
3760 dollar_present |= character == '$';
3761
3762 if (character == CTLESC || character == CTLNUL)
3763 token[token_index++] = CTLESC;
3764
3765 token[token_index++] = character;
3766
3767 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
3768 TOKEN_DEFAULT_GROW_SIZE);
3769
3770 next_character:
3771 if (character == '\n' && interactive &&
3772 (bash_input.type == st_stdin || bash_input.type == st_stream))
3773 prompt_again ();
3774
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 (;;) */
3781
3782 got_token:
3783
3784 token[token_index] = '\0';
3785
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))
3793 {
3794 yylval.number = atoi (token);
3795 return (NUMBER);
3796 }
3797
3798 /* Check for special case tokens. */
3799 result = special_case_tokens (token);
3800 if (result >= 0)
3801 return result;
3802
3803 #if defined (ALIAS)
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
3806 as an alias. */
3807 if (posixly_correct)
3808 CHECK_FOR_RESERVED_WORD (token);
3809
3810 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
3811 inhibits alias expansion. */
3812 if (expand_aliases && quoted == 0)
3813 {
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;
3819 }
3820
3821 /* If not in Posix.2 mode, check for reserved words after alias
3822 expansion. */
3823 if (posixly_correct == 0)
3824 #endif
3825 CHECK_FOR_RESERVED_WORD (token);
3826
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);
3831 if (dollar_present)
3832 the_word->flags |= W_HASDOLLAR;
3833 if (quoted)
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))
3839 {
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;
3844 }
3845
3846 yylval.word = the_word;
3847
3848 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
3849 ? ASSIGNMENT_WORD : WORD;
3850
3851 if (last_read_token == FUNCTION)
3852 {
3853 parser_state |= PST_ALLOWOPNBRC;
3854 function_dstart = line_number;
3855 }
3856
3857 return (result);
3858 }
3859
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. */
3862 static char *
3863 ansiexpand (string, start, end, lenp)
3864 char *string;
3865 int start, end, *lenp;
3866 {
3867 char *temp, *t;
3868 int len, tlen;
3869
3870 temp = xmalloc (end - start + 1);
3871 for (tlen = 0, len = start; len < end; )
3872 temp[tlen++] = string[len++];
3873 temp[tlen] = '\0';
3874
3875 if (*temp)
3876 {
3877 t = ansicstr (temp, tlen, (int *)NULL, lenp);
3878 free (temp);
3879 return (t);
3880 }
3881 else
3882 {
3883 if (lenp)
3884 *lenp = 0;
3885 return (temp);
3886 }
3887 }
3888
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,
3895 if non-null. */
3896 static char *
3897 localeexpand (string, start, end, lenp)
3898 char *string;
3899 int start, end, *lenp;
3900 {
3901 int len, tlen;
3902 char *temp, *t;
3903
3904 temp = xmalloc (end - start + 1);
3905 for (tlen = 0, len = start; len < end; )
3906 temp[tlen++] = string[len++];
3907 temp[tlen] = '\0';
3908
3909 /* If we're just dumping translatable strings, don't do anything. */
3910 if (dump_translatable_strings)
3911 {
3912 printf ("\"%s\"\n", temp);
3913 if (lenp)
3914 *lenp = tlen;
3915 return (temp);
3916 }
3917 else if (*temp)
3918 {
3919 t = localetrans (temp, tlen, &len);
3920 free (temp);
3921 if (lenp)
3922 *lenp = len;
3923 return (t);
3924 }
3925 else
3926 {
3927 if (lenp)
3928 *lenp = 0;
3929 return (temp);
3930 }
3931 }
3932
3933 /* Return 1 if TOKEN is a token that after being read would allow
3934 a reserved word to be seen, else 0. */
3935 static int
3936 reserved_word_acceptable (token)
3937 int token;
3938 {
3939 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
3940 token == '|' || token == '&' || token == '{' ||
3941 token == '}' || /* XXX */
3942 token == AND_AND ||
3943 token == BANG ||
3944 token == TIME || token == TIMEOPT ||
3945 token == DO ||
3946 token == ELIF ||
3947 token == ELSE ||
3948 token == FI ||
3949 token == IF ||
3950 token == OR_OR ||
3951 token == SEMI_SEMI ||
3952 token == THEN ||
3953 token == UNTIL ||
3954 token == WHILE ||
3955 token == DONE || /* XXX these two are experimental */
3956 token == ESAC ||
3957 token == 0)
3958 return (1);
3959 else
3960 return (0);
3961 }
3962
3963 /* Return the index of TOKEN in the alist of reserved words, or -1 if
3964 TOKEN is not a shell reserved word. */
3965 int
3966 find_reserved_word (token)
3967 char *token;
3968 {
3969 int i;
3970 for (i = 0; word_token_alist[i].word; i++)
3971 if (STREQ (token, word_token_alist[i].word))
3972 return i;
3973 return -1;
3974 }
3975
3976 #if 0
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
3980 variable. */
3981 static void
3982 reset_readline_prompt ()
3983 {
3984 char *temp_prompt;
3985
3986 if (prompt_string_pointer)
3987 {
3988 temp_prompt = (*prompt_string_pointer)
3989 ? decode_prompt_string (*prompt_string_pointer)
3990 : (char *)NULL;
3991
3992 if (temp_prompt == 0)
3993 {
3994 temp_prompt = xmalloc (1);
3995 temp_prompt[0] = '\0';
3996 }
3997
3998 FREE (current_readline_prompt);
3999 current_readline_prompt = temp_prompt;
4000 }
4001 }
4002 #endif /* READLINE */
4003 #endif /* 0 */
4004
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,
4012 0
4013 };
4014
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
4018 history entry. */
4019 char *
4020 history_delimiting_chars ()
4021 {
4022 register int i;
4023
4024 if (dstack.delimiter_depth != 0)
4025 return ("\n");
4026
4027 /* First, handle some special cases. */
4028 /*(*/
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. */
4033 /*)(*/
4034 if (token_before_that == ')')
4035 {
4036 if (two_tokens_ago == '(') /*)*/ /* function def */
4037 return " ";
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 */
4041 return " ";
4042 else
4043 return "; "; /* (...) subshell */
4044 }
4045
4046 for (i = 0; no_semi_successors[i]; i++)
4047 {
4048 if (token_before_that == no_semi_successors[i])
4049 return (" ");
4050 }
4051
4052 return ("; ");
4053 }
4054 #endif /* HISTORY */
4055
4056 /* Issue a prompt, or prepare to issue a prompt when the next character
4057 is read. */
4058 static void
4059 prompt_again ()
4060 {
4061 char *temp_prompt;
4062
4063 if (!interactive) /* XXX */
4064 return;
4065
4066 ps1_prompt = get_string_value ("PS1");
4067 ps2_prompt = get_string_value ("PS2");
4068
4069 if (!prompt_string_pointer)
4070 prompt_string_pointer = &ps1_prompt;
4071
4072 temp_prompt = *prompt_string_pointer
4073 ? decode_prompt_string (*prompt_string_pointer)
4074 : (char *)NULL;
4075
4076 if (temp_prompt == 0)
4077 {
4078 temp_prompt = xmalloc (1);
4079 temp_prompt[0] = '\0';
4080 }
4081
4082 current_prompt_string = *prompt_string_pointer;
4083 prompt_string_pointer = &ps2_prompt;
4084
4085 #if defined (READLINE)
4086 if (!no_line_editing)
4087 {
4088 FREE (current_readline_prompt);
4089 current_readline_prompt = temp_prompt;
4090 }
4091 else
4092 #endif /* READLINE */
4093 {
4094 FREE (current_decoded_prompt);
4095 current_decoded_prompt = temp_prompt;
4096 }
4097 }
4098
4099 static void
4100 print_prompt ()
4101 {
4102 fprintf (stderr, "%s", current_decoded_prompt);
4103 fflush (stderr);
4104 }
4105
4106 /* Return a string which will be printed as a prompt. The string
4107 may contain special characters which are decoded as follows:
4108
4109 \a bell (ascii 07)
4110 \e escape (ascii 033)
4111 \d the date in Day Mon Date format
4112 \h the hostname up to the first `.'
4113 \H the hostname
4114 \n CRLF
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
4123 \u your username
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
4128 \\ a backslash
4129 \[ begin a sequence of non-printing chars
4130 \] end a sequence of non-printing chars
4131 */
4132 #define PROMPT_GROWTH 48
4133 char *
4134 decode_prompt_string (string)
4135 char *string;
4136 {
4137 WORD_LIST *list;
4138 char *result, *t;
4139 struct dstack save_dstack;
4140 #if defined (PROMPT_STRING_DECODE)
4141 int result_size, result_index;
4142 int c, n;
4143 char *temp, octal_string[4];
4144 time_t the_time;
4145
4146 result = xmalloc (result_size = PROMPT_GROWTH);
4147 result[result_index = 0] = 0;
4148 temp = (char *)NULL;
4149
4150 while (c = *string++)
4151 {
4152 if (posixly_correct && c == '!')
4153 {
4154 if (*string == '!')
4155 {
4156 temp = savestring ("!");
4157 goto add_string;
4158 }
4159 else
4160 {
4161 #if !defined (HISTORY)
4162 temp = savestring ("1");
4163 #else /* HISTORY */
4164 temp = itos (history_number ());
4165 #endif /* HISTORY */
4166 string--; /* add_string increments string again. */
4167 goto add_string;
4168 }
4169 }
4170 if (c == '\\')
4171 {
4172 c = *string;
4173
4174 switch (c)
4175 {
4176 case '0':
4177 case '1':
4178 case '2':
4179 case '3':
4180 case '4':
4181 case '5':
4182 case '6':
4183 case '7':
4184 strncpy (octal_string, string, 3);
4185 octal_string[3] = '\0';
4186
4187 n = read_octal (octal_string);
4188 temp = xmalloc (3);
4189
4190 if (n == CTLESC || n == CTLNUL)
4191 {
4192 string += 3;
4193 temp[0] = CTLESC;
4194 temp[1] = n;
4195 temp[2] = '\0';
4196 }
4197 else if (n == -1)
4198 {
4199 temp[0] = '\\';
4200 temp[1] = '\0';
4201 }
4202 else
4203 {
4204 string += 3;
4205 temp[0] = n;
4206 temp[1] = '\0';
4207 }
4208
4209 c = 0;
4210 goto add_string;
4211
4212 case 't':
4213 case 'd':
4214 case 'T':
4215 case '@':
4216 /* Make the current time/date into a string. */
4217 the_time = time (0);
4218 temp = ctime (&the_time);
4219
4220 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
4221 temp[(c != 'd') ? 8 : 10] = '\0';
4222
4223 /* quick and dirty conversion to 12-hour time */
4224 if (c == 'T' || c == '@')
4225 {
4226 if (c == '@')
4227 {
4228 temp[5] = 'a'; /* am/pm format */
4229 temp[6] = 'm';
4230 temp[7] = '\0';
4231 }
4232 c = temp[2];
4233 temp[2] = '\0';
4234 n = atoi (temp);
4235 temp[2] = c;
4236 n -= 12;
4237 if (n > 0)
4238 {
4239 temp[0] = (n / 10) + '0';
4240 temp[1] = (n % 10) + '0';
4241 }
4242 if (n >= 0 && temp[5] == 'a')
4243 temp[5] = 'p';
4244 }
4245 goto add_string;
4246
4247 case 'n':
4248 temp = xmalloc (3);
4249 temp[0] = no_line_editing ? '\n' : '\r';
4250 temp[1] = no_line_editing ? '\0' : '\n';
4251 temp[2] = '\0';
4252 goto add_string;
4253
4254 case 's':
4255 temp = base_pathname (shell_name);
4256 temp = savestring (temp);
4257 goto add_string;
4258
4259 case 'v':
4260 case 'V':
4261 temp = xmalloc (8);
4262 if (c == 'v')
4263 strcpy (temp, dist_version);
4264 else
4265 sprintf (temp, "%s.%d", dist_version, patch_level);
4266 goto add_string;
4267
4268 case 'w':
4269 case 'W':
4270 {
4271 /* Use the value of PWD because it is much more efficient. */
4272 char t_string[PATH_MAX];
4273 int tlen;
4274
4275 temp = get_string_value ("PWD");
4276
4277 if (temp == 0)
4278 {
4279 if (getcwd (t_string, sizeof(t_string)) == 0)
4280 {
4281 t_string[0] = '.';
4282 tlen = 1;
4283 }
4284 else
4285 tlen = strlen (t_string);
4286 }
4287 else
4288 {
4289 tlen = sizeof (t_string) - 1;
4290 strncpy (t_string, temp, tlen);
4291 }
4292 t_string[tlen] = '\0';
4293
4294 if (c == 'W')
4295 {
4296 t = strrchr (t_string, '/');
4297 if (t && t != t_string)
4298 strcpy (t_string, t + 1);
4299 }
4300 else
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));
4304
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);
4309 else
4310 temp = savestring (t_string);
4311
4312 goto add_string;
4313 }
4314
4315 case 'u':
4316 temp = savestring (current_user.user_name);
4317 goto add_string;
4318
4319 case 'h':
4320 case 'H':
4321 temp = savestring (current_host_name);
4322 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4323 *t = '\0';
4324 goto add_string;
4325
4326 case '#':
4327 temp = itos (current_command_number);
4328 goto add_string;
4329
4330 case '!':
4331 #if !defined (HISTORY)
4332 temp = savestring ("1");
4333 #else /* HISTORY */
4334 temp = itos (history_number ());
4335 #endif /* HISTORY */
4336 goto add_string;
4337
4338 case '$':
4339 temp = xmalloc (2);
4340 temp[0] = current_user.euid == 0 ? '#' : '$';
4341 temp[1] = '\0';
4342 goto add_string;
4343
4344 #if defined (READLINE)
4345 case '[':
4346 case ']':
4347 temp = xmalloc (3);
4348 temp[0] = '\001';
4349 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4350 temp[2] = '\0';
4351 goto add_string;
4352 #endif /* READLINE */
4353
4354 case '\\':
4355 temp = xmalloc (2);
4356 temp[0] = c;
4357 temp[1] = '\0';
4358 goto add_string;
4359
4360 case 'a':
4361 case 'e':
4362 temp = xmalloc (2);
4363 temp[0] = (c == 'a') ? '\07' : '\033';
4364 temp[1] = '\0';
4365 goto add_string;
4366
4367 default:
4368 temp = xmalloc (3);
4369 temp[0] = '\\';
4370 temp[1] = c;
4371 temp[2] = '\0';
4372
4373 add_string:
4374 if (c)
4375 string++;
4376 result =
4377 sub_append_string (temp, result, &result_index, &result_size);
4378 temp = (char *)NULL; /* Freed in sub_append_string (). */
4379 result[result_index] = '\0';
4380 break;
4381 }
4382 }
4383 else
4384 {
4385 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
4386 result[result_index++] = c;
4387 result[result_index] = '\0';
4388 }
4389 }
4390 #else /* !PROMPT_STRING_DECODE */
4391 result = savestring (string);
4392 #endif /* !PROMPT_STRING_DECODE */
4393
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;
4400
4401 /* Perform variable and parameter expansion and command substitution on
4402 the prompt string. */
4403 if (promptvars || posixly_correct)
4404 {
4405 list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
4406 free (result);
4407 result = string_list (list);
4408 dispose_words (list);
4409 }
4410 else
4411 {
4412 t = dequote_string (result);
4413 free (result);
4414 result = t;
4415 }
4416
4417 dstack = save_dstack;
4418
4419 return (result);
4420 }
4421
4422 /* Report a syntax error, and restart the parser. Call here for fatal
4423 errors. */
4424 int
4425 yyerror ()
4426 {
4427 report_syntax_error ((char *)NULL);
4428 reset_parser ();
4429 return (0);
4430 }
4431
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. */
4436 static void
4437 report_syntax_error (message)
4438 char *message;
4439 {
4440 char *msg, *t;
4441 int token_end, i;
4442 char msg2[2];
4443
4444 if (message)
4445 {
4446 parser_error (line_number, "%s", message);
4447 if (interactive && EOF_Reached)
4448 EOF_Reached = 0;
4449 last_command_exit_value = EX_USAGE;
4450 return;
4451 }
4452
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)
4456 {
4457 t = shell_input_line;
4458 i = shell_input_line_index;
4459 token_end = 0;
4460
4461 if (i && t[i] == '\0')
4462 i--;
4463
4464 while (i && (whitespace (t[i]) || t[i] == '\n'))
4465 i--;
4466
4467 if (i)
4468 token_end = i + 1;
4469
4470 while (i && (member (t[i], " \n\t;|&") == 0))
4471 i--;
4472
4473 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4474 i++;
4475
4476 /* Print the offending token. */
4477 if (token_end || (i == 0 && token_end == 0))
4478 {
4479 if (token_end)
4480 {
4481 msg = xmalloc (1 + (token_end - i));
4482 strncpy (msg, t + i, token_end - i);
4483 msg[token_end - i] = '\0';
4484 }
4485 else /* one-character token */
4486 {
4487 msg2[0] = t[i];
4488 msg2[1] = '\0';
4489 msg = msg2;
4490 }
4491
4492 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
4493
4494 if (msg != msg2)
4495 free (msg);
4496 }
4497
4498 /* If not interactive, print the line containing the error. */
4499 if (interactive == 0)
4500 {
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';
4505
4506 parser_error (line_number, "`%s'", msg);
4507 free (msg);
4508 }
4509 }
4510 else
4511 {
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)
4518 EOF_Reached = 0;
4519 }
4520 last_command_exit_value = EX_USAGE;
4521 }
4522
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. */
4528 static void
4529 discard_parser_constructs (error_p)
4530 int error_p;
4531 {
4532 }
4533
4534 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4535
4536 /* A flag denoting whether or not ignoreeof is set. */
4537 int ignoreeof = 0;
4538
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;
4543
4544 /* The limit for eof_encountered. */
4545 int eof_encountered_limit = 10;
4546
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. */
4551 static void
4552 handle_eof_input_unit ()
4553 {
4554 if (interactive)
4555 {
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
4558 in this file. */
4559 if (EOF_Reached)
4560 EOF_Reached = 0;
4561
4562 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4563 if (ignoreeof)
4564 {
4565 if (eof_encountered < eof_encountered_limit)
4566 {
4567 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
4568 login_shell ? "logout" : "exit");
4569 eof_encountered++;
4570 /* Reset the prompt string to be $PS1. */
4571 prompt_string_pointer = (char **)NULL;
4572 prompt_again ();
4573 last_read_token = current_token = '\n';
4574 return;
4575 }
4576 }
4577
4578 /* In this case EOF should exit the shell. Do it now. */
4579 reset_parser ();
4580 exit_builtin ((WORD_LIST *)NULL);
4581 }
4582 else
4583 {
4584 /* We don't write history files, etc., for non-interactive shells. */
4585 EOF_Reached = 1;
4586 }
4587 }