]> git.ipfire.org Git - thirdparty/bash.git/blob - y.tab.c
367348a8ce3b58831ac6c0ff27e4c96285aabfee
[thirdparty/bash.git] / y.tab.c
1
2 /* A Bison parser, made from /usr/src/local/chet/src/bash/src/parse.y
3 by GNU Bison version 1.28 */
4
5 #define YYBISON 1 /* Identify Bison output. */
6
7 #define IF 257
8 #define THEN 258
9 #define ELSE 259
10 #define ELIF 260
11 #define FI 261
12 #define CASE 262
13 #define ESAC 263
14 #define FOR 264
15 #define SELECT 265
16 #define WHILE 266
17 #define UNTIL 267
18 #define DO 268
19 #define DONE 269
20 #define FUNCTION 270
21 #define COND_START 271
22 #define COND_END 272
23 #define COND_ERROR 273
24 #define IN 274
25 #define BANG 275
26 #define TIME 276
27 #define TIMEOPT 277
28 #define WORD 278
29 #define ASSIGNMENT_WORD 279
30 #define NUMBER 280
31 #define ARITH_CMD 281
32 #define ARITH_FOR_EXPRS 282
33 #define COND_CMD 283
34 #define AND_AND 284
35 #define OR_OR 285
36 #define GREATER_GREATER 286
37 #define LESS_LESS 287
38 #define LESS_AND 288
39 #define LESS_LESS_LESS 289
40 #define GREATER_AND 290
41 #define SEMI_SEMI 291
42 #define LESS_LESS_MINUS 292
43 #define AND_GREATER 293
44 #define LESS_GREATER 294
45 #define GREATER_BAR 295
46 #define yacc_EOF 296
47
48 #line 21 "/usr/src/local/chet/src/bash/src/parse.y"
49
50 #include "config.h"
51
52 #include "bashtypes.h"
53 #include "bashansi.h"
54
55 #include "filecntl.h"
56
57 #if defined (HAVE_UNISTD_H)
58 # include <unistd.h>
59 #endif
60
61 #if defined (HAVE_LOCALE_H)
62 # include <locale.h>
63 #endif
64
65 #include <stdio.h>
66 #include "chartypes.h"
67 #include <signal.h>
68
69 #include "memalloc.h"
70
71 #include "bashintl.h"
72
73 #define NEED_STRFTIME_DECL /* used in externs.h */
74
75 #include "shell.h"
76 #include "trap.h"
77 #include "flags.h"
78 #include "parser.h"
79 #include "mailcheck.h"
80 #include "test.h"
81 #include "builtins.h"
82 #include "builtins/common.h"
83 #include "builtins/builtext.h"
84
85 #include "shmbutil.h"
86
87 #if defined (READLINE)
88 # include "bashline.h"
89 # include <readline/readline.h>
90 #endif /* READLINE */
91
92 #if defined (HISTORY)
93 # include "bashhist.h"
94 # include <readline/history.h>
95 #endif /* HISTORY */
96
97 #if defined (JOB_CONTROL)
98 # include "jobs.h"
99 #endif /* JOB_CONTROL */
100
101 #if defined (ALIAS)
102 # include "alias.h"
103 #else
104 typedef void *alias_t;
105 #endif /* ALIAS */
106
107 #if defined (PROMPT_STRING_DECODE)
108 # ifndef _MINIX
109 # include <sys/param.h>
110 # endif
111 # include <time.h>
112 # if defined (TM_IN_SYS_TIME)
113 # include <sys/types.h>
114 # include <sys/time.h>
115 # endif /* TM_IN_SYS_TIME */
116 # include "maxpath.h"
117 #endif /* PROMPT_STRING_DECODE */
118
119 #define RE_READ_TOKEN -99
120 #define NO_EXPANSION -100
121
122 #ifdef DEBUG
123 # define YYDEBUG 1
124 #else
125 # define YYDEBUG 0
126 #endif
127
128 #if defined (HANDLE_MULTIBYTE)
129 # define last_shell_getc_is_singlebyte \
130 ((shell_input_line_index > 1) \
131 ? shell_input_line_property[shell_input_line_index - 1] \
132 : 1)
133 # define MBTEST(x) ((x) && last_shell_getc_is_singlebyte)
134 #else
135 # define last_shell_getc_is_singlebyte 1
136 # define MBTEST(x) ((x))
137 #endif
138
139 #if defined (EXTENDED_GLOB)
140 extern int extended_glob;
141 #endif
142
143 extern int eof_encountered;
144 extern int no_line_editing, running_under_emacs;
145 extern int current_command_number;
146 extern int sourcelevel;
147 extern int posixly_correct;
148 extern int last_command_exit_value;
149 extern int interrupt_immediately;
150 extern char *shell_name, *current_host_name;
151 extern char *dist_version;
152 extern int patch_level;
153 extern int dump_translatable_strings, dump_po_strings;
154 extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
155 #if defined (BUFFERED_INPUT)
156 extern int bash_input_fd_changed;
157 #endif
158
159 extern int errno;
160 /* **************************************************************** */
161 /* */
162 /* "Forward" declarations */
163 /* */
164 /* **************************************************************** */
165
166 #ifdef DEBUG
167 static void debug_parser __P((int));
168 #endif
169
170 static int yy_getc __P((void));
171 static int yy_ungetc __P((int));
172
173 #if defined (READLINE)
174 static int yy_readline_get __P((void));
175 static int yy_readline_unget __P((int));
176 #endif
177
178 static int yy_string_get __P((void));
179 static int yy_string_unget __P((int));
180 static int yy_stream_get __P((void));
181 static int yy_stream_unget __P((int));
182
183 static int shell_getc __P((int));
184 static void shell_ungetc __P((int));
185 static void discard_until __P((int));
186
187 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
188 static void push_string __P((char *, int, alias_t *));
189 static void pop_string __P((void));
190 static void free_string_list __P((void));
191 #endif
192
193 static char *read_a_line __P((int));
194
195 static int reserved_word_acceptable __P((int));
196 static int yylex __P((void));
197 static int alias_expand_token __P((char *));
198 static int time_command_acceptable __P((void));
199 static int special_case_tokens __P((char *));
200 static int read_token __P((int));
201 static char *parse_matched_pair __P((int, int, int, int *, int));
202 #if defined (ARRAY_VARS)
203 static char *parse_compound_assignment __P((int *));
204 #endif
205 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
206 static int parse_dparen __P((int));
207 static int parse_arith_cmd __P((char **, int));
208 #endif
209 #if defined (COND_COMMAND)
210 static void cond_error __P((void));
211 static COND_COM *cond_expr __P((void));
212 static COND_COM *cond_or __P((void));
213 static COND_COM *cond_and __P((void));
214 static COND_COM *cond_term __P((void));
215 static int cond_skip_newlines __P((void));
216 static COMMAND *parse_cond_command __P((void));
217 #endif
218 #if defined (ARRAY_VARS)
219 static int token_is_assignment __P((char *, int));
220 static int token_is_ident __P((char *, int));
221 #endif
222 static int read_token_word __P((int));
223 static void discard_parser_constructs __P((int));
224
225 static char *error_token_from_token __P((int));
226 static char *error_token_from_text __P((void));
227 static void print_offending_line __P((void));
228 static void report_syntax_error __P((char *));
229
230 static void handle_eof_input_unit __P((void));
231 static void prompt_again __P((void));
232 #if 0
233 static void reset_readline_prompt __P((void));
234 #endif
235 static void print_prompt __P((void));
236
237 #if defined (HISTORY)
238 char *history_delimiting_chars __P((void));
239 #endif
240
241 #if defined (HANDLE_MULTIBYTE)
242 static void set_line_mbstate __P((void));
243 static char *shell_input_line_property = NULL;
244 #else
245 # define set_line_mbstate()
246 #endif
247
248 extern int yyerror __P((const char *));
249
250 #ifdef DEBUG
251 extern int yydebug;
252 #endif
253
254 /* Default prompt strings */
255 char *primary_prompt = PPROMPT;
256 char *secondary_prompt = SPROMPT;
257
258 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
259 char *ps1_prompt, *ps2_prompt;
260
261 /* Handle on the current prompt string. Indirectly points through
262 ps1_ or ps2_prompt. */
263 char **prompt_string_pointer = (char **)NULL;
264 char *current_prompt_string;
265
266 /* Non-zero means we expand aliases in commands. */
267 int expand_aliases = 0;
268
269 /* If non-zero, the decoded prompt string undergoes parameter and
270 variable substitution, command substitution, arithmetic substitution,
271 string expansion, process substitution, and quote removal in
272 decode_prompt_string. */
273 int promptvars = 1;
274
275 /* If non-zero, $'...' and $"..." are expanded when they appear within
276 a ${...} expansion, even when the expansion appears within double
277 quotes. */
278 int extended_quote = 1;
279
280 /* The decoded prompt string. Used if READLINE is not defined or if
281 editing is turned off. Analogous to current_readline_prompt. */
282 static char *current_decoded_prompt;
283
284 /* The number of lines read from input while creating the current command. */
285 int current_command_line_count;
286
287 /* Variables to manage the task of reading here documents, because we need to
288 defer the reading until after a complete command has been collected. */
289 static REDIRECT *redir_stack[10];
290 int need_here_doc;
291
292 /* Where shell input comes from. History expansion is performed on each
293 line when the shell is interactive. */
294 static char *shell_input_line = (char *)NULL;
295 static int shell_input_line_index;
296 static int shell_input_line_size; /* Amount allocated for shell_input_line. */
297 static int shell_input_line_len; /* strlen (shell_input_line) */
298
299 /* Either zero or EOF. */
300 static int shell_input_line_terminator;
301
302 /* The line number in a script on which a function definition starts. */
303 static int function_dstart;
304
305 /* The line number in a script on which a function body starts. */
306 static int function_bstart;
307
308 /* The line number in a script at which an arithmetic for command starts. */
309 static int arith_for_lineno;
310
311 /* The line number in a script where the word in a `case WORD', `select WORD'
312 or `for WORD' begins. This is a nested command maximum, since the array
313 index is decremented after a case, select, or for command is parsed. */
314 #define MAX_CASE_NEST 128
315 static int word_lineno[MAX_CASE_NEST];
316 static int word_top = -1;
317
318 /* If non-zero, it is the token that we want read_token to return
319 regardless of what text is (or isn't) present to be read. This
320 is reset by read_token. If token_to_read == WORD or
321 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
322 static int token_to_read;
323 static WORD_DESC *word_desc_to_read;
324
325 static REDIRECTEE redir;
326
327 #line 300 "/usr/src/local/chet/src/bash/src/parse.y"
328 typedef union {
329 WORD_DESC *word; /* the word that we read. */
330 int number; /* the number that we read. */
331 WORD_LIST *word_list;
332 COMMAND *command;
333 REDIRECT *redirect;
334 ELEMENT element;
335 PATTERN_LIST *pattern;
336 } YYSTYPE;
337 #include <stdio.h>
338
339 #ifndef __cplusplus
340 #ifndef __STDC__
341 #define const
342 #endif
343 #endif
344
345
346
347 #define YYFINAL 302
348 #define YYFLAG -32768
349 #define YYNTBASE 54
350
351 #define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 90)
352
353 static const char yytranslate[] = { 0,
354 2, 2, 2, 2, 2, 2, 2, 2, 2, 44,
355 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
356 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
357 2, 2, 2, 2, 2, 2, 2, 42, 2, 52,
358 53, 2, 2, 2, 49, 2, 2, 2, 2, 2,
359 2, 2, 2, 2, 2, 2, 2, 2, 43, 48,
360 2, 47, 2, 2, 2, 2, 2, 2, 2, 2,
361 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
362 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
363 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
364 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
365 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
366 2, 2, 50, 46, 51, 2, 2, 2, 2, 2,
367 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
368 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
369 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
370 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
371 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
372 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
373 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
374 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
375 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
376 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
377 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
378 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
379 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
380 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
381 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
382 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
383 37, 38, 39, 40, 41, 45
384 };
385
386 #if YYDEBUG != 0
387 static const short yyprhs[] = { 0,
388 0, 3, 5, 8, 10, 12, 15, 18, 21, 25,
389 29, 32, 36, 39, 43, 46, 50, 53, 57, 60,
390 64, 67, 71, 74, 78, 81, 85, 88, 92, 95,
391 99, 102, 106, 109, 112, 116, 118, 120, 122, 124,
392 127, 129, 132, 134, 136, 139, 141, 143, 145, 151,
393 157, 159, 161, 163, 165, 167, 169, 171, 178, 185,
394 193, 201, 212, 223, 233, 243, 251, 259, 265, 271,
395 278, 285, 293, 301, 312, 323, 330, 338, 345, 351,
396 358, 363, 365, 368, 372, 378, 386, 393, 397, 399,
397 403, 408, 415, 421, 423, 426, 431, 436, 442, 448,
398 451, 455, 457, 461, 464, 466, 469, 473, 477, 481,
399 486, 491, 496, 501, 506, 508, 510, 512, 514, 516,
400 518, 519, 522, 524, 527, 530, 535, 540, 544, 548,
401 550, 552, 555, 558, 562, 566, 569, 574, 576, 578
402 };
403
404 static const short yyrhs[] = { 85,
405 82, 0, 44, 0, 1, 44, 0, 45, 0, 24,
406 0, 55, 24, 0, 47, 24, 0, 48, 24, 0,
407 26, 47, 24, 0, 26, 48, 24, 0, 32, 24,
408 0, 26, 32, 24, 0, 33, 24, 0, 26, 33,
409 24, 0, 35, 24, 0, 26, 35, 24, 0, 34,
410 26, 0, 26, 34, 26, 0, 36, 26, 0, 26,
411 36, 26, 0, 34, 24, 0, 26, 34, 24, 0,
412 36, 24, 0, 26, 36, 24, 0, 38, 24, 0,
413 26, 38, 24, 0, 36, 49, 0, 26, 36, 49,
414 0, 34, 49, 0, 26, 34, 49, 0, 39, 24,
415 0, 26, 40, 24, 0, 40, 24, 0, 41, 24,
416 0, 26, 41, 24, 0, 24, 0, 25, 0, 56,
417 0, 56, 0, 58, 56, 0, 57, 0, 59, 57,
418 0, 59, 0, 61, 0, 61, 58, 0, 66, 0,
419 62, 0, 65, 0, 12, 79, 14, 79, 15, 0,
420 13, 79, 14, 79, 15, 0, 64, 0, 69, 0,
421 68, 0, 70, 0, 71, 0, 72, 0, 63, 0,
422 10, 24, 84, 14, 79, 15, 0, 10, 24, 84,
423 50, 79, 51, 0, 10, 24, 43, 84, 14, 79,
424 15, 0, 10, 24, 43, 84, 50, 79, 51, 0,
425 10, 24, 84, 20, 55, 83, 84, 14, 79, 15,
426 0, 10, 24, 84, 20, 55, 83, 84, 50, 79,
427 51, 0, 10, 24, 84, 20, 83, 84, 14, 79,
428 15, 0, 10, 24, 84, 20, 83, 84, 50, 79,
429 51, 0, 10, 28, 83, 84, 14, 79, 15, 0,
430 10, 28, 83, 84, 50, 79, 51, 0, 10, 28,
431 14, 79, 15, 0, 10, 28, 50, 79, 51, 0,
432 11, 24, 84, 14, 78, 15, 0, 11, 24, 84,
433 50, 78, 51, 0, 11, 24, 43, 84, 14, 78,
434 15, 0, 11, 24, 43, 84, 50, 78, 51, 0,
435 11, 24, 84, 20, 55, 83, 84, 14, 78, 15,
436 0, 11, 24, 84, 20, 55, 83, 84, 50, 78,
437 51, 0, 8, 24, 84, 20, 84, 9, 0, 8,
438 24, 84, 20, 76, 84, 9, 0, 8, 24, 84,
439 20, 74, 9, 0, 24, 52, 53, 84, 67, 0,
440 16, 24, 52, 53, 84, 67, 0, 16, 24, 84,
441 67, 0, 61, 0, 61, 58, 0, 52, 79, 53,
442 0, 3, 79, 4, 79, 7, 0, 3, 79, 4,
443 79, 5, 79, 7, 0, 3, 79, 4, 79, 73,
444 7, 0, 50, 79, 51, 0, 27, 0, 17, 29,
445 18, 0, 6, 79, 4, 79, 0, 6, 79, 4,
446 79, 5, 79, 0, 6, 79, 4, 79, 73, 0,
447 75, 0, 76, 75, 0, 84, 77, 53, 79, 0,
448 84, 77, 53, 84, 0, 84, 52, 77, 53, 79,
449 0, 84, 52, 77, 53, 84, 0, 75, 37, 0,
450 76, 75, 37, 0, 24, 0, 77, 46, 24, 0,
451 84, 80, 0, 78, 0, 84, 81, 0, 81, 44,
452 84, 0, 81, 42, 84, 0, 81, 43, 84, 0,
453 81, 30, 84, 81, 0, 81, 31, 84, 81, 0,
454 81, 42, 84, 81, 0, 81, 43, 84, 81, 0,
455 81, 44, 84, 81, 0, 87, 0, 44, 0, 45,
456 0, 44, 0, 43, 0, 45, 0, 0, 84, 44,
457 0, 86, 0, 86, 42, 0, 86, 43, 0, 86,
458 30, 84, 86, 0, 86, 31, 84, 86, 0, 86,
459 42, 86, 0, 86, 43, 86, 0, 87, 0, 88,
460 0, 21, 88, 0, 89, 88, 0, 89, 21, 88,
461 0, 21, 89, 88, 0, 89, 83, 0, 88, 46,
462 84, 88, 0, 60, 0, 22, 0, 22, 23, 0
463 };
464
465 #endif
466
467 #if YYDEBUG != 0
468 static const short yyrline[] = { 0,
469 351, 360, 367, 382, 392, 394, 398, 403, 408, 413,
470 418, 423, 428, 434, 440, 445, 450, 455, 460, 465,
471 470, 475, 480, 485, 490, 497, 504, 509, 514, 519,
472 524, 529, 534, 539, 544, 551, 553, 555, 559, 563,
473 574, 576, 580, 582, 584, 600, 604, 606, 608, 610,
474 612, 614, 616, 618, 620, 622, 624, 628, 633, 638,
475 643, 648, 653, 658, 663, 670, 675, 680, 685, 692,
476 697, 702, 707, 712, 717, 724, 729, 734, 741, 744,
477 747, 752, 754, 785, 792, 794, 796, 801, 805, 809,
478 813, 815, 817, 821, 822, 826, 828, 830, 832, 836,
479 837, 841, 843, 852, 860, 861, 867, 868, 875, 879,
480 881, 883, 890, 892, 894, 898, 899, 902, 904, 906,
481 910, 911, 920, 926, 935, 943, 945, 947, 954, 957,
482 961, 963, 969, 975, 981, 987, 1007, 1010, 1014, 1016
483 };
484 #endif
485
486
487 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
488
489 static const char * const yytname[] = { "$","error","$undefined.","IF","THEN",
490 "ELSE","ELIF","FI","CASE","ESAC","FOR","SELECT","WHILE","UNTIL","DO","DONE",
491 "FUNCTION","COND_START","COND_END","COND_ERROR","IN","BANG","TIME","TIMEOPT",
492 "WORD","ASSIGNMENT_WORD","NUMBER","ARITH_CMD","ARITH_FOR_EXPRS","COND_CMD","AND_AND",
493 "OR_OR","GREATER_GREATER","LESS_LESS","LESS_AND","LESS_LESS_LESS","GREATER_AND",
494 "SEMI_SEMI","LESS_LESS_MINUS","AND_GREATER","LESS_GREATER","GREATER_BAR","'&'",
495 "';'","'\\n'","yacc_EOF","'|'","'>'","'<'","'-'","'{'","'}'","'('","')'","inputunit",
496 "word_list","redirection","simple_command_element","redirection_list","simple_command",
497 "command","shell_command","for_command","arith_for_command","select_command",
498 "case_command","function_def","function_body","subshell","if_command","group_command",
499 "arith_command","cond_command","elif_clause","case_clause","pattern_list","case_clause_sequence",
500 "pattern","list","compound_list","list0","list1","simple_list_terminator","list_terminator",
501 "newline_list","simple_list","simple_list1","pipeline_command","pipeline","timespec", NULL
502 };
503 #endif
504
505 static const short yyr1[] = { 0,
506 54, 54, 54, 54, 55, 55, 56, 56, 56, 56,
507 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
508 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
509 56, 56, 56, 56, 56, 57, 57, 57, 58, 58,
510 59, 59, 60, 60, 60, 60, 61, 61, 61, 61,
511 61, 61, 61, 61, 61, 61, 61, 62, 62, 62,
512 62, 62, 62, 62, 62, 63, 63, 63, 63, 64,
513 64, 64, 64, 64, 64, 65, 65, 65, 66, 66,
514 66, 67, 67, 68, 69, 69, 69, 70, 71, 72,
515 73, 73, 73, 74, 74, 75, 75, 75, 75, 76,
516 76, 77, 77, 78, 79, 79, 80, 80, 80, 81,
517 81, 81, 81, 81, 81, 82, 82, 83, 83, 83,
518 84, 84, 85, 85, 85, 86, 86, 86, 86, 86,
519 87, 87, 87, 87, 87, 87, 88, 88, 89, 89
520 };
521
522 static const short yyr2[] = { 0,
523 2, 1, 2, 1, 1, 2, 2, 2, 3, 3,
524 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
525 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
526 2, 3, 2, 2, 3, 1, 1, 1, 1, 2,
527 1, 2, 1, 1, 2, 1, 1, 1, 5, 5,
528 1, 1, 1, 1, 1, 1, 1, 6, 6, 7,
529 7, 10, 10, 9, 9, 7, 7, 5, 5, 6,
530 6, 7, 7, 10, 10, 6, 7, 6, 5, 6,
531 4, 1, 2, 3, 5, 7, 6, 3, 1, 3,
532 4, 6, 5, 1, 2, 4, 4, 5, 5, 2,
533 3, 1, 3, 2, 1, 2, 3, 3, 3, 4,
534 4, 4, 4, 4, 1, 1, 1, 1, 1, 1,
535 0, 2, 1, 2, 2, 4, 4, 3, 3, 1,
536 1, 2, 2, 3, 3, 2, 4, 1, 1, 2
537 };
538
539 static const short yydefact[] = { 0,
540 0, 121, 0, 0, 0, 121, 121, 0, 0, 0,
541 139, 36, 37, 0, 89, 0, 0, 0, 0, 0,
542 0, 0, 0, 0, 2, 4, 0, 0, 121, 121,
543 38, 41, 43, 138, 44, 47, 57, 51, 48, 46,
544 53, 52, 54, 55, 56, 0, 123, 130, 131, 0,
545 3, 105, 0, 0, 121, 121, 0, 121, 0, 0,
546 121, 0, 132, 0, 140, 0, 0, 0, 0, 0,
547 0, 0, 0, 0, 0, 0, 11, 13, 21, 17,
548 29, 15, 23, 19, 27, 25, 31, 33, 34, 7,
549 8, 0, 0, 36, 42, 39, 45, 116, 117, 1,
550 121, 121, 124, 125, 121, 0, 119, 118, 120, 136,
551 133, 121, 122, 104, 106, 115, 0, 121, 0, 121,
552 121, 121, 121, 0, 121, 121, 0, 0, 90, 135,
553 121, 12, 14, 22, 18, 30, 16, 24, 20, 28,
554 26, 32, 35, 9, 10, 88, 84, 40, 0, 0,
555 128, 129, 0, 134, 0, 121, 121, 121, 121, 121,
556 121, 0, 121, 0, 121, 0, 0, 0, 0, 121,
557 0, 121, 0, 0, 121, 82, 81, 0, 126, 127,
558 0, 0, 137, 121, 121, 85, 0, 0, 0, 108,
559 109, 107, 0, 94, 121, 0, 121, 121, 0, 5,
560 0, 121, 0, 68, 69, 121, 121, 121, 121, 0,
561 0, 0, 0, 49, 50, 0, 83, 79, 0, 0,
562 87, 110, 111, 112, 113, 114, 78, 100, 95, 0,
563 76, 102, 0, 0, 0, 0, 58, 6, 121, 0,
564 59, 0, 0, 0, 0, 70, 0, 121, 71, 80,
565 86, 121, 121, 121, 121, 101, 77, 0, 0, 121,
566 60, 61, 0, 121, 121, 66, 67, 72, 73, 0,
567 91, 0, 0, 0, 121, 103, 96, 97, 121, 121,
568 0, 0, 121, 121, 121, 93, 98, 99, 0, 0,
569 64, 65, 0, 0, 92, 62, 63, 74, 75, 0,
570 0, 0
571 };
572
573 static const short yydefgoto[] = { 300,
574 201, 31, 32, 97, 33, 34, 35, 36, 37, 38,
575 39, 40, 177, 41, 42, 43, 44, 45, 187, 193,
576 194, 195, 234, 52, 53, 114, 115, 100, 110, 54,
577 46, 151, 116, 49, 50
578 };
579
580 static const short yypact[] = { 274,
581 -23,-32768, 5, 55, 10,-32768,-32768, 21, 31, 446,
582 32, 19,-32768, 553,-32768, 56, 72, -12, 89, -11,
583 92, 102, 111, 113,-32768,-32768, 117, 124,-32768,-32768,
584 -32768,-32768, 183,-32768, 202,-32768,-32768,-32768,-32768,-32768,
585 -32768,-32768,-32768,-32768,-32768, -13, 134,-32768, 52, 317,
586 -32768,-32768, 148, 360,-32768, 115, 22, 120, 154, 173,
587 114, 155, 52, 532,-32768, 140, 180, 181, 101, 182,
588 112, 186, 188, 189, 190, 205,-32768,-32768,-32768,-32768,
589 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
590 -32768, 193, 195,-32768,-32768,-32768, 202,-32768,-32768,-32768,
591 -32768,-32768, 403, 403,-32768, 532,-32768,-32768,-32768,-32768,
592 52,-32768,-32768,-32768, 221,-32768, -9,-32768, 42,-32768,
593 -32768,-32768,-32768, 61,-32768,-32768, 200, 41,-32768, 52,
594 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
595 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 360, 360,
596 152, 152, 489, 52, 192,-32768,-32768,-32768,-32768,-32768,
597 -32768, 26,-32768, 127,-32768, 218, 194, 34, 73,-32768,
598 215,-32768, 242, 245,-32768, 202,-32768, 41,-32768,-32768,
599 403, 403, 52,-32768,-32768,-32768, 254, 360, 360, 360,
600 360, 360, 253, 229,-32768, -2,-32768,-32768, 252,-32768,
601 151,-32768, 217,-32768,-32768,-32768,-32768,-32768,-32768, 255,
602 360, 151, 220,-32768,-32768, 41, 202,-32768, 265, 272,
603 -32768,-32768,-32768, 159, 159, 159,-32768,-32768, 241, 17,
604 -32768,-32768, 256, 36, 266, 232,-32768,-32768,-32768, 74,
605 -32768, 273, 238, 277, 243,-32768, 221,-32768,-32768,-32768,
606 -32768,-32768,-32768,-32768,-32768,-32768,-32768, 116, 269,-32768,
607 -32768,-32768, 90,-32768,-32768,-32768,-32768,-32768,-32768, 95,
608 197, 360, 360, 360,-32768,-32768,-32768, 360,-32768,-32768,
609 282, 251,-32768,-32768,-32768,-32768,-32768, 360, 288, 260,
610 -32768,-32768, 289, 280,-32768,-32768,-32768,-32768,-32768, 305,
611 316,-32768
612 };
613
614 static const short yypgoto[] = {-32768,
615 146, -33, 290, 156,-32768,-32768, -119,-32768,-32768,-32768,
616 -32768,-32768, -153,-32768,-32768,-32768,-32768,-32768, 64,-32768,
617 141,-32768, 104, -162, -6,-32768, -172,-32768, -52, -28,
618 -32768, 6, 4, -7, 329
619 };
620
621
622 #define YYLAST 601
623
624
625 static const short yytable[] = { 59,
626 60, 96, 63, 48, 122, 47, 231, 210, 176, 213,
627 161, 79, 83, 80, 84, 222, 223, 224, 225, 226,
628 51, 232, 92, 93, 218, 257, 117, 119, 55, 124,
629 98, 99, 128, 58, 113, 120, 81, 85, 247, 197,
630 232, 113, 111, 2, 61, 244, 245, 206, 3, 233,
631 4, 5, 6, 7, 65, 163, 130, 9, 176, 62,
632 113, 164, 250, 148, 107, 108, 109, 15, 233, 113,
633 66, 121, 149, 150, 170, 198, 153, 113, 56, 77,
634 171, 259, 57, 207, 113, 113, 208, 264, 260, 162,
635 29, 165, 30, 168, 169, 78, 176, 105, 154, 224,
636 225, 226, 178, 279, 113, 155, 48, 48, 283, 152,
637 172, 202, 82, 166, 167, 86, 113, 113, 173, 174,
638 293, 294, 209, 265, 134, 87, 135, 188, 189, 190,
639 191, 192, 196, 113, 88, 138, 89, 139, 113, 280,
640 90, 211, 96, 211, 284, 183, 216, 91, 239, 136,
641 200, 112, 48, 48, 179, 180, 199, 118, 203, 248,
642 140, 259, 123, 101, 102, 127, 230, 125, 275, 107,
643 108, 109, 129, 240, 238, 103, 104, 219, 220, 211,
644 211, 101, 102, 148, 48, 48, 126, 152, 156, 157,
645 235, 236, 131, 107, 108, 109, 184, 185, 186, 242,
646 243, 285, 185, 132, 133, 137, 94, 13, 14, 141,
647 263, 142, 143, 144, 16, 17, 18, 19, 20, 270,
648 21, 22, 23, 24, 272, 273, 274, 14, 145, 27,
649 28, 278, 204, 16, 17, 18, 19, 20, 200, 21,
650 22, 23, 24, 146, 205, 271, 288, 147, 27, 28,
651 156, 157, 175, 277, 211, 211, 214, 281, 282, 215,
652 221, 227, 158, 159, 160, 228, 237, 241, 287, 246,
653 249, 251, 289, 290, 1, 252, 2, 256, 295, 232,
654 261, 3, 262, 4, 5, 6, 7, 266, 267, 8,
655 9, 268, 276, 269, 10, 11, 291, 12, 13, 14,
656 15, 292, 296, 298, 301, 16, 17, 18, 19, 20,
657 297, 21, 22, 23, 24, 302, 212, 25, 26, 2,
658 27, 28, 95, 29, 3, 30, 4, 5, 6, 7,
659 299, 217, 8, 9, 286, 229, 258, 106, 64, 0,
660 12, 13, 14, 15, 0, 0, 0, 0, 16, 17,
661 18, 19, 20, 0, 21, 22, 23, 24, 0, 107,
662 108, 109, 2, 27, 28, 0, 29, 3, 30, 4,
663 5, 6, 7, 0, 0, 8, 9, 0, 0, 0,
664 10, 11, 0, 12, 13, 14, 15, 0, 0, 0,
665 0, 16, 17, 18, 19, 20, 0, 21, 22, 23,
666 24, 0, 0, 113, 0, 2, 27, 28, 0, 29,
667 3, 30, 4, 5, 6, 7, 0, 0, 8, 9,
668 0, 0, 0, 10, 11, 0, 12, 13, 14, 15,
669 0, 0, 0, 0, 16, 17, 18, 19, 20, 0,
670 21, 22, 23, 24, 0, 0, 0, 0, 2, 27,
671 28, 0, 29, 3, 30, 4, 5, 6, 7, 0,
672 0, 8, 9, 0, 0, 0, 0, 11, 0, 12,
673 13, 14, 15, 0, 0, 0, 0, 16, 17, 18,
674 19, 20, 0, 21, 22, 23, 24, 0, 0, 0,
675 0, 2, 27, 28, 0, 29, 3, 30, 4, 5,
676 6, 7, 0, 0, 8, 9, 0, 0, 0, 0,
677 0, 0, 12, 13, 14, 15, 0, 0, 0, 0,
678 16, 17, 18, 19, 20, 0, 21, 22, 23, 24,
679 0, 0, 113, 0, 2, 27, 28, 0, 29, 3,
680 30, 4, 5, 6, 7, 0, 0, 8, 9, 0,
681 0, 0, 0, 0, 0, 12, 13, 14, 15, 0,
682 0, 0, 0, 16, 17, 18, 19, 20, 0, 21,
683 22, 23, 24, 0, 0, 0, 0, 0, 27, 28,
684 0, 29, 0, 30, 67, 68, 69, 70, 71, 0,
685 72, 0, 73, 74, 0, 0, 0, 0, 0, 75,
686 76
687 };
688
689 static const short yycheck[] = { 6,
690 7, 35, 10, 0, 57, 0, 9, 170, 128, 172,
691 20, 24, 24, 26, 26, 188, 189, 190, 191, 192,
692 44, 24, 29, 30, 178, 9, 55, 56, 24, 58,
693 44, 45, 61, 24, 44, 14, 49, 49, 211, 14,
694 24, 44, 50, 3, 24, 208, 209, 14, 8, 52,
695 10, 11, 12, 13, 23, 14, 64, 17, 178, 29,
696 44, 20, 216, 97, 43, 44, 45, 27, 52, 44,
697 52, 50, 101, 102, 14, 50, 105, 44, 24, 24,
698 20, 46, 28, 50, 44, 44, 14, 14, 53, 118,
699 50, 50, 52, 122, 123, 24, 216, 46, 106, 272,
700 273, 274, 131, 14, 44, 112, 103, 104, 14, 104,
701 50, 164, 24, 120, 121, 24, 44, 44, 125, 126,
702 283, 284, 50, 50, 24, 24, 26, 156, 157, 158,
703 159, 160, 161, 44, 24, 24, 24, 26, 44, 50,
704 24, 170, 176, 172, 50, 153, 175, 24, 201, 49,
705 24, 4, 149, 150, 149, 150, 163, 43, 165, 212,
706 49, 46, 43, 30, 31, 52, 195, 14, 53, 43,
707 44, 45, 18, 202, 24, 42, 43, 184, 185, 208,
708 209, 30, 31, 217, 181, 182, 14, 182, 30, 31,
709 197, 198, 53, 43, 44, 45, 5, 6, 7, 206,
710 207, 5, 6, 24, 24, 24, 24, 25, 26, 24,
711 239, 24, 24, 24, 32, 33, 34, 35, 36, 248,
712 38, 39, 40, 41, 253, 254, 255, 26, 24, 47,
713 48, 260, 15, 32, 33, 34, 35, 36, 24, 38,
714 39, 40, 41, 51, 51, 252, 275, 53, 47, 48,
715 30, 31, 53, 260, 283, 284, 15, 264, 265, 15,
716 7, 9, 42, 43, 44, 37, 15, 51, 275, 15,
717 51, 7, 279, 280, 1, 4, 3, 37, 285, 24,
718 15, 8, 51, 10, 11, 12, 13, 15, 51, 16,
719 17, 15, 24, 51, 21, 22, 15, 24, 25, 26,
720 27, 51, 15, 15, 0, 32, 33, 34, 35, 36,
721 51, 38, 39, 40, 41, 0, 171, 44, 45, 3,
722 47, 48, 33, 50, 8, 52, 10, 11, 12, 13,
723 51, 176, 16, 17, 271, 195, 233, 21, 10, -1,
724 24, 25, 26, 27, -1, -1, -1, -1, 32, 33,
725 34, 35, 36, -1, 38, 39, 40, 41, -1, 43,
726 44, 45, 3, 47, 48, -1, 50, 8, 52, 10,
727 11, 12, 13, -1, -1, 16, 17, -1, -1, -1,
728 21, 22, -1, 24, 25, 26, 27, -1, -1, -1,
729 -1, 32, 33, 34, 35, 36, -1, 38, 39, 40,
730 41, -1, -1, 44, -1, 3, 47, 48, -1, 50,
731 8, 52, 10, 11, 12, 13, -1, -1, 16, 17,
732 -1, -1, -1, 21, 22, -1, 24, 25, 26, 27,
733 -1, -1, -1, -1, 32, 33, 34, 35, 36, -1,
734 38, 39, 40, 41, -1, -1, -1, -1, 3, 47,
735 48, -1, 50, 8, 52, 10, 11, 12, 13, -1,
736 -1, 16, 17, -1, -1, -1, -1, 22, -1, 24,
737 25, 26, 27, -1, -1, -1, -1, 32, 33, 34,
738 35, 36, -1, 38, 39, 40, 41, -1, -1, -1,
739 -1, 3, 47, 48, -1, 50, 8, 52, 10, 11,
740 12, 13, -1, -1, 16, 17, -1, -1, -1, -1,
741 -1, -1, 24, 25, 26, 27, -1, -1, -1, -1,
742 32, 33, 34, 35, 36, -1, 38, 39, 40, 41,
743 -1, -1, 44, -1, 3, 47, 48, -1, 50, 8,
744 52, 10, 11, 12, 13, -1, -1, 16, 17, -1,
745 -1, -1, -1, -1, -1, 24, 25, 26, 27, -1,
746 -1, -1, -1, 32, 33, 34, 35, 36, -1, 38,
747 39, 40, 41, -1, -1, -1, -1, -1, 47, 48,
748 -1, 50, -1, 52, 32, 33, 34, 35, 36, -1,
749 38, -1, 40, 41, -1, -1, -1, -1, -1, 47,
750 48
751 };
752 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
753 #line 3 "/usr/share/bison.simple"
754 /* This file comes from bison-1.28. */
755
756 /* Skeleton output parser for bison,
757 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
758
759 This program is free software; you can redistribute it and/or modify
760 it under the terms of the GNU General Public License as published by
761 the Free Software Foundation; either version 2, or (at your option)
762 any later version.
763
764 This program is distributed in the hope that it will be useful,
765 but WITHOUT ANY WARRANTY; without even the implied warranty of
766 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
767 GNU General Public License for more details.
768
769 You should have received a copy of the GNU General Public License
770 along with this program; if not, write to the Free Software
771 Foundation, Inc., 59 Temple Place - Suite 330,
772 Boston, MA 02111-1307, USA. */
773
774 /* As a special exception, when this file is copied by Bison into a
775 Bison output file, you may use that output file without restriction.
776 This special exception was added by the Free Software Foundation
777 in version 1.24 of Bison. */
778
779 /* This is the parser code that is written into each bison parser
780 when the %semantic_parser declaration is not specified in the grammar.
781 It was written by Richard Stallman by simplifying the hairy parser
782 used when %semantic_parser is specified. */
783
784 #ifndef YYSTACK_USE_ALLOCA
785 #ifdef alloca
786 #define YYSTACK_USE_ALLOCA
787 #else /* alloca not defined */
788 #ifdef __GNUC__
789 #define YYSTACK_USE_ALLOCA
790 #define alloca __builtin_alloca
791 #else /* not GNU C. */
792 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
793 #define YYSTACK_USE_ALLOCA
794 #include <alloca.h>
795 #else /* not sparc */
796 /* We think this test detects Watcom and Microsoft C. */
797 /* This used to test MSDOS, but that is a bad idea
798 since that symbol is in the user namespace. */
799 #if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
800 #if 0 /* No need for malloc.h, which pollutes the namespace;
801 instead, just don't use alloca. */
802 #include <malloc.h>
803 #endif
804 #else /* not MSDOS, or __TURBOC__ */
805 #if defined(_AIX)
806 /* I don't know what this was needed for, but it pollutes the namespace.
807 So I turned it off. rms, 2 May 1997. */
808 /* #include <malloc.h> */
809 #pragma alloca
810 #define YYSTACK_USE_ALLOCA
811 #else /* not MSDOS, or __TURBOC__, or _AIX */
812 #if 0
813 #ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
814 and on HPUX 10. Eventually we can turn this on. */
815 #define YYSTACK_USE_ALLOCA
816 #define alloca __builtin_alloca
817 #endif /* __hpux */
818 #endif
819 #endif /* not _AIX */
820 #endif /* not MSDOS, or __TURBOC__ */
821 #endif /* not sparc */
822 #endif /* not GNU C */
823 #endif /* alloca not defined */
824 #endif /* YYSTACK_USE_ALLOCA not defined */
825
826 #ifdef YYSTACK_USE_ALLOCA
827 #define YYSTACK_ALLOC alloca
828 #else
829 #define YYSTACK_ALLOC malloc
830 #endif
831
832 /* Note: there must be only one dollar sign in this file.
833 It is replaced by the list of actions, each action
834 as one case of the switch. */
835
836 #define yyerrok (yyerrstatus = 0)
837 #define yyclearin (yychar = YYEMPTY)
838 #define YYEMPTY -2
839 #define YYEOF 0
840 #define YYACCEPT goto yyacceptlab
841 #define YYABORT goto yyabortlab
842 #define YYERROR goto yyerrlab1
843 /* Like YYERROR except do call yyerror.
844 This remains here temporarily to ease the
845 transition to the new meaning of YYERROR, for GCC.
846 Once GCC version 2 has supplanted version 1, this can go. */
847 #define YYFAIL goto yyerrlab
848 #define YYRECOVERING() (!!yyerrstatus)
849 #define YYBACKUP(token, value) \
850 do \
851 if (yychar == YYEMPTY && yylen == 1) \
852 { yychar = (token), yylval = (value); \
853 yychar1 = YYTRANSLATE (yychar); \
854 YYPOPSTACK; \
855 goto yybackup; \
856 } \
857 else \
858 { yyerror ("syntax error: cannot back up"); YYERROR; } \
859 while (0)
860
861 #define YYTERROR 1
862 #define YYERRCODE 256
863
864 #ifndef YYPURE
865 #define YYLEX yylex()
866 #endif
867
868 #ifdef YYPURE
869 #ifdef YYLSP_NEEDED
870 #ifdef YYLEX_PARAM
871 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
872 #else
873 #define YYLEX yylex(&yylval, &yylloc)
874 #endif
875 #else /* not YYLSP_NEEDED */
876 #ifdef YYLEX_PARAM
877 #define YYLEX yylex(&yylval, YYLEX_PARAM)
878 #else
879 #define YYLEX yylex(&yylval)
880 #endif
881 #endif /* not YYLSP_NEEDED */
882 #endif
883
884 /* If nonreentrant, generate the variables here */
885
886 #ifndef YYPURE
887
888 int yychar; /* the lookahead symbol */
889 YYSTYPE yylval; /* the semantic value of the */
890 /* lookahead symbol */
891
892 #ifdef YYLSP_NEEDED
893 YYLTYPE yylloc; /* location data for the lookahead */
894 /* symbol */
895 #endif
896
897 int yynerrs; /* number of parse errors so far */
898 #endif /* not YYPURE */
899
900 #if YYDEBUG != 0
901 int yydebug; /* nonzero means print parse trace */
902 /* Since this is uninitialized, it does not stop multiple parsers
903 from coexisting. */
904 #endif
905
906 /* YYINITDEPTH indicates the initial size of the parser's stacks */
907
908 #ifndef YYINITDEPTH
909 #define YYINITDEPTH 200
910 #endif
911
912 /* YYMAXDEPTH is the maximum size the stacks can grow to
913 (effective only if the built-in stack extension method is used). */
914
915 #if YYMAXDEPTH == 0
916 #undef YYMAXDEPTH
917 #endif
918
919 #ifndef YYMAXDEPTH
920 #define YYMAXDEPTH 10000
921 #endif
922 \f
923 /* Define __yy_memcpy. Note that the size argument
924 should be passed with type unsigned int, because that is what the non-GCC
925 definitions require. With GCC, __builtin_memcpy takes an arg
926 of type size_t, but it can handle unsigned int. */
927
928 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
929 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
930 #else /* not GNU C or C++ */
931 #ifndef __cplusplus
932
933 /* This is the most reliable way to avoid incompatibilities
934 in available built-in functions on various systems. */
935 static void
936 __yy_memcpy (to, from, count)
937 char *to;
938 char *from;
939 unsigned int count;
940 {
941 register char *f = from;
942 register char *t = to;
943 register int i = count;
944
945 while (i-- > 0)
946 *t++ = *f++;
947 }
948
949 #else /* __cplusplus */
950
951 /* This is the most reliable way to avoid incompatibilities
952 in available built-in functions on various systems. */
953 static void
954 __yy_memcpy (char *to, char *from, unsigned int count)
955 {
956 register char *t = to;
957 register char *f = from;
958 register int i = count;
959
960 while (i-- > 0)
961 *t++ = *f++;
962 }
963
964 #endif
965 #endif
966 \f
967 #line 217 "/usr/share/bison.simple"
968
969 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
970 into yyparse. The argument should have type void *.
971 It should actually point to an object.
972 Grammar actions can access the variable by casting it
973 to the proper pointer type. */
974
975 #ifdef YYPARSE_PARAM
976 #ifdef __cplusplus
977 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
978 #define YYPARSE_PARAM_DECL
979 #else /* not __cplusplus */
980 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
981 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
982 #endif /* not __cplusplus */
983 #else /* not YYPARSE_PARAM */
984 #define YYPARSE_PARAM_ARG
985 #define YYPARSE_PARAM_DECL
986 #endif /* not YYPARSE_PARAM */
987
988 /* Prevent warning if -Wstrict-prototypes. */
989 #ifdef __GNUC__
990 #ifdef YYPARSE_PARAM
991 int yyparse (void *);
992 #else
993 int yyparse (void);
994 #endif
995 #endif
996
997 int
998 yyparse(YYPARSE_PARAM_ARG)
999 YYPARSE_PARAM_DECL
1000 {
1001 register int yystate;
1002 register int yyn;
1003 register short *yyssp;
1004 register YYSTYPE *yyvsp;
1005 int yyerrstatus; /* number of tokens to shift before error messages enabled */
1006 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
1007
1008 short yyssa[YYINITDEPTH]; /* the state stack */
1009 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
1010
1011 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
1012 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
1013
1014 #ifdef YYLSP_NEEDED
1015 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
1016 YYLTYPE *yyls = yylsa;
1017 YYLTYPE *yylsp;
1018
1019 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
1020 #else
1021 #define YYPOPSTACK (yyvsp--, yyssp--)
1022 #endif
1023
1024 int yystacksize = YYINITDEPTH;
1025 int yyfree_stacks = 0;
1026
1027 #ifdef YYPURE
1028 int yychar;
1029 YYSTYPE yylval;
1030 int yynerrs;
1031 #ifdef YYLSP_NEEDED
1032 YYLTYPE yylloc;
1033 #endif
1034 #endif
1035
1036 YYSTYPE yyval; /* the variable used to return */
1037 /* semantic values from the action */
1038 /* routines */
1039
1040 int yylen;
1041
1042 #if YYDEBUG != 0
1043 if (yydebug)
1044 fprintf(stderr, "Starting parse\n");
1045 #endif
1046
1047 yystate = 0;
1048 yyerrstatus = 0;
1049 yynerrs = 0;
1050 yychar = YYEMPTY; /* Cause a token to be read. */
1051
1052 /* Initialize stack pointers.
1053 Waste one element of value and location stack
1054 so that they stay on the same level as the state stack.
1055 The wasted elements are never initialized. */
1056
1057 yyssp = yyss - 1;
1058 yyvsp = yyvs;
1059 #ifdef YYLSP_NEEDED
1060 yylsp = yyls;
1061 #endif
1062
1063 /* Push a new state, which is found in yystate . */
1064 /* In all cases, when you get here, the value and location stacks
1065 have just been pushed. so pushing a state here evens the stacks. */
1066 yynewstate:
1067
1068 *++yyssp = yystate;
1069
1070 if (yyssp >= yyss + yystacksize - 1)
1071 {
1072 /* Give user a chance to reallocate the stack */
1073 /* Use copies of these so that the &'s don't force the real ones into memory. */
1074 YYSTYPE *yyvs1 = yyvs;
1075 short *yyss1 = yyss;
1076 #ifdef YYLSP_NEEDED
1077 YYLTYPE *yyls1 = yyls;
1078 #endif
1079
1080 /* Get the current used size of the three stacks, in elements. */
1081 int size = yyssp - yyss + 1;
1082
1083 #ifdef yyoverflow
1084 /* Each stack pointer address is followed by the size of
1085 the data in use in that stack, in bytes. */
1086 #ifdef YYLSP_NEEDED
1087 /* This used to be a conditional around just the two extra args,
1088 but that might be undefined if yyoverflow is a macro. */
1089 yyoverflow("parser stack overflow",
1090 &yyss1, size * sizeof (*yyssp),
1091 &yyvs1, size * sizeof (*yyvsp),
1092 &yyls1, size * sizeof (*yylsp),
1093 &yystacksize);
1094 #else
1095 yyoverflow("parser stack overflow",
1096 &yyss1, size * sizeof (*yyssp),
1097 &yyvs1, size * sizeof (*yyvsp),
1098 &yystacksize);
1099 #endif
1100
1101 yyss = yyss1; yyvs = yyvs1;
1102 #ifdef YYLSP_NEEDED
1103 yyls = yyls1;
1104 #endif
1105 #else /* no yyoverflow */
1106 /* Extend the stack our own way. */
1107 if (yystacksize >= YYMAXDEPTH)
1108 {
1109 yyerror("parser stack overflow");
1110 if (yyfree_stacks)
1111 {
1112 free (yyss);
1113 free (yyvs);
1114 #ifdef YYLSP_NEEDED
1115 free (yyls);
1116 #endif
1117 }
1118 return 2;
1119 }
1120 yystacksize *= 2;
1121 if (yystacksize > YYMAXDEPTH)
1122 yystacksize = YYMAXDEPTH;
1123 #ifndef YYSTACK_USE_ALLOCA
1124 yyfree_stacks = 1;
1125 #endif
1126 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
1127 __yy_memcpy ((char *)yyss, (char *)yyss1,
1128 size * (unsigned int) sizeof (*yyssp));
1129 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
1130 __yy_memcpy ((char *)yyvs, (char *)yyvs1,
1131 size * (unsigned int) sizeof (*yyvsp));
1132 #ifdef YYLSP_NEEDED
1133 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
1134 __yy_memcpy ((char *)yyls, (char *)yyls1,
1135 size * (unsigned int) sizeof (*yylsp));
1136 #endif
1137 #endif /* no yyoverflow */
1138
1139 yyssp = yyss + size - 1;
1140 yyvsp = yyvs + size - 1;
1141 #ifdef YYLSP_NEEDED
1142 yylsp = yyls + size - 1;
1143 #endif
1144
1145 #if YYDEBUG != 0
1146 if (yydebug)
1147 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
1148 #endif
1149
1150 if (yyssp >= yyss + yystacksize - 1)
1151 YYABORT;
1152 }
1153
1154 #if YYDEBUG != 0
1155 if (yydebug)
1156 fprintf(stderr, "Entering state %d\n", yystate);
1157 #endif
1158
1159 goto yybackup;
1160 yybackup:
1161
1162 /* Do appropriate processing given the current state. */
1163 /* Read a lookahead token if we need one and don't already have one. */
1164 /* yyresume: */
1165
1166 /* First try to decide what to do without reference to lookahead token. */
1167
1168 yyn = yypact[yystate];
1169 if (yyn == YYFLAG)
1170 goto yydefault;
1171
1172 /* Not known => get a lookahead token if don't already have one. */
1173
1174 /* yychar is either YYEMPTY or YYEOF
1175 or a valid token in external form. */
1176
1177 if (yychar == YYEMPTY)
1178 {
1179 #if YYDEBUG != 0
1180 if (yydebug)
1181 fprintf(stderr, "Reading a token: ");
1182 #endif
1183 yychar = YYLEX;
1184 }
1185
1186 /* Convert token to internal form (in yychar1) for indexing tables with */
1187
1188 if (yychar <= 0) /* This means end of input. */
1189 {
1190 yychar1 = 0;
1191 yychar = YYEOF; /* Don't call YYLEX any more */
1192
1193 #if YYDEBUG != 0
1194 if (yydebug)
1195 fprintf(stderr, "Now at end of input.\n");
1196 #endif
1197 }
1198 else
1199 {
1200 yychar1 = YYTRANSLATE(yychar);
1201
1202 #if YYDEBUG != 0
1203 if (yydebug)
1204 {
1205 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
1206 /* Give the individual parser a way to print the precise meaning
1207 of a token, for further debugging info. */
1208 #ifdef YYPRINT
1209 YYPRINT (stderr, yychar, yylval);
1210 #endif
1211 fprintf (stderr, ")\n");
1212 }
1213 #endif
1214 }
1215
1216 yyn += yychar1;
1217 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
1218 goto yydefault;
1219
1220 yyn = yytable[yyn];
1221
1222 /* yyn is what to do for this token type in this state.
1223 Negative => reduce, -yyn is rule number.
1224 Positive => shift, yyn is new state.
1225 New state is final state => don't bother to shift,
1226 just return success.
1227 0, or most negative number => error. */
1228
1229 if (yyn < 0)
1230 {
1231 if (yyn == YYFLAG)
1232 goto yyerrlab;
1233 yyn = -yyn;
1234 goto yyreduce;
1235 }
1236 else if (yyn == 0)
1237 goto yyerrlab;
1238
1239 if (yyn == YYFINAL)
1240 YYACCEPT;
1241
1242 /* Shift the lookahead token. */
1243
1244 #if YYDEBUG != 0
1245 if (yydebug)
1246 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
1247 #endif
1248
1249 /* Discard the token being shifted unless it is eof. */
1250 if (yychar != YYEOF)
1251 yychar = YYEMPTY;
1252
1253 *++yyvsp = yylval;
1254 #ifdef YYLSP_NEEDED
1255 *++yylsp = yylloc;
1256 #endif
1257
1258 /* count tokens shifted since error; after three, turn off error status. */
1259 if (yyerrstatus) yyerrstatus--;
1260
1261 yystate = yyn;
1262 goto yynewstate;
1263
1264 /* Do the default action for the current state. */
1265 yydefault:
1266
1267 yyn = yydefact[yystate];
1268 if (yyn == 0)
1269 goto yyerrlab;
1270
1271 /* Do a reduction. yyn is the number of a rule to reduce with. */
1272 yyreduce:
1273 yylen = yyr2[yyn];
1274 if (yylen > 0)
1275 yyval = yyvsp[1-yylen]; /* implement default value of the action */
1276
1277 #if YYDEBUG != 0
1278 if (yydebug)
1279 {
1280 int i;
1281
1282 fprintf (stderr, "Reducing via rule %d (line %d), ",
1283 yyn, yyrline[yyn]);
1284
1285 /* Print the symbols being reduced, and their result. */
1286 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
1287 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
1288 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
1289 }
1290 #endif
1291
1292
1293 switch (yyn) {
1294
1295 case 1:
1296 #line 352 "/usr/src/local/chet/src/bash/src/parse.y"
1297 {
1298 /* Case of regular command. Discard the error
1299 safety net,and return the command just parsed. */
1300 global_command = yyvsp[-1].command;
1301 eof_encountered = 0;
1302 /* discard_parser_constructs (0); */
1303 YYACCEPT;
1304 ;
1305 break;}
1306 case 2:
1307 #line 361 "/usr/src/local/chet/src/bash/src/parse.y"
1308 {
1309 /* Case of regular command, but not a very
1310 interesting one. Return a NULL command. */
1311 global_command = (COMMAND *)NULL;
1312 YYACCEPT;
1313 ;
1314 break;}
1315 case 3:
1316 #line 368 "/usr/src/local/chet/src/bash/src/parse.y"
1317 {
1318 /* Error during parsing. Return NULL command. */
1319 global_command = (COMMAND *)NULL;
1320 eof_encountered = 0;
1321 /* discard_parser_constructs (1); */
1322 if (interactive)
1323 {
1324 YYACCEPT;
1325 }
1326 else
1327 {
1328 YYABORT;
1329 }
1330 ;
1331 break;}
1332 case 4:
1333 #line 383 "/usr/src/local/chet/src/bash/src/parse.y"
1334 {
1335 /* Case of EOF seen by itself. Do ignoreeof or
1336 not. */
1337 global_command = (COMMAND *)NULL;
1338 handle_eof_input_unit ();
1339 YYACCEPT;
1340 ;
1341 break;}
1342 case 5:
1343 #line 393 "/usr/src/local/chet/src/bash/src/parse.y"
1344 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1345 break;}
1346 case 6:
1347 #line 395 "/usr/src/local/chet/src/bash/src/parse.y"
1348 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-1].word_list); ;
1349 break;}
1350 case 7:
1351 #line 399 "/usr/src/local/chet/src/bash/src/parse.y"
1352 {
1353 redir.filename = yyvsp[0].word;
1354 yyval.redirect = make_redirection (1, r_output_direction, redir);
1355 ;
1356 break;}
1357 case 8:
1358 #line 404 "/usr/src/local/chet/src/bash/src/parse.y"
1359 {
1360 redir.filename = yyvsp[0].word;
1361 yyval.redirect = make_redirection (0, r_input_direction, redir);
1362 ;
1363 break;}
1364 case 9:
1365 #line 409 "/usr/src/local/chet/src/bash/src/parse.y"
1366 {
1367 redir.filename = yyvsp[0].word;
1368 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_direction, redir);
1369 ;
1370 break;}
1371 case 10:
1372 #line 414 "/usr/src/local/chet/src/bash/src/parse.y"
1373 {
1374 redir.filename = yyvsp[0].word;
1375 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_direction, redir);
1376 ;
1377 break;}
1378 case 11:
1379 #line 419 "/usr/src/local/chet/src/bash/src/parse.y"
1380 {
1381 redir.filename = yyvsp[0].word;
1382 yyval.redirect = make_redirection (1, r_appending_to, redir);
1383 ;
1384 break;}
1385 case 12:
1386 #line 424 "/usr/src/local/chet/src/bash/src/parse.y"
1387 {
1388 redir.filename = yyvsp[0].word;
1389 yyval.redirect = make_redirection (yyvsp[-2].number, r_appending_to, redir);
1390 ;
1391 break;}
1392 case 13:
1393 #line 429 "/usr/src/local/chet/src/bash/src/parse.y"
1394 {
1395 redir.filename = yyvsp[0].word;
1396 yyval.redirect = make_redirection (0, r_reading_until, redir);
1397 redir_stack[need_here_doc++] = yyval.redirect;
1398 ;
1399 break;}
1400 case 14:
1401 #line 435 "/usr/src/local/chet/src/bash/src/parse.y"
1402 {
1403 redir.filename = yyvsp[0].word;
1404 yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_until, redir);
1405 redir_stack[need_here_doc++] = yyval.redirect;
1406 ;
1407 break;}
1408 case 15:
1409 #line 441 "/usr/src/local/chet/src/bash/src/parse.y"
1410 {
1411 redir.filename = yyvsp[0].word;
1412 yyval.redirect = make_redirection (0, r_reading_string, redir);
1413 ;
1414 break;}
1415 case 16:
1416 #line 446 "/usr/src/local/chet/src/bash/src/parse.y"
1417 {
1418 redir.filename = yyvsp[0].word;
1419 yyval.redirect = make_redirection (yyvsp[-2].number, r_reading_string, redir);
1420 ;
1421 break;}
1422 case 17:
1423 #line 451 "/usr/src/local/chet/src/bash/src/parse.y"
1424 {
1425 redir.dest = yyvsp[0].number;
1426 yyval.redirect = make_redirection (0, r_duplicating_input, redir);
1427 ;
1428 break;}
1429 case 18:
1430 #line 456 "/usr/src/local/chet/src/bash/src/parse.y"
1431 {
1432 redir.dest = yyvsp[0].number;
1433 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input, redir);
1434 ;
1435 break;}
1436 case 19:
1437 #line 461 "/usr/src/local/chet/src/bash/src/parse.y"
1438 {
1439 redir.dest = yyvsp[0].number;
1440 yyval.redirect = make_redirection (1, r_duplicating_output, redir);
1441 ;
1442 break;}
1443 case 20:
1444 #line 466 "/usr/src/local/chet/src/bash/src/parse.y"
1445 {
1446 redir.dest = yyvsp[0].number;
1447 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output, redir);
1448 ;
1449 break;}
1450 case 21:
1451 #line 471 "/usr/src/local/chet/src/bash/src/parse.y"
1452 {
1453 redir.filename = yyvsp[0].word;
1454 yyval.redirect = make_redirection (0, r_duplicating_input_word, redir);
1455 ;
1456 break;}
1457 case 22:
1458 #line 476 "/usr/src/local/chet/src/bash/src/parse.y"
1459 {
1460 redir.filename = yyvsp[0].word;
1461 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_input_word, redir);
1462 ;
1463 break;}
1464 case 23:
1465 #line 481 "/usr/src/local/chet/src/bash/src/parse.y"
1466 {
1467 redir.filename = yyvsp[0].word;
1468 yyval.redirect = make_redirection (1, r_duplicating_output_word, redir);
1469 ;
1470 break;}
1471 case 24:
1472 #line 486 "/usr/src/local/chet/src/bash/src/parse.y"
1473 {
1474 redir.filename = yyvsp[0].word;
1475 yyval.redirect = make_redirection (yyvsp[-2].number, r_duplicating_output_word, redir);
1476 ;
1477 break;}
1478 case 25:
1479 #line 491 "/usr/src/local/chet/src/bash/src/parse.y"
1480 {
1481 redir.filename = yyvsp[0].word;
1482 yyval.redirect = make_redirection
1483 (0, r_deblank_reading_until, redir);
1484 redir_stack[need_here_doc++] = yyval.redirect;
1485 ;
1486 break;}
1487 case 26:
1488 #line 498 "/usr/src/local/chet/src/bash/src/parse.y"
1489 {
1490 redir.filename = yyvsp[0].word;
1491 yyval.redirect = make_redirection
1492 (yyvsp[-2].number, r_deblank_reading_until, redir);
1493 redir_stack[need_here_doc++] = yyval.redirect;
1494 ;
1495 break;}
1496 case 27:
1497 #line 505 "/usr/src/local/chet/src/bash/src/parse.y"
1498 {
1499 redir.dest = 0;
1500 yyval.redirect = make_redirection (1, r_close_this, redir);
1501 ;
1502 break;}
1503 case 28:
1504 #line 510 "/usr/src/local/chet/src/bash/src/parse.y"
1505 {
1506 redir.dest = 0;
1507 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1508 ;
1509 break;}
1510 case 29:
1511 #line 515 "/usr/src/local/chet/src/bash/src/parse.y"
1512 {
1513 redir.dest = 0;
1514 yyval.redirect = make_redirection (0, r_close_this, redir);
1515 ;
1516 break;}
1517 case 30:
1518 #line 520 "/usr/src/local/chet/src/bash/src/parse.y"
1519 {
1520 redir.dest = 0;
1521 yyval.redirect = make_redirection (yyvsp[-2].number, r_close_this, redir);
1522 ;
1523 break;}
1524 case 31:
1525 #line 525 "/usr/src/local/chet/src/bash/src/parse.y"
1526 {
1527 redir.filename = yyvsp[0].word;
1528 yyval.redirect = make_redirection (1, r_err_and_out, redir);
1529 ;
1530 break;}
1531 case 32:
1532 #line 530 "/usr/src/local/chet/src/bash/src/parse.y"
1533 {
1534 redir.filename = yyvsp[0].word;
1535 yyval.redirect = make_redirection (yyvsp[-2].number, r_input_output, redir);
1536 ;
1537 break;}
1538 case 33:
1539 #line 535 "/usr/src/local/chet/src/bash/src/parse.y"
1540 {
1541 redir.filename = yyvsp[0].word;
1542 yyval.redirect = make_redirection (0, r_input_output, redir);
1543 ;
1544 break;}
1545 case 34:
1546 #line 540 "/usr/src/local/chet/src/bash/src/parse.y"
1547 {
1548 redir.filename = yyvsp[0].word;
1549 yyval.redirect = make_redirection (1, r_output_force, redir);
1550 ;
1551 break;}
1552 case 35:
1553 #line 545 "/usr/src/local/chet/src/bash/src/parse.y"
1554 {
1555 redir.filename = yyvsp[0].word;
1556 yyval.redirect = make_redirection (yyvsp[-2].number, r_output_force, redir);
1557 ;
1558 break;}
1559 case 36:
1560 #line 552 "/usr/src/local/chet/src/bash/src/parse.y"
1561 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1562 break;}
1563 case 37:
1564 #line 554 "/usr/src/local/chet/src/bash/src/parse.y"
1565 { yyval.element.word = yyvsp[0].word; yyval.element.redirect = 0; ;
1566 break;}
1567 case 38:
1568 #line 556 "/usr/src/local/chet/src/bash/src/parse.y"
1569 { yyval.element.redirect = yyvsp[0].redirect; yyval.element.word = 0; ;
1570 break;}
1571 case 39:
1572 #line 560 "/usr/src/local/chet/src/bash/src/parse.y"
1573 {
1574 yyval.redirect = yyvsp[0].redirect;
1575 ;
1576 break;}
1577 case 40:
1578 #line 564 "/usr/src/local/chet/src/bash/src/parse.y"
1579 {
1580 register REDIRECT *t;
1581
1582 for (t = yyvsp[-1].redirect; t->next; t = t->next)
1583 ;
1584 t->next = yyvsp[0].redirect;
1585 yyval.redirect = yyvsp[-1].redirect;
1586 ;
1587 break;}
1588 case 41:
1589 #line 575 "/usr/src/local/chet/src/bash/src/parse.y"
1590 { yyval.command = make_simple_command (yyvsp[0].element, (COMMAND *)NULL); ;
1591 break;}
1592 case 42:
1593 #line 577 "/usr/src/local/chet/src/bash/src/parse.y"
1594 { yyval.command = make_simple_command (yyvsp[0].element, yyvsp[-1].command); ;
1595 break;}
1596 case 43:
1597 #line 581 "/usr/src/local/chet/src/bash/src/parse.y"
1598 { yyval.command = clean_simple_command (yyvsp[0].command); ;
1599 break;}
1600 case 44:
1601 #line 583 "/usr/src/local/chet/src/bash/src/parse.y"
1602 { yyval.command = yyvsp[0].command; ;
1603 break;}
1604 case 45:
1605 #line 585 "/usr/src/local/chet/src/bash/src/parse.y"
1606 {
1607 COMMAND *tc;
1608
1609 tc = yyvsp[-1].command;
1610 if (tc->redirects)
1611 {
1612 register REDIRECT *t;
1613 for (t = tc->redirects; t->next; t = t->next)
1614 ;
1615 t->next = yyvsp[0].redirect;
1616 }
1617 else
1618 tc->redirects = yyvsp[0].redirect;
1619 yyval.command = yyvsp[-1].command;
1620 ;
1621 break;}
1622 case 46:
1623 #line 601 "/usr/src/local/chet/src/bash/src/parse.y"
1624 { yyval.command = yyvsp[0].command; ;
1625 break;}
1626 case 47:
1627 #line 605 "/usr/src/local/chet/src/bash/src/parse.y"
1628 { yyval.command = yyvsp[0].command; ;
1629 break;}
1630 case 48:
1631 #line 607 "/usr/src/local/chet/src/bash/src/parse.y"
1632 { yyval.command = yyvsp[0].command; ;
1633 break;}
1634 case 49:
1635 #line 609 "/usr/src/local/chet/src/bash/src/parse.y"
1636 { yyval.command = make_while_command (yyvsp[-3].command, yyvsp[-1].command); ;
1637 break;}
1638 case 50:
1639 #line 611 "/usr/src/local/chet/src/bash/src/parse.y"
1640 { yyval.command = make_until_command (yyvsp[-3].command, yyvsp[-1].command); ;
1641 break;}
1642 case 51:
1643 #line 613 "/usr/src/local/chet/src/bash/src/parse.y"
1644 { yyval.command = yyvsp[0].command; ;
1645 break;}
1646 case 52:
1647 #line 615 "/usr/src/local/chet/src/bash/src/parse.y"
1648 { yyval.command = yyvsp[0].command; ;
1649 break;}
1650 case 53:
1651 #line 617 "/usr/src/local/chet/src/bash/src/parse.y"
1652 { yyval.command = yyvsp[0].command; ;
1653 break;}
1654 case 54:
1655 #line 619 "/usr/src/local/chet/src/bash/src/parse.y"
1656 { yyval.command = yyvsp[0].command; ;
1657 break;}
1658 case 55:
1659 #line 621 "/usr/src/local/chet/src/bash/src/parse.y"
1660 { yyval.command = yyvsp[0].command; ;
1661 break;}
1662 case 56:
1663 #line 623 "/usr/src/local/chet/src/bash/src/parse.y"
1664 { yyval.command = yyvsp[0].command; ;
1665 break;}
1666 case 57:
1667 #line 625 "/usr/src/local/chet/src/bash/src/parse.y"
1668 { yyval.command = yyvsp[0].command; ;
1669 break;}
1670 case 58:
1671 #line 629 "/usr/src/local/chet/src/bash/src/parse.y"
1672 {
1673 yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command, word_lineno[word_top]);
1674 if (word_top > 0) word_top--;
1675 ;
1676 break;}
1677 case 59:
1678 #line 634 "/usr/src/local/chet/src/bash/src/parse.y"
1679 {
1680 yyval.command = make_for_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command, word_lineno[word_top]);
1681 if (word_top > 0) word_top--;
1682 ;
1683 break;}
1684 case 60:
1685 #line 639 "/usr/src/local/chet/src/bash/src/parse.y"
1686 {
1687 yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command, word_lineno[word_top]);
1688 if (word_top > 0) word_top--;
1689 ;
1690 break;}
1691 case 61:
1692 #line 644 "/usr/src/local/chet/src/bash/src/parse.y"
1693 {
1694 yyval.command = make_for_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command, word_lineno[word_top]);
1695 if (word_top > 0) word_top--;
1696 ;
1697 break;}
1698 case 62:
1699 #line 649 "/usr/src/local/chet/src/bash/src/parse.y"
1700 {
1701 yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command, word_lineno[word_top]);
1702 if (word_top > 0) word_top--;
1703 ;
1704 break;}
1705 case 63:
1706 #line 654 "/usr/src/local/chet/src/bash/src/parse.y"
1707 {
1708 yyval.command = make_for_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command, word_lineno[word_top]);
1709 if (word_top > 0) word_top--;
1710 ;
1711 break;}
1712 case 64:
1713 #line 659 "/usr/src/local/chet/src/bash/src/parse.y"
1714 {
1715 yyval.command = make_for_command (yyvsp[-7].word, (WORD_LIST *)NULL, yyvsp[-1].command, word_lineno[word_top]);
1716 if (word_top > 0) word_top--;
1717 ;
1718 break;}
1719 case 65:
1720 #line 664 "/usr/src/local/chet/src/bash/src/parse.y"
1721 {
1722 yyval.command = make_for_command (yyvsp[-7].word, (WORD_LIST *)NULL, yyvsp[-1].command, word_lineno[word_top]);
1723 if (word_top > 0) word_top--;
1724 ;
1725 break;}
1726 case 66:
1727 #line 671 "/usr/src/local/chet/src/bash/src/parse.y"
1728 {
1729 yyval.command = make_arith_for_command (yyvsp[-5].word_list, yyvsp[-1].command, arith_for_lineno);
1730 if (word_top > 0) word_top--;
1731 ;
1732 break;}
1733 case 67:
1734 #line 676 "/usr/src/local/chet/src/bash/src/parse.y"
1735 {
1736 yyval.command = make_arith_for_command (yyvsp[-5].word_list, yyvsp[-1].command, arith_for_lineno);
1737 if (word_top > 0) word_top--;
1738 ;
1739 break;}
1740 case 68:
1741 #line 681 "/usr/src/local/chet/src/bash/src/parse.y"
1742 {
1743 yyval.command = make_arith_for_command (yyvsp[-3].word_list, yyvsp[-1].command, arith_for_lineno);
1744 if (word_top > 0) word_top--;
1745 ;
1746 break;}
1747 case 69:
1748 #line 686 "/usr/src/local/chet/src/bash/src/parse.y"
1749 {
1750 yyval.command = make_arith_for_command (yyvsp[-3].word_list, yyvsp[-1].command, arith_for_lineno);
1751 if (word_top > 0) word_top--;
1752 ;
1753 break;}
1754 case 70:
1755 #line 693 "/usr/src/local/chet/src/bash/src/parse.y"
1756 {
1757 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command, word_lineno[word_top]);
1758 if (word_top > 0) word_top--;
1759 ;
1760 break;}
1761 case 71:
1762 #line 698 "/usr/src/local/chet/src/bash/src/parse.y"
1763 {
1764 yyval.command = make_select_command (yyvsp[-4].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command, word_lineno[word_top]);
1765 if (word_top > 0) word_top--;
1766 ;
1767 break;}
1768 case 72:
1769 #line 703 "/usr/src/local/chet/src/bash/src/parse.y"
1770 {
1771 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command, word_lineno[word_top]);
1772 if (word_top > 0) word_top--;
1773 ;
1774 break;}
1775 case 73:
1776 #line 708 "/usr/src/local/chet/src/bash/src/parse.y"
1777 {
1778 yyval.command = make_select_command (yyvsp[-5].word, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), yyvsp[-1].command, word_lineno[word_top]);
1779 if (word_top > 0) word_top--;
1780 ;
1781 break;}
1782 case 74:
1783 #line 713 "/usr/src/local/chet/src/bash/src/parse.y"
1784 {
1785 yyval.command = make_select_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command, word_lineno[word_top]);
1786 if (word_top > 0) word_top--;
1787 ;
1788 break;}
1789 case 75:
1790 #line 718 "/usr/src/local/chet/src/bash/src/parse.y"
1791 {
1792 yyval.command = make_select_command (yyvsp[-8].word, REVERSE_LIST (yyvsp[-5].word_list, WORD_LIST *), yyvsp[-1].command, word_lineno[word_top]);
1793 if (word_top > 0) word_top--;
1794 ;
1795 break;}
1796 case 76:
1797 #line 725 "/usr/src/local/chet/src/bash/src/parse.y"
1798 {
1799 yyval.command = make_case_command (yyvsp[-4].word, (PATTERN_LIST *)NULL, word_lineno[word_top]);
1800 if (word_top > 0) word_top--;
1801 ;
1802 break;}
1803 case 77:
1804 #line 730 "/usr/src/local/chet/src/bash/src/parse.y"
1805 {
1806 yyval.command = make_case_command (yyvsp[-5].word, yyvsp[-2].pattern, word_lineno[word_top]);
1807 if (word_top > 0) word_top--;
1808 ;
1809 break;}
1810 case 78:
1811 #line 735 "/usr/src/local/chet/src/bash/src/parse.y"
1812 {
1813 yyval.command = make_case_command (yyvsp[-4].word, yyvsp[-1].pattern, word_lineno[word_top]);
1814 if (word_top > 0) word_top--;
1815 ;
1816 break;}
1817 case 79:
1818 #line 742 "/usr/src/local/chet/src/bash/src/parse.y"
1819 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1820 break;}
1821 case 80:
1822 #line 745 "/usr/src/local/chet/src/bash/src/parse.y"
1823 { yyval.command = make_function_def (yyvsp[-4].word, yyvsp[0].command, function_dstart, function_bstart); ;
1824 break;}
1825 case 81:
1826 #line 748 "/usr/src/local/chet/src/bash/src/parse.y"
1827 { yyval.command = make_function_def (yyvsp[-2].word, yyvsp[0].command, function_dstart, function_bstart); ;
1828 break;}
1829 case 82:
1830 #line 753 "/usr/src/local/chet/src/bash/src/parse.y"
1831 { yyval.command = yyvsp[0].command; ;
1832 break;}
1833 case 83:
1834 #line 755 "/usr/src/local/chet/src/bash/src/parse.y"
1835 {
1836 COMMAND *tc;
1837
1838 tc = yyvsp[-1].command;
1839 /* According to Posix.2 3.9.5, redirections
1840 specified after the body of a function should
1841 be attached to the function and performed when
1842 the function is executed, not as part of the
1843 function definition command. */
1844 /* XXX - I don't think it matters, but we might
1845 want to change this in the future to avoid
1846 problems differentiating between a function
1847 definition with a redirection and a function
1848 definition containing a single command with a
1849 redirection. The two are semantically equivalent,
1850 though -- the only difference is in how the
1851 command printing code displays the redirections. */
1852 if (tc->redirects)
1853 {
1854 register REDIRECT *t;
1855 for (t = tc->redirects; t->next; t = t->next)
1856 ;
1857 t->next = yyvsp[0].redirect;
1858 }
1859 else
1860 tc->redirects = yyvsp[0].redirect;
1861 yyval.command = yyvsp[-1].command;
1862 ;
1863 break;}
1864 case 84:
1865 #line 786 "/usr/src/local/chet/src/bash/src/parse.y"
1866 {
1867 yyval.command = make_subshell_command (yyvsp[-1].command);
1868 yyval.command->flags |= CMD_WANT_SUBSHELL;
1869 ;
1870 break;}
1871 case 85:
1872 #line 793 "/usr/src/local/chet/src/bash/src/parse.y"
1873 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, (COMMAND *)NULL); ;
1874 break;}
1875 case 86:
1876 #line 795 "/usr/src/local/chet/src/bash/src/parse.y"
1877 { yyval.command = make_if_command (yyvsp[-5].command, yyvsp[-3].command, yyvsp[-1].command); ;
1878 break;}
1879 case 87:
1880 #line 797 "/usr/src/local/chet/src/bash/src/parse.y"
1881 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[-1].command); ;
1882 break;}
1883 case 88:
1884 #line 802 "/usr/src/local/chet/src/bash/src/parse.y"
1885 { yyval.command = make_group_command (yyvsp[-1].command); ;
1886 break;}
1887 case 89:
1888 #line 806 "/usr/src/local/chet/src/bash/src/parse.y"
1889 { yyval.command = make_arith_command (yyvsp[0].word_list); ;
1890 break;}
1891 case 90:
1892 #line 810 "/usr/src/local/chet/src/bash/src/parse.y"
1893 { yyval.command = yyvsp[-1].command; ;
1894 break;}
1895 case 91:
1896 #line 814 "/usr/src/local/chet/src/bash/src/parse.y"
1897 { yyval.command = make_if_command (yyvsp[-2].command, yyvsp[0].command, (COMMAND *)NULL); ;
1898 break;}
1899 case 92:
1900 #line 816 "/usr/src/local/chet/src/bash/src/parse.y"
1901 { yyval.command = make_if_command (yyvsp[-4].command, yyvsp[-2].command, yyvsp[0].command); ;
1902 break;}
1903 case 93:
1904 #line 818 "/usr/src/local/chet/src/bash/src/parse.y"
1905 { yyval.command = make_if_command (yyvsp[-3].command, yyvsp[-1].command, yyvsp[0].command); ;
1906 break;}
1907 case 95:
1908 #line 823 "/usr/src/local/chet/src/bash/src/parse.y"
1909 { yyvsp[0].pattern->next = yyvsp[-1].pattern; yyval.pattern = yyvsp[0].pattern; ;
1910 break;}
1911 case 96:
1912 #line 827 "/usr/src/local/chet/src/bash/src/parse.y"
1913 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1914 break;}
1915 case 97:
1916 #line 829 "/usr/src/local/chet/src/bash/src/parse.y"
1917 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1918 break;}
1919 case 98:
1920 #line 831 "/usr/src/local/chet/src/bash/src/parse.y"
1921 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, yyvsp[0].command); ;
1922 break;}
1923 case 99:
1924 #line 833 "/usr/src/local/chet/src/bash/src/parse.y"
1925 { yyval.pattern = make_pattern_list (yyvsp[-2].word_list, (COMMAND *)NULL); ;
1926 break;}
1927 case 101:
1928 #line 838 "/usr/src/local/chet/src/bash/src/parse.y"
1929 { yyvsp[-1].pattern->next = yyvsp[-2].pattern; yyval.pattern = yyvsp[-1].pattern; ;
1930 break;}
1931 case 102:
1932 #line 842 "/usr/src/local/chet/src/bash/src/parse.y"
1933 { yyval.word_list = make_word_list (yyvsp[0].word, (WORD_LIST *)NULL); ;
1934 break;}
1935 case 103:
1936 #line 844 "/usr/src/local/chet/src/bash/src/parse.y"
1937 { yyval.word_list = make_word_list (yyvsp[0].word, yyvsp[-2].word_list); ;
1938 break;}
1939 case 104:
1940 #line 853 "/usr/src/local/chet/src/bash/src/parse.y"
1941 {
1942 yyval.command = yyvsp[0].command;
1943 if (need_here_doc)
1944 gather_here_documents ();
1945 ;
1946 break;}
1947 case 106:
1948 #line 862 "/usr/src/local/chet/src/bash/src/parse.y"
1949 {
1950 yyval.command = yyvsp[0].command;
1951 ;
1952 break;}
1953 case 108:
1954 #line 869 "/usr/src/local/chet/src/bash/src/parse.y"
1955 {
1956 if (yyvsp[-2].command->type == cm_connection)
1957 yyval.command = connect_async_list (yyvsp[-2].command, (COMMAND *)NULL, '&');
1958 else
1959 yyval.command = command_connect (yyvsp[-2].command, (COMMAND *)NULL, '&');
1960 ;
1961 break;}
1962 case 110:
1963 #line 880 "/usr/src/local/chet/src/bash/src/parse.y"
1964 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
1965 break;}
1966 case 111:
1967 #line 882 "/usr/src/local/chet/src/bash/src/parse.y"
1968 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
1969 break;}
1970 case 112:
1971 #line 884 "/usr/src/local/chet/src/bash/src/parse.y"
1972 {
1973 if (yyvsp[-3].command->type == cm_connection)
1974 yyval.command = connect_async_list (yyvsp[-3].command, yyvsp[0].command, '&');
1975 else
1976 yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '&');
1977 ;
1978 break;}
1979 case 113:
1980 #line 891 "/usr/src/local/chet/src/bash/src/parse.y"
1981 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1982 break;}
1983 case 114:
1984 #line 893 "/usr/src/local/chet/src/bash/src/parse.y"
1985 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, ';'); ;
1986 break;}
1987 case 115:
1988 #line 895 "/usr/src/local/chet/src/bash/src/parse.y"
1989 { yyval.command = yyvsp[0].command; ;
1990 break;}
1991 case 118:
1992 #line 903 "/usr/src/local/chet/src/bash/src/parse.y"
1993 { yyval.number = '\n'; ;
1994 break;}
1995 case 119:
1996 #line 905 "/usr/src/local/chet/src/bash/src/parse.y"
1997 { yyval.number = ';'; ;
1998 break;}
1999 case 120:
2000 #line 907 "/usr/src/local/chet/src/bash/src/parse.y"
2001 { yyval.number = yacc_EOF; ;
2002 break;}
2003 case 123:
2004 #line 921 "/usr/src/local/chet/src/bash/src/parse.y"
2005 {
2006 yyval.command = yyvsp[0].command;
2007 if (need_here_doc)
2008 gather_here_documents ();
2009 ;
2010 break;}
2011 case 124:
2012 #line 927 "/usr/src/local/chet/src/bash/src/parse.y"
2013 {
2014 if (yyvsp[-1].command->type == cm_connection)
2015 yyval.command = connect_async_list (yyvsp[-1].command, (COMMAND *)NULL, '&');
2016 else
2017 yyval.command = command_connect (yyvsp[-1].command, (COMMAND *)NULL, '&');
2018 if (need_here_doc)
2019 gather_here_documents ();
2020 ;
2021 break;}
2022 case 125:
2023 #line 936 "/usr/src/local/chet/src/bash/src/parse.y"
2024 {
2025 yyval.command = yyvsp[-1].command;
2026 if (need_here_doc)
2027 gather_here_documents ();
2028 ;
2029 break;}
2030 case 126:
2031 #line 944 "/usr/src/local/chet/src/bash/src/parse.y"
2032 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, AND_AND); ;
2033 break;}
2034 case 127:
2035 #line 946 "/usr/src/local/chet/src/bash/src/parse.y"
2036 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, OR_OR); ;
2037 break;}
2038 case 128:
2039 #line 948 "/usr/src/local/chet/src/bash/src/parse.y"
2040 {
2041 if (yyvsp[-2].command->type == cm_connection)
2042 yyval.command = connect_async_list (yyvsp[-2].command, yyvsp[0].command, '&');
2043 else
2044 yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, '&');
2045 ;
2046 break;}
2047 case 129:
2048 #line 955 "/usr/src/local/chet/src/bash/src/parse.y"
2049 { yyval.command = command_connect (yyvsp[-2].command, yyvsp[0].command, ';'); ;
2050 break;}
2051 case 130:
2052 #line 958 "/usr/src/local/chet/src/bash/src/parse.y"
2053 { yyval.command = yyvsp[0].command; ;
2054 break;}
2055 case 131:
2056 #line 962 "/usr/src/local/chet/src/bash/src/parse.y"
2057 { yyval.command = yyvsp[0].command; ;
2058 break;}
2059 case 132:
2060 #line 964 "/usr/src/local/chet/src/bash/src/parse.y"
2061 {
2062 if (yyvsp[0].command)
2063 yyvsp[0].command->flags |= CMD_INVERT_RETURN;
2064 yyval.command = yyvsp[0].command;
2065 ;
2066 break;}
2067 case 133:
2068 #line 970 "/usr/src/local/chet/src/bash/src/parse.y"
2069 {
2070 if (yyvsp[0].command)
2071 yyvsp[0].command->flags |= yyvsp[-1].number;
2072 yyval.command = yyvsp[0].command;
2073 ;
2074 break;}
2075 case 134:
2076 #line 976 "/usr/src/local/chet/src/bash/src/parse.y"
2077 {
2078 if (yyvsp[0].command)
2079 yyvsp[0].command->flags |= yyvsp[-2].number|CMD_INVERT_RETURN;
2080 yyval.command = yyvsp[0].command;
2081 ;
2082 break;}
2083 case 135:
2084 #line 982 "/usr/src/local/chet/src/bash/src/parse.y"
2085 {
2086 if (yyvsp[0].command)
2087 yyvsp[0].command->flags |= yyvsp[-1].number|CMD_INVERT_RETURN;
2088 yyval.command = yyvsp[0].command;
2089 ;
2090 break;}
2091 case 136:
2092 #line 988 "/usr/src/local/chet/src/bash/src/parse.y"
2093 {
2094 ELEMENT x;
2095
2096 /* Boy, this is unclean. `time' by itself can
2097 time a null command. We cheat and push a
2098 newline back if the list_terminator was a newline
2099 to avoid the double-newline problem (one to
2100 terminate this, one to terminate the command) */
2101 x.word = 0;
2102 x.redirect = 0;
2103 yyval.command = make_simple_command (x, (COMMAND *)NULL);
2104 yyval.command->flags |= yyvsp[-1].number;
2105 /* XXX - let's cheat and push a newline back */
2106 if (yyvsp[0].number == '\n')
2107 token_to_read = '\n';
2108 ;
2109 break;}
2110 case 137:
2111 #line 1009 "/usr/src/local/chet/src/bash/src/parse.y"
2112 { yyval.command = command_connect (yyvsp[-3].command, yyvsp[0].command, '|'); ;
2113 break;}
2114 case 138:
2115 #line 1011 "/usr/src/local/chet/src/bash/src/parse.y"
2116 { yyval.command = yyvsp[0].command; ;
2117 break;}
2118 case 139:
2119 #line 1015 "/usr/src/local/chet/src/bash/src/parse.y"
2120 { yyval.number = CMD_TIME_PIPELINE; ;
2121 break;}
2122 case 140:
2123 #line 1017 "/usr/src/local/chet/src/bash/src/parse.y"
2124 { yyval.number = CMD_TIME_PIPELINE|CMD_TIME_POSIX; ;
2125 break;}
2126 }
2127 /* the action file gets copied in in place of this dollarsign */
2128 #line 543 "/usr/share/bison.simple"
2129 \f
2130 yyvsp -= yylen;
2131 yyssp -= yylen;
2132 #ifdef YYLSP_NEEDED
2133 yylsp -= yylen;
2134 #endif
2135
2136 #if YYDEBUG != 0
2137 if (yydebug)
2138 {
2139 short *ssp1 = yyss - 1;
2140 fprintf (stderr, "state stack now");
2141 while (ssp1 != yyssp)
2142 fprintf (stderr, " %d", *++ssp1);
2143 fprintf (stderr, "\n");
2144 }
2145 #endif
2146
2147 *++yyvsp = yyval;
2148
2149 #ifdef YYLSP_NEEDED
2150 yylsp++;
2151 if (yylen == 0)
2152 {
2153 yylsp->first_line = yylloc.first_line;
2154 yylsp->first_column = yylloc.first_column;
2155 yylsp->last_line = (yylsp-1)->last_line;
2156 yylsp->last_column = (yylsp-1)->last_column;
2157 yylsp->text = 0;
2158 }
2159 else
2160 {
2161 yylsp->last_line = (yylsp+yylen-1)->last_line;
2162 yylsp->last_column = (yylsp+yylen-1)->last_column;
2163 }
2164 #endif
2165
2166 /* Now "shift" the result of the reduction.
2167 Determine what state that goes to,
2168 based on the state we popped back to
2169 and the rule number reduced by. */
2170
2171 yyn = yyr1[yyn];
2172
2173 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
2174 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
2175 yystate = yytable[yystate];
2176 else
2177 yystate = yydefgoto[yyn - YYNTBASE];
2178
2179 goto yynewstate;
2180
2181 yyerrlab: /* here on detecting error */
2182
2183 if (! yyerrstatus)
2184 /* If not already recovering from an error, report this error. */
2185 {
2186 ++yynerrs;
2187
2188 #ifdef YYERROR_VERBOSE
2189 yyn = yypact[yystate];
2190
2191 if (yyn > YYFLAG && yyn < YYLAST)
2192 {
2193 int size = 0;
2194 char *msg;
2195 int x, count;
2196
2197 count = 0;
2198 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
2199 for (x = (yyn < 0 ? -yyn : 0);
2200 x < (sizeof(yytname) / sizeof(char *)); x++)
2201 if (yycheck[x + yyn] == x)
2202 size += strlen(yytname[x]) + 15, count++;
2203 msg = (char *) malloc(size + 15);
2204 if (msg != 0)
2205 {
2206 strcpy(msg, "parse error");
2207
2208 if (count < 5)
2209 {
2210 count = 0;
2211 for (x = (yyn < 0 ? -yyn : 0);
2212 x < (sizeof(yytname) / sizeof(char *)); x++)
2213 if (yycheck[x + yyn] == x)
2214 {
2215 strcat(msg, count == 0 ? ", expecting `" : " or `");
2216 strcat(msg, yytname[x]);
2217 strcat(msg, "'");
2218 count++;
2219 }
2220 }
2221 yyerror(msg);
2222 free(msg);
2223 }
2224 else
2225 yyerror ("parse error; also virtual memory exceeded");
2226 }
2227 else
2228 #endif /* YYERROR_VERBOSE */
2229 yyerror("parse error");
2230 }
2231
2232 goto yyerrlab1;
2233 yyerrlab1: /* here on error raised explicitly by an action */
2234
2235 if (yyerrstatus == 3)
2236 {
2237 /* if just tried and failed to reuse lookahead token after an error, discard it. */
2238
2239 /* return failure if at end of input */
2240 if (yychar == YYEOF)
2241 YYABORT;
2242
2243 #if YYDEBUG != 0
2244 if (yydebug)
2245 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
2246 #endif
2247
2248 yychar = YYEMPTY;
2249 }
2250
2251 /* Else will try to reuse lookahead token
2252 after shifting the error token. */
2253
2254 yyerrstatus = 3; /* Each real token shifted decrements this */
2255
2256 goto yyerrhandle;
2257
2258 yyerrdefault: /* current state does not do anything special for the error token. */
2259
2260 #if 0
2261 /* This is wrong; only states that explicitly want error tokens
2262 should shift them. */
2263 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
2264 if (yyn) goto yydefault;
2265 #endif
2266
2267 yyerrpop: /* pop the current state because it cannot handle the error token */
2268
2269 if (yyssp == yyss) YYABORT;
2270 yyvsp--;
2271 yystate = *--yyssp;
2272 #ifdef YYLSP_NEEDED
2273 yylsp--;
2274 #endif
2275
2276 #if YYDEBUG != 0
2277 if (yydebug)
2278 {
2279 short *ssp1 = yyss - 1;
2280 fprintf (stderr, "Error: state stack now");
2281 while (ssp1 != yyssp)
2282 fprintf (stderr, " %d", *++ssp1);
2283 fprintf (stderr, "\n");
2284 }
2285 #endif
2286
2287 yyerrhandle:
2288
2289 yyn = yypact[yystate];
2290 if (yyn == YYFLAG)
2291 goto yyerrdefault;
2292
2293 yyn += YYTERROR;
2294 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
2295 goto yyerrdefault;
2296
2297 yyn = yytable[yyn];
2298 if (yyn < 0)
2299 {
2300 if (yyn == YYFLAG)
2301 goto yyerrpop;
2302 yyn = -yyn;
2303 goto yyreduce;
2304 }
2305 else if (yyn == 0)
2306 goto yyerrpop;
2307
2308 if (yyn == YYFINAL)
2309 YYACCEPT;
2310
2311 #if YYDEBUG != 0
2312 if (yydebug)
2313 fprintf(stderr, "Shifting error token, ");
2314 #endif
2315
2316 *++yyvsp = yylval;
2317 #ifdef YYLSP_NEEDED
2318 *++yylsp = yylloc;
2319 #endif
2320
2321 yystate = yyn;
2322 goto yynewstate;
2323
2324 yyacceptlab:
2325 /* YYACCEPT comes here. */
2326 if (yyfree_stacks)
2327 {
2328 free (yyss);
2329 free (yyvs);
2330 #ifdef YYLSP_NEEDED
2331 free (yyls);
2332 #endif
2333 }
2334 return 0;
2335
2336 yyabortlab:
2337 /* YYABORT comes here. */
2338 if (yyfree_stacks)
2339 {
2340 free (yyss);
2341 free (yyvs);
2342 #ifdef YYLSP_NEEDED
2343 free (yyls);
2344 #endif
2345 }
2346 return 1;
2347 }
2348 #line 1019 "/usr/src/local/chet/src/bash/src/parse.y"
2349
2350
2351 /* Possible states for the parser that require it to do special things. */
2352 #define PST_CASEPAT 0x0001 /* in a case pattern list */
2353 #define PST_ALEXPNEXT 0x0002 /* expand next word for aliases */
2354 #define PST_ALLOWOPNBRC 0x0004 /* allow open brace for function def */
2355 #define PST_NEEDCLOSBRC 0x0008 /* need close brace */
2356 #define PST_DBLPAREN 0x0010 /* double-paren parsing */
2357 #define PST_SUBSHELL 0x0020 /* ( ... ) subshell */
2358 #define PST_CMDSUBST 0x0040 /* $( ... ) command substitution */
2359 #define PST_CASESTMT 0x0080 /* parsing a case statement */
2360 #define PST_CONDCMD 0x0100 /* parsing a [[...]] command */
2361 #define PST_CONDEXPR 0x0200 /* parsing the guts of [[...]] */
2362 #define PST_ARITHFOR 0x0400 /* parsing an arithmetic for command */
2363 #define PST_ALEXPAND 0x0800 /* OK to expand aliases - unused */
2364 #define PST_CMDTOKEN 0x1000 /* command token OK - unused */
2365 #define PST_COMPASSIGN 0x2000 /* parsing x=(...) compound assignment */
2366 #define PST_ASSIGNOK 0x4000 /* assignment statement ok in this context */
2367
2368 /* Initial size to allocate for tokens, and the
2369 amount to grow them by. */
2370 #define TOKEN_DEFAULT_INITIAL_SIZE 496
2371 #define TOKEN_DEFAULT_GROW_SIZE 512
2372
2373 /* Should we call prompt_again? */
2374 #define SHOULD_PROMPT() \
2375 (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
2376
2377 #if defined (ALIAS)
2378 # define expanding_alias() (pushed_string_list && pushed_string_list->expander)
2379 #else
2380 # define expanding_alias() 0
2381 #endif
2382
2383 /* The token currently being read. */
2384 static int current_token;
2385
2386 /* The last read token, or NULL. read_token () uses this for context
2387 checking. */
2388 static int last_read_token;
2389
2390 /* The token read prior to last_read_token. */
2391 static int token_before_that;
2392
2393 /* The token read prior to token_before_that. */
2394 static int two_tokens_ago;
2395
2396 /* The current parser state. */
2397 static int parser_state;
2398
2399 /* Global var is non-zero when end of file has been reached. */
2400 int EOF_Reached = 0;
2401
2402 #ifdef DEBUG
2403 static void
2404 debug_parser (i)
2405 int i;
2406 {
2407 #if YYDEBUG != 0
2408 yydebug = i;
2409 #endif
2410 }
2411 #endif
2412
2413 /* yy_getc () returns the next available character from input or EOF.
2414 yy_ungetc (c) makes `c' the next character to read.
2415 init_yy_io (get, unget, type, location) makes the function GET the
2416 installed function for getting the next character, makes UNGET the
2417 installed function for un-getting a character, sets the type of stream
2418 (either string or file) from TYPE, and makes LOCATION point to where
2419 the input is coming from. */
2420
2421 /* Unconditionally returns end-of-file. */
2422 int
2423 return_EOF ()
2424 {
2425 return (EOF);
2426 }
2427
2428 /* Variable containing the current get and unget functions.
2429 See ./input.h for a clearer description. */
2430 BASH_INPUT bash_input;
2431
2432 /* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
2433 is non-null, avoiding a memory leak. */
2434 void
2435 initialize_bash_input ()
2436 {
2437 bash_input.type = st_none;
2438 FREE (bash_input.name);
2439 bash_input.name = (char *)NULL;
2440 bash_input.location.file = (FILE *)NULL;
2441 bash_input.location.string = (char *)NULL;
2442 bash_input.getter = (sh_cget_func_t *)NULL;
2443 bash_input.ungetter = (sh_cunget_func_t *)NULL;
2444 }
2445
2446 /* Set the contents of the current bash input stream from
2447 GET, UNGET, TYPE, NAME, and LOCATION. */
2448 void
2449 init_yy_io (get, unget, type, name, location)
2450 sh_cget_func_t *get;
2451 sh_cunget_func_t *unget;
2452 enum stream_type type;
2453 const char *name;
2454 INPUT_STREAM location;
2455 {
2456 bash_input.type = type;
2457 FREE (bash_input.name);
2458 bash_input.name = name ? savestring (name) : (char *)NULL;
2459
2460 /* XXX */
2461 #if defined (CRAY)
2462 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
2463 #else
2464 bash_input.location = location;
2465 #endif
2466 bash_input.getter = get;
2467 bash_input.ungetter = unget;
2468 }
2469
2470 char *
2471 yy_input_name ()
2472 {
2473 return (bash_input.name ? bash_input.name : "stdin");
2474 }
2475
2476 /* Call this to get the next character of input. */
2477 static int
2478 yy_getc ()
2479 {
2480 return (*(bash_input.getter)) ();
2481 }
2482
2483 /* Call this to unget C. That is, to make C the next character
2484 to be read. */
2485 static int
2486 yy_ungetc (c)
2487 int c;
2488 {
2489 return (*(bash_input.ungetter)) (c);
2490 }
2491
2492 #if defined (BUFFERED_INPUT)
2493 #ifdef INCLUDE_UNUSED
2494 int
2495 input_file_descriptor ()
2496 {
2497 switch (bash_input.type)
2498 {
2499 case st_stream:
2500 return (fileno (bash_input.location.file));
2501 case st_bstream:
2502 return (bash_input.location.buffered_fd);
2503 case st_stdin:
2504 default:
2505 return (fileno (stdin));
2506 }
2507 }
2508 #endif
2509 #endif /* BUFFERED_INPUT */
2510
2511 /* **************************************************************** */
2512 /* */
2513 /* Let input be read from readline (). */
2514 /* */
2515 /* **************************************************************** */
2516
2517 #if defined (READLINE)
2518 char *current_readline_prompt = (char *)NULL;
2519 char *current_readline_line = (char *)NULL;
2520 int current_readline_line_index = 0;
2521
2522 static int
2523 yy_readline_get ()
2524 {
2525 SigHandler *old_sigint;
2526 int line_len;
2527 unsigned char c;
2528
2529 if (!current_readline_line)
2530 {
2531 if (!bash_readline_initialized)
2532 initialize_readline ();
2533
2534 #if defined (JOB_CONTROL)
2535 if (job_control)
2536 give_terminal_to (shell_pgrp, 0);
2537 #endif /* JOB_CONTROL */
2538
2539 old_sigint = (SigHandler *)NULL;
2540 if (signal_is_ignored (SIGINT) == 0)
2541 {
2542 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
2543 interrupt_immediately++;
2544 }
2545
2546 current_readline_line = readline (current_readline_prompt ?
2547 current_readline_prompt : "");
2548
2549 if (signal_is_ignored (SIGINT) == 0 && old_sigint)
2550 {
2551 interrupt_immediately--;
2552 set_signal_handler (SIGINT, old_sigint);
2553 }
2554
2555 #if 0
2556 /* Reset the prompt to the decoded value of prompt_string_pointer. */
2557 reset_readline_prompt ();
2558 #endif
2559
2560 if (current_readline_line == 0)
2561 return (EOF);
2562
2563 current_readline_line_index = 0;
2564 line_len = strlen (current_readline_line);
2565
2566 current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len);
2567 current_readline_line[line_len++] = '\n';
2568 current_readline_line[line_len] = '\0';
2569 }
2570
2571 if (current_readline_line[current_readline_line_index] == 0)
2572 {
2573 free (current_readline_line);
2574 current_readline_line = (char *)NULL;
2575 return (yy_readline_get ());
2576 }
2577 else
2578 {
2579 c = current_readline_line[current_readline_line_index++];
2580 return (c);
2581 }
2582 }
2583
2584 static int
2585 yy_readline_unget (c)
2586 int c;
2587 {
2588 if (current_readline_line_index && current_readline_line)
2589 current_readline_line[--current_readline_line_index] = c;
2590 return (c);
2591 }
2592
2593 void
2594 with_input_from_stdin ()
2595 {
2596 INPUT_STREAM location;
2597
2598 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
2599 {
2600 location.string = current_readline_line;
2601 init_yy_io (yy_readline_get, yy_readline_unget,
2602 st_stdin, "readline stdin", location);
2603 }
2604 }
2605
2606 #else /* !READLINE */
2607
2608 void
2609 with_input_from_stdin ()
2610 {
2611 with_input_from_stream (stdin, "stdin");
2612 }
2613 #endif /* !READLINE */
2614
2615 /* **************************************************************** */
2616 /* */
2617 /* Let input come from STRING. STRING is zero terminated. */
2618 /* */
2619 /* **************************************************************** */
2620
2621 static int
2622 yy_string_get ()
2623 {
2624 register char *string;
2625 register unsigned char c;
2626
2627 string = bash_input.location.string;
2628
2629 /* If the string doesn't exist, or is empty, EOF found. */
2630 if (string && *string)
2631 {
2632 c = *string++;
2633 bash_input.location.string = string;
2634 return (c);
2635 }
2636 else
2637 return (EOF);
2638 }
2639
2640 static int
2641 yy_string_unget (c)
2642 int c;
2643 {
2644 *(--bash_input.location.string) = c;
2645 return (c);
2646 }
2647
2648 void
2649 with_input_from_string (string, name)
2650 char *string;
2651 const char *name;
2652 {
2653 INPUT_STREAM location;
2654
2655 location.string = string;
2656 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
2657 }
2658
2659 /* **************************************************************** */
2660 /* */
2661 /* Let input come from STREAM. */
2662 /* */
2663 /* **************************************************************** */
2664
2665 /* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
2666 define, and just use getc/ungetc if it was defined, but since bash
2667 installs its signal handlers without the SA_RESTART flag, some signals
2668 (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
2669 the read to be restarted. We need to restart it ourselves. */
2670
2671 static int
2672 yy_stream_get ()
2673 {
2674 int result;
2675
2676 result = EOF;
2677 if (bash_input.location.file)
2678 {
2679 if (interactive)
2680 interrupt_immediately++;
2681 result = getc_with_restart (bash_input.location.file);
2682 if (interactive)
2683 interrupt_immediately--;
2684 }
2685 return (result);
2686 }
2687
2688 static int
2689 yy_stream_unget (c)
2690 int c;
2691 {
2692 return (ungetc_with_restart (c, bash_input.location.file));
2693 }
2694
2695 void
2696 with_input_from_stream (stream, name)
2697 FILE *stream;
2698 const char *name;
2699 {
2700 INPUT_STREAM location;
2701
2702 location.file = stream;
2703 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
2704 }
2705
2706 typedef struct stream_saver {
2707 struct stream_saver *next;
2708 BASH_INPUT bash_input;
2709 int line;
2710 #if defined (BUFFERED_INPUT)
2711 BUFFERED_STREAM *bstream;
2712 #endif /* BUFFERED_INPUT */
2713 } STREAM_SAVER;
2714
2715 /* The globally known line number. */
2716 int line_number = 0;
2717
2718 #if defined (COND_COMMAND)
2719 static int cond_lineno;
2720 static int cond_token;
2721 #endif
2722
2723 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
2724
2725 void
2726 push_stream (reset_lineno)
2727 int reset_lineno;
2728 {
2729 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
2730
2731 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
2732
2733 #if defined (BUFFERED_INPUT)
2734 saver->bstream = (BUFFERED_STREAM *)NULL;
2735 /* If we have a buffered stream, clear out buffers[fd]. */
2736 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2737 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
2738 (BUFFERED_STREAM *)NULL);
2739 #endif /* BUFFERED_INPUT */
2740
2741 saver->line = line_number;
2742 bash_input.name = (char *)NULL;
2743 saver->next = stream_list;
2744 stream_list = saver;
2745 EOF_Reached = 0;
2746 if (reset_lineno)
2747 line_number = 0;
2748 }
2749
2750 void
2751 pop_stream ()
2752 {
2753 if (!stream_list)
2754 EOF_Reached = 1;
2755 else
2756 {
2757 STREAM_SAVER *saver = stream_list;
2758
2759 EOF_Reached = 0;
2760 stream_list = stream_list->next;
2761
2762 init_yy_io (saver->bash_input.getter,
2763 saver->bash_input.ungetter,
2764 saver->bash_input.type,
2765 saver->bash_input.name,
2766 saver->bash_input.location);
2767
2768 #if defined (BUFFERED_INPUT)
2769 /* If we have a buffered stream, restore buffers[fd]. */
2770 /* If the input file descriptor was changed while this was on the
2771 save stack, update the buffered fd to the new file descriptor and
2772 re-establish the buffer <-> bash_input fd correspondence. */
2773 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
2774 {
2775 if (bash_input_fd_changed)
2776 {
2777 bash_input_fd_changed = 0;
2778 if (default_buffered_input >= 0)
2779 {
2780 bash_input.location.buffered_fd = default_buffered_input;
2781 saver->bstream->b_fd = default_buffered_input;
2782 SET_CLOSE_ON_EXEC (default_buffered_input);
2783 }
2784 }
2785 /* XXX could free buffered stream returned as result here. */
2786 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
2787 }
2788 #endif /* BUFFERED_INPUT */
2789
2790 line_number = saver->line;
2791
2792 FREE (saver->bash_input.name);
2793 free (saver);
2794 }
2795 }
2796
2797 /* Return 1 if a stream of type TYPE is saved on the stack. */
2798 int
2799 stream_on_stack (type)
2800 enum stream_type type;
2801 {
2802 register STREAM_SAVER *s;
2803
2804 for (s = stream_list; s; s = s->next)
2805 if (s->bash_input.type == type)
2806 return 1;
2807 return 0;
2808 }
2809
2810 /* Save the current token state and return it in a malloced array. */
2811 int *
2812 save_token_state ()
2813 {
2814 int *ret;
2815
2816 ret = (int *)xmalloc (3 * sizeof (int));
2817 ret[0] = last_read_token;
2818 ret[1] = token_before_that;
2819 ret[2] = two_tokens_ago;
2820 return ret;
2821 }
2822
2823 void
2824 restore_token_state (ts)
2825 int *ts;
2826 {
2827 if (ts == 0)
2828 return;
2829 last_read_token = ts[0];
2830 token_before_that = ts[1];
2831 two_tokens_ago = ts[2];
2832 }
2833
2834 /*
2835 * This is used to inhibit alias expansion and reserved word recognition
2836 * inside case statement pattern lists. A `case statement pattern list' is:
2837 *
2838 * everything between the `in' in a `case word in' and the next ')'
2839 * or `esac'
2840 * everything between a `;;' and the next `)' or `esac'
2841 */
2842
2843 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2844
2845 #define END_OF_ALIAS 0
2846
2847 /*
2848 * Pseudo-global variables used in implementing token-wise alias expansion.
2849 */
2850
2851 /*
2852 * Pushing and popping strings. This works together with shell_getc to
2853 * implement alias expansion on a per-token basis.
2854 */
2855
2856 typedef struct string_saver {
2857 struct string_saver *next;
2858 int expand_alias; /* Value to set expand_alias to when string is popped. */
2859 char *saved_line;
2860 #if defined (ALIAS)
2861 alias_t *expander; /* alias that caused this line to be pushed. */
2862 #endif
2863 int saved_line_size, saved_line_index, saved_line_terminator;
2864 } STRING_SAVER;
2865
2866 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
2867
2868 /*
2869 * Push the current shell_input_line onto a stack of such lines and make S
2870 * the current input. Used when expanding aliases. EXPAND is used to set
2871 * the value of expand_next_token when the string is popped, so that the
2872 * word after the alias in the original line is handled correctly when the
2873 * alias expands to multiple words. TOKEN is the token that was expanded
2874 * into S; it is saved and used to prevent infinite recursive expansion.
2875 */
2876 static void
2877 push_string (s, expand, ap)
2878 char *s;
2879 int expand;
2880 alias_t *ap;
2881 {
2882 STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER));
2883
2884 temp->expand_alias = expand;
2885 temp->saved_line = shell_input_line;
2886 temp->saved_line_size = shell_input_line_size;
2887 temp->saved_line_index = shell_input_line_index;
2888 temp->saved_line_terminator = shell_input_line_terminator;
2889 #if defined (ALIAS)
2890 temp->expander = ap;
2891 #endif
2892 temp->next = pushed_string_list;
2893 pushed_string_list = temp;
2894
2895 #if defined (ALIAS)
2896 if (ap)
2897 ap->flags |= AL_BEINGEXPANDED;
2898 #endif
2899
2900 shell_input_line = s;
2901 shell_input_line_size = strlen (s);
2902 shell_input_line_index = 0;
2903 shell_input_line_terminator = '\0';
2904 #if 0
2905 parser_state &= ~PST_ALEXPNEXT; /* XXX */
2906 #endif
2907
2908 set_line_mbstate ();
2909 }
2910
2911 /*
2912 * Make the top of the pushed_string stack be the current shell input.
2913 * Only called when there is something on the stack. Called from shell_getc
2914 * when it thinks it has consumed the string generated by an alias expansion
2915 * and needs to return to the original input line.
2916 */
2917 static void
2918 pop_string ()
2919 {
2920 STRING_SAVER *t;
2921
2922 FREE (shell_input_line);
2923 shell_input_line = pushed_string_list->saved_line;
2924 shell_input_line_index = pushed_string_list->saved_line_index;
2925 shell_input_line_size = pushed_string_list->saved_line_size;
2926 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
2927
2928 if (pushed_string_list->expand_alias)
2929 parser_state |= PST_ALEXPNEXT;
2930 else
2931 parser_state &= ~PST_ALEXPNEXT;
2932
2933 t = pushed_string_list;
2934 pushed_string_list = pushed_string_list->next;
2935
2936 #if defined (ALIAS)
2937 if (t->expander)
2938 t->expander->flags &= ~AL_BEINGEXPANDED;
2939 #endif
2940
2941 free ((char *)t);
2942
2943 set_line_mbstate ();
2944 }
2945
2946 static void
2947 free_string_list ()
2948 {
2949 register STRING_SAVER *t, *t1;
2950
2951 for (t = pushed_string_list; t; )
2952 {
2953 t1 = t->next;
2954 FREE (t->saved_line);
2955 #if defined (ALIAS)
2956 if (t->expander)
2957 t->expander->flags &= ~AL_BEINGEXPANDED;
2958 #endif
2959 free ((char *)t);
2960 t = t1;
2961 }
2962 pushed_string_list = (STRING_SAVER *)NULL;
2963 }
2964
2965 #endif /* ALIAS || DPAREN_ARITHMETIC */
2966
2967 void
2968 free_pushed_string_input ()
2969 {
2970 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2971 free_string_list ();
2972 #endif
2973 }
2974
2975 /* Return a line of text, taken from wherever yylex () reads input.
2976 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
2977 is non-zero, we remove unquoted \<newline> pairs. This is used by
2978 read_secondary_line to read here documents. */
2979 static char *
2980 read_a_line (remove_quoted_newline)
2981 int remove_quoted_newline;
2982 {
2983 static char *line_buffer = (char *)NULL;
2984 static int buffer_size = 0;
2985 int indx = 0, c, peekc, pass_next;
2986
2987 #if defined (READLINE)
2988 if (no_line_editing && SHOULD_PROMPT ())
2989 #else
2990 if (SHOULD_PROMPT ())
2991 #endif
2992 print_prompt ();
2993
2994 pass_next = 0;
2995 while (1)
2996 {
2997 /* Allow immediate exit if interrupted during input. */
2998 QUIT;
2999
3000 c = yy_getc ();
3001
3002 /* Ignore null bytes in input. */
3003 if (c == 0)
3004 {
3005 #if 0
3006 internal_warning ("read_a_line: ignored null byte in input");
3007 #endif
3008 continue;
3009 }
3010
3011 /* If there is no more input, then we return NULL. */
3012 if (c == EOF)
3013 {
3014 if (interactive && bash_input.type == st_stream)
3015 clearerr (stdin);
3016 if (indx == 0)
3017 return ((char *)NULL);
3018 c = '\n';
3019 }
3020
3021 /* `+2' in case the final character in the buffer is a newline. */
3022 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
3023
3024 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
3025 here document with an unquoted delimiter. In this case,
3026 the line will be expanded as if it were in double quotes.
3027 We allow a backslash to escape the next character, but we
3028 need to treat the backslash specially only if a backslash
3029 quoting a backslash-newline pair appears in the line. */
3030 if (pass_next)
3031 {
3032 line_buffer[indx++] = c;
3033 pass_next = 0;
3034 }
3035 else if (c == '\\' && remove_quoted_newline)
3036 {
3037 peekc = yy_getc ();
3038 if (peekc == '\n')
3039 {
3040 line_number++;
3041 continue; /* Make the unquoted \<newline> pair disappear. */
3042 }
3043 else
3044 {
3045 yy_ungetc (peekc);
3046 pass_next = 1;
3047 line_buffer[indx++] = c; /* Preserve the backslash. */
3048 }
3049 }
3050 else
3051 line_buffer[indx++] = c;
3052
3053 if (c == '\n')
3054 {
3055 line_buffer[indx] = '\0';
3056 return (line_buffer);
3057 }
3058 }
3059 }
3060
3061 /* Return a line as in read_a_line (), but insure that the prompt is
3062 the secondary prompt. This is used to read the lines of a here
3063 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
3064 newlines quoted with backslashes while reading the line. It is
3065 non-zero unless the delimiter of the here document was quoted. */
3066 char *
3067 read_secondary_line (remove_quoted_newline)
3068 int remove_quoted_newline;
3069 {
3070 prompt_string_pointer = &ps2_prompt;
3071 if (SHOULD_PROMPT())
3072 prompt_again ();
3073 return (read_a_line (remove_quoted_newline));
3074 }
3075
3076 /* **************************************************************** */
3077 /* */
3078 /* YYLEX () */
3079 /* */
3080 /* **************************************************************** */
3081
3082 /* Reserved words. These are only recognized as the first word of a
3083 command. */
3084 STRING_INT_ALIST word_token_alist[] = {
3085 { "if", IF },
3086 { "then", THEN },
3087 { "else", ELSE },
3088 { "elif", ELIF },
3089 { "fi", FI },
3090 { "case", CASE },
3091 { "esac", ESAC },
3092 { "for", FOR },
3093 #if defined (SELECT_COMMAND)
3094 { "select", SELECT },
3095 #endif
3096 { "while", WHILE },
3097 { "until", UNTIL },
3098 { "do", DO },
3099 { "done", DONE },
3100 { "in", IN },
3101 { "function", FUNCTION },
3102 #if defined (COMMAND_TIMING)
3103 { "time", TIME },
3104 #endif
3105 { "{", '{' },
3106 { "}", '}' },
3107 { "!", BANG },
3108 #if defined (COND_COMMAND)
3109 { "[[", COND_START },
3110 { "]]", COND_END },
3111 #endif
3112 { (char *)NULL, 0}
3113 };
3114
3115 /* other tokens that can be returned by read_token() */
3116 STRING_INT_ALIST other_token_alist[] = {
3117 /* Multiple-character tokens with special values */
3118 { "-p", TIMEOPT },
3119 { "&&", AND_AND },
3120 { "||", OR_OR },
3121 { ">>", GREATER_GREATER },
3122 { "<<", LESS_LESS },
3123 { "<&", LESS_AND },
3124 { ">&", GREATER_AND },
3125 { ";;", SEMI_SEMI },
3126 { "<<-", LESS_LESS_MINUS },
3127 { "<<<", LESS_LESS_LESS },
3128 { "&>", AND_GREATER },
3129 { "<>", LESS_GREATER },
3130 { ">|", GREATER_BAR },
3131 { "EOF", yacc_EOF },
3132 /* Tokens whose value is the character itself */
3133 { ">", '>' },
3134 { "<", '<' },
3135 { "-", '-' },
3136 { "{", '{' },
3137 { "}", '}' },
3138 { ";", ';' },
3139 { "(", '(' },
3140 { ")", ')' },
3141 { "|", '|' },
3142 { "&", '&' },
3143 { "newline", '\n' },
3144 { (char *)NULL, 0}
3145 };
3146
3147 /* others not listed here:
3148 WORD look at yylval.word
3149 ASSIGNMENT_WORD look at yylval.word
3150 NUMBER look at yylval.number
3151 ARITH_CMD look at yylval.word_list
3152 ARITH_FOR_EXPRS look at yylval.word_list
3153 COND_CMD look at yylval.command
3154 */
3155
3156 /* These are used by read_token_word, but appear up here so that shell_getc
3157 can use them to decide when to add otherwise blank lines to the history. */
3158
3159 /* The primary delimiter stack. */
3160 struct dstack dstack = { (char *)NULL, 0, 0 };
3161
3162 /* A temporary delimiter stack to be used when decoding prompt strings.
3163 This is needed because command substitutions in prompt strings (e.g., PS2)
3164 can screw up the parser's quoting state. */
3165 static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
3166
3167 /* Macro for accessing the top delimiter on the stack. Returns the
3168 delimiter or zero if none. */
3169 #define current_delimiter(ds) \
3170 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
3171
3172 #define push_delimiter(ds, character) \
3173 do \
3174 { \
3175 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
3176 ds.delimiters = (char *)xrealloc \
3177 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
3178 ds.delimiters[ds.delimiter_depth] = character; \
3179 ds.delimiter_depth++; \
3180 } \
3181 while (0)
3182
3183 #define pop_delimiter(ds) ds.delimiter_depth--
3184
3185 /* Return the next shell input character. This always reads characters
3186 from shell_input_line; when that line is exhausted, it is time to
3187 read the next line. This is called by read_token when the shell is
3188 processing normal command input. */
3189
3190 /* This implements one-character lookahead/lookbehind across physical input
3191 lines, to avoid something being lost because it's pushed back with
3192 shell_ungetc when we're at the start of a line. */
3193 static int eol_ungetc_lookahead = 0;
3194
3195 static int
3196 shell_getc (remove_quoted_newline)
3197 int remove_quoted_newline;
3198 {
3199 register int i;
3200 int c;
3201 unsigned char uc;
3202 static int mustpop = 0;
3203
3204 QUIT;
3205
3206 if (sigwinch_received)
3207 {
3208 sigwinch_received = 0;
3209 get_new_window_size (0, (int *)0, (int *)0);
3210 }
3211
3212 if (eol_ungetc_lookahead)
3213 {
3214 c = eol_ungetc_lookahead;
3215 eol_ungetc_lookahead = 0;
3216 return (c);
3217 }
3218
3219 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
3220 /* If shell_input_line[shell_input_line_index] == 0, but there is
3221 something on the pushed list of strings, then we don't want to go
3222 off and get another line. We let the code down below handle it. */
3223
3224 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
3225 (pushed_string_list == (STRING_SAVER *)NULL)))
3226 #else /* !ALIAS && !DPAREN_ARITHMETIC */
3227 if (!shell_input_line || !shell_input_line[shell_input_line_index])
3228 #endif /* !ALIAS && !DPAREN_ARITHMETIC */
3229 {
3230 line_number++;
3231
3232 restart_read:
3233
3234 /* Allow immediate exit if interrupted during input. */
3235 QUIT;
3236
3237 i = 0;
3238 shell_input_line_terminator = 0;
3239
3240 /* If the shell is interatctive, but not currently printing a prompt
3241 (interactive_shell && interactive == 0), we don't want to print
3242 notifies or cleanup the jobs -- we want to defer it until we do
3243 print the next prompt. */
3244 if (interactive_shell == 0 || SHOULD_PROMPT())
3245 {
3246 #if defined (JOB_CONTROL)
3247 /* This can cause a problem when reading a command as the result
3248 of a trap, when the trap is called from flush_child. This call
3249 had better not cause jobs to disappear from the job table in
3250 that case, or we will have big trouble. */
3251 notify_and_cleanup ();
3252 #else /* !JOB_CONTROL */
3253 cleanup_dead_jobs ();
3254 #endif /* !JOB_CONTROL */
3255 }
3256
3257 #if defined (READLINE)
3258 if (no_line_editing && SHOULD_PROMPT())
3259 #else
3260 if (SHOULD_PROMPT())
3261 #endif
3262 print_prompt ();
3263
3264 if (bash_input.type == st_stream)
3265 clearerr (stdin);
3266
3267 while (1)
3268 {
3269 c = yy_getc ();
3270
3271 /* Allow immediate exit if interrupted during input. */
3272 QUIT;
3273
3274 if (c == '\0')
3275 {
3276 #if 0
3277 internal_warning ("shell_getc: ignored null byte in input");
3278 #endif
3279 continue;
3280 }
3281
3282 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
3283
3284 if (c == EOF)
3285 {
3286 if (bash_input.type == st_stream)
3287 clearerr (stdin);
3288
3289 if (i == 0)
3290 shell_input_line_terminator = EOF;
3291
3292 shell_input_line[i] = '\0';
3293 break;
3294 }
3295
3296 shell_input_line[i++] = c;
3297
3298 if (c == '\n')
3299 {
3300 shell_input_line[--i] = '\0';
3301 current_command_line_count++;
3302 break;
3303 }
3304 }
3305
3306 shell_input_line_index = 0;
3307 shell_input_line_len = i; /* == strlen (shell_input_line) */
3308
3309 set_line_mbstate ();
3310
3311 #if defined (HISTORY)
3312 if (remember_on_history && shell_input_line && shell_input_line[0])
3313 {
3314 char *expansions;
3315 # if defined (BANG_HISTORY)
3316 int old_hist;
3317
3318 /* If the current delimiter is a single quote, we should not be
3319 performing history expansion, even if we're on a different
3320 line from the original single quote. */
3321 old_hist = history_expansion_inhibited;
3322 if (current_delimiter (dstack) == '\'')
3323 history_expansion_inhibited = 1;
3324 # endif
3325 expansions = pre_process_line (shell_input_line, 1, 1);
3326 # if defined (BANG_HISTORY)
3327 history_expansion_inhibited = old_hist;
3328 # endif
3329 if (expansions != shell_input_line)
3330 {
3331 free (shell_input_line);
3332 shell_input_line = expansions;
3333 shell_input_line_len = shell_input_line ?
3334 strlen (shell_input_line) : 0;
3335 if (!shell_input_line_len)
3336 current_command_line_count--;
3337
3338 /* We have to force the xrealloc below because we don't know
3339 the true allocated size of shell_input_line anymore. */
3340 shell_input_line_size = shell_input_line_len;
3341
3342 set_line_mbstate ();
3343 }
3344 }
3345 /* Try to do something intelligent with blank lines encountered while
3346 entering multi-line commands. XXX - this is grotesque */
3347 else if (remember_on_history && shell_input_line &&
3348 shell_input_line[0] == '\0' &&
3349 current_command_line_count > 1)
3350 {
3351 if (current_delimiter (dstack))
3352 /* We know shell_input_line[0] == 0 and we're reading some sort of
3353 quoted string. This means we've got a line consisting of only
3354 a newline in a quoted string. We want to make sure this line
3355 gets added to the history. */
3356 maybe_add_history (shell_input_line);
3357 else
3358 {
3359 char *hdcs;
3360 hdcs = history_delimiting_chars ();
3361 if (hdcs && hdcs[0] == ';')
3362 maybe_add_history (shell_input_line);
3363 }
3364 }
3365
3366 #endif /* HISTORY */
3367
3368 if (shell_input_line)
3369 {
3370 /* Lines that signify the end of the shell's input should not be
3371 echoed. */
3372 if (echo_input_at_read && (shell_input_line[0] ||
3373 shell_input_line_terminator != EOF))
3374 fprintf (stderr, "%s\n", shell_input_line);
3375 }
3376 else
3377 {
3378 shell_input_line_size = 0;
3379 prompt_string_pointer = &current_prompt_string;
3380 if (SHOULD_PROMPT ())
3381 prompt_again ();
3382 goto restart_read;
3383 }
3384
3385 /* Add the newline to the end of this string, iff the string does
3386 not already end in an EOF character. */
3387 if (shell_input_line_terminator != EOF)
3388 {
3389 if (shell_input_line_len + 3 > shell_input_line_size)
3390 shell_input_line = (char *)xrealloc (shell_input_line,
3391 1 + (shell_input_line_size += 2));
3392
3393 shell_input_line[shell_input_line_len] = '\n';
3394 shell_input_line[shell_input_line_len + 1] = '\0';
3395
3396 set_line_mbstate ();
3397 }
3398 }
3399
3400 uc = shell_input_line[shell_input_line_index];
3401
3402 if (uc)
3403 shell_input_line_index++;
3404
3405 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
3406 /* If UC is NULL, we have reached the end of the current input string. If
3407 pushed_string_list is non-empty, it's time to pop to the previous string
3408 because we have fully consumed the result of the last alias expansion.
3409 Do it transparently; just return the next character of the string popped
3410 to. */
3411 if (!uc && (pushed_string_list != (STRING_SAVER *)NULL))
3412 {
3413 pop_string ();
3414 uc = shell_input_line[shell_input_line_index];
3415 if (uc)
3416 shell_input_line_index++;
3417 }
3418 #endif /* ALIAS || DPAREN_ARITHMETIC */
3419
3420 if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
3421 {
3422 if (SHOULD_PROMPT ())
3423 prompt_again ();
3424 line_number++;
3425 goto restart_read;
3426 }
3427
3428 if (!uc && shell_input_line_terminator == EOF)
3429 return ((shell_input_line_index != 0) ? '\n' : EOF);
3430
3431 return (uc);
3432 }
3433
3434 /* Put C back into the input for the shell. This might need changes for
3435 HANDLE_MULTIBYTE around EOLs. Since we (currently) never push back a
3436 character different than we read, shell_input_line_property doesn't need
3437 to change when manipulating shell_input_line. The define for
3438 last_shell_getc_is_singlebyte should take care of it, though. */
3439 static void
3440 shell_ungetc (c)
3441 int c;
3442 {
3443 if (shell_input_line && shell_input_line_index)
3444 shell_input_line[--shell_input_line_index] = c;
3445 else
3446 eol_ungetc_lookahead = c;
3447 }
3448
3449 #ifdef INCLUDE_UNUSED
3450 /* Back the input pointer up by one, effectively `ungetting' a character. */
3451 static void
3452 shell_ungetchar ()
3453 {
3454 if (shell_input_line && shell_input_line_index)
3455 shell_input_line_index--;
3456 }
3457 #endif
3458
3459 /* Discard input until CHARACTER is seen, then push that character back
3460 onto the input stream. */
3461 static void
3462 discard_until (character)
3463 int character;
3464 {
3465 int c;
3466
3467 while ((c = shell_getc (0)) != EOF && c != character)
3468 ;
3469
3470 if (c != EOF)
3471 shell_ungetc (c);
3472 }
3473
3474 void
3475 execute_prompt_command (command)
3476 char *command;
3477 {
3478 char *last_lastarg;
3479 sh_parser_state_t ps;
3480
3481 save_parser_state (&ps);
3482 last_lastarg = get_string_value ("_");
3483 if (last_lastarg)
3484 last_lastarg = savestring (last_lastarg);
3485
3486 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
3487
3488 restore_parser_state (&ps);
3489 bind_variable ("_", last_lastarg, 0);
3490 FREE (last_lastarg);
3491
3492 if (token_to_read == '\n') /* reset_parser was called */
3493 token_to_read = 0;
3494 }
3495
3496 /* Place to remember the token. We try to keep the buffer
3497 at a reasonable size, but it can grow. */
3498 static char *token = (char *)NULL;
3499
3500 /* Current size of the token buffer. */
3501 static int token_buffer_size;
3502
3503 /* Command to read_token () explaining what we want it to do. */
3504 #define READ 0
3505 #define RESET 1
3506 #define prompt_is_ps1 \
3507 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
3508
3509 /* Function for yyparse to call. yylex keeps track of
3510 the last two tokens read, and calls read_token. */
3511 static int
3512 yylex ()
3513 {
3514 if (interactive && (current_token == 0 || current_token == '\n'))
3515 {
3516 /* Before we print a prompt, we might have to check mailboxes.
3517 We do this only if it is time to do so. Notice that only here
3518 is the mail alarm reset; nothing takes place in check_mail ()
3519 except the checking of mail. Please don't change this. */
3520 if (prompt_is_ps1 && time_to_check_mail ())
3521 {
3522 check_mail ();
3523 reset_mail_timer ();
3524 }
3525
3526 /* Avoid printing a prompt if we're not going to read anything, e.g.
3527 after resetting the parser with read_token (RESET). */
3528 if (token_to_read == 0 && SHOULD_PROMPT ())
3529 prompt_again ();
3530 }
3531
3532 two_tokens_ago = token_before_that;
3533 token_before_that = last_read_token;
3534 last_read_token = current_token;
3535 current_token = read_token (READ);
3536 return (current_token);
3537 }
3538
3539 /* When non-zero, we have read the required tokens
3540 which allow ESAC to be the next one read. */
3541 static int esacs_needed_count;
3542
3543 void
3544 gather_here_documents ()
3545 {
3546 int r = 0;
3547 while (need_here_doc)
3548 {
3549 make_here_document (redir_stack[r++]);
3550 need_here_doc--;
3551 }
3552 }
3553
3554 /* When non-zero, an open-brace used to create a group is awaiting a close
3555 brace partner. */
3556 static int open_brace_count;
3557
3558 #define command_token_position(token) \
3559 (((token) == ASSIGNMENT_WORD) || \
3560 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
3561
3562 #define assignment_acceptable(token) \
3563 (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
3564
3565 /* Check to see if TOKEN is a reserved word and return the token
3566 value if it is. */
3567 #define CHECK_FOR_RESERVED_WORD(tok) \
3568 do { \
3569 if (!dollar_present && !quoted && \
3570 reserved_word_acceptable (last_read_token)) \
3571 { \
3572 int i; \
3573 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
3574 if (STREQ (tok, word_token_alist[i].word)) \
3575 { \
3576 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
3577 break; \
3578 if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
3579 break; \
3580 if (word_token_alist[i].token == ESAC) \
3581 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
3582 else if (word_token_alist[i].token == CASE) \
3583 parser_state |= PST_CASESTMT; \
3584 else if (word_token_alist[i].token == COND_END) \
3585 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
3586 else if (word_token_alist[i].token == COND_START) \
3587 parser_state |= PST_CONDCMD; \
3588 else if (word_token_alist[i].token == '{') \
3589 open_brace_count++; \
3590 else if (word_token_alist[i].token == '}' && open_brace_count) \
3591 open_brace_count--; \
3592 return (word_token_alist[i].token); \
3593 } \
3594 } \
3595 } while (0)
3596
3597 #if defined (ALIAS)
3598
3599 /* OK, we have a token. Let's try to alias expand it, if (and only if)
3600 it's eligible.
3601
3602 It is eligible for expansion if EXPAND_ALIASES is set, and
3603 the token is unquoted and the last token read was a command
3604 separator (or expand_next_token is set), and we are currently
3605 processing an alias (pushed_string_list is non-empty) and this
3606 token is not the same as the current or any previously
3607 processed alias.
3608
3609 Special cases that disqualify:
3610 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
3611
3612 static char *
3613 mk_alexpansion (s)
3614 char *s;
3615 {
3616 int l;
3617 char *r;
3618
3619 l = strlen (s);
3620 r = xmalloc (l + 2);
3621 strcpy (r, s);
3622 if (r[l -1] != ' ')
3623 r[l++] = ' ';
3624 r[l] = '\0';
3625 return r;
3626 }
3627
3628 static int
3629 alias_expand_token (tokstr)
3630 char *tokstr;
3631 {
3632 char *expanded;
3633 alias_t *ap;
3634
3635 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
3636 (parser_state & PST_CASEPAT) == 0)
3637 {
3638 ap = find_alias (tokstr);
3639
3640 /* Currently expanding this token. */
3641 if (ap && (ap->flags & AL_BEINGEXPANDED))
3642 return (NO_EXPANSION);
3643
3644 /* mk_alexpansion puts an extra space on the end of the alias expansion,
3645 so the lookahead by the parser works right. If this gets changed,
3646 make sure the code in shell_getc that deals with reaching the end of
3647 an expanded alias is changed with it. */
3648 expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
3649
3650 if (expanded)
3651 {
3652 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
3653 return (RE_READ_TOKEN);
3654 }
3655 else
3656 /* This is an eligible token that does not have an expansion. */
3657 return (NO_EXPANSION);
3658 }
3659 return (NO_EXPANSION);
3660 }
3661 #endif /* ALIAS */
3662
3663 static int
3664 time_command_acceptable ()
3665 {
3666 #if defined (COMMAND_TIMING)
3667 switch (last_read_token)
3668 {
3669 case 0:
3670 case ';':
3671 case '\n':
3672 case AND_AND:
3673 case OR_OR:
3674 case '&':
3675 case DO:
3676 case THEN:
3677 case ELSE:
3678 case '{': /* } */
3679 case '(': /* ) */
3680 return 1;
3681 default:
3682 return 0;
3683 }
3684 #else
3685 return 0;
3686 #endif /* COMMAND_TIMING */
3687 }
3688
3689 /* Handle special cases of token recognition:
3690 IN is recognized if the last token was WORD and the token
3691 before that was FOR or CASE or SELECT.
3692
3693 DO is recognized if the last token was WORD and the token
3694 before that was FOR or SELECT.
3695
3696 ESAC is recognized if the last token caused `esacs_needed_count'
3697 to be set
3698
3699 `{' is recognized if the last token as WORD and the token
3700 before that was FUNCTION, or if we just parsed an arithmetic
3701 `for' command.
3702
3703 `}' is recognized if there is an unclosed `{' present.
3704
3705 `-p' is returned as TIMEOPT if the last read token was TIME.
3706
3707 ']]' is returned as COND_END if the parser is currently parsing
3708 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
3709
3710 `time' is returned as TIME if and only if it is immediately
3711 preceded by one of `;', `\n', `||', `&&', or `&'.
3712 */
3713
3714 static int
3715 special_case_tokens (tokstr)
3716 char *tokstr;
3717 {
3718 if ((last_read_token == WORD) &&
3719 #if defined (SELECT_COMMAND)
3720 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
3721 #else
3722 ((token_before_that == FOR) || (token_before_that == CASE)) &&
3723 #endif
3724 (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
3725 {
3726 if (token_before_that == CASE)
3727 {
3728 parser_state |= PST_CASEPAT;
3729 esacs_needed_count++;
3730 }
3731 return (IN);
3732 }
3733
3734 if (last_read_token == WORD &&
3735 #if defined (SELECT_COMMAND)
3736 (token_before_that == FOR || token_before_that == SELECT) &&
3737 #else
3738 (token_before_that == FOR) &&
3739 #endif
3740 (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
3741 return (DO);
3742
3743 /* Ditto for ESAC in the CASE case.
3744 Specifically, this handles "case word in esac", which is a legal
3745 construct, certainly because someone will pass an empty arg to the
3746 case construct, and we don't want it to barf. Of course, we should
3747 insist that the case construct has at least one pattern in it, but
3748 the designers disagree. */
3749 if (esacs_needed_count)
3750 {
3751 esacs_needed_count--;
3752 if (STREQ (tokstr, "esac"))
3753 {
3754 parser_state &= ~PST_CASEPAT;
3755 return (ESAC);
3756 }
3757 }
3758
3759 /* The start of a shell function definition. */
3760 if (parser_state & PST_ALLOWOPNBRC)
3761 {
3762 parser_state &= ~PST_ALLOWOPNBRC;
3763 if (tokstr[0] == '{' && tokstr[1] == '\0') /* } */
3764 {
3765 open_brace_count++;
3766 function_bstart = line_number;
3767 return ('{'); /* } */
3768 }
3769 }
3770
3771 /* We allow a `do' after a for ((...)) without an intervening
3772 list_terminator */
3773 if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
3774 return (DO);
3775 if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0') /* } */
3776 {
3777 open_brace_count++;
3778 return ('{'); /* } */
3779 }
3780
3781 if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
3782 {
3783 open_brace_count--; /* { */
3784 return ('}');
3785 }
3786
3787 #if defined (COMMAND_TIMING)
3788 /* Handle -p after `time'. */
3789 if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
3790 return (TIMEOPT);
3791 #endif
3792
3793 #if 0
3794 #if defined (COMMAND_TIMING)
3795 if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
3796 return (TIME);
3797 #endif /* COMMAND_TIMING */
3798 #endif
3799
3800 #if defined (COND_COMMAND) /* [[ */
3801 if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
3802 return (COND_END);
3803 #endif
3804
3805 return (-1);
3806 }
3807
3808 /* Called from shell.c when Control-C is typed at top level. Or
3809 by the error rule at top level. */
3810 void
3811 reset_parser ()
3812 {
3813 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3814 open_brace_count = 0;
3815
3816 parser_state = 0;
3817
3818 #if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
3819 if (pushed_string_list)
3820 free_string_list ();
3821 #endif /* ALIAS || DPAREN_ARITHMETIC */
3822
3823 if (shell_input_line)
3824 {
3825 free (shell_input_line);
3826 shell_input_line = (char *)NULL;
3827 shell_input_line_size = shell_input_line_index = 0;
3828 }
3829
3830 FREE (word_desc_to_read);
3831 word_desc_to_read = (WORD_DESC *)NULL;
3832
3833 last_read_token = '\n';
3834 token_to_read = '\n';
3835 }
3836
3837 /* Read the next token. Command can be READ (normal operation) or
3838 RESET (to normalize state). */
3839 static int
3840 read_token (command)
3841 int command;
3842 {
3843 int character; /* Current character. */
3844 int peek_char; /* Temporary look-ahead character. */
3845 int result; /* The thing to return. */
3846
3847 if (command == RESET)
3848 {
3849 reset_parser ();
3850 return ('\n');
3851 }
3852
3853 if (token_to_read)
3854 {
3855 result = token_to_read;
3856 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
3857 {
3858 yylval.word = word_desc_to_read;
3859 word_desc_to_read = (WORD_DESC *)NULL;
3860 }
3861 token_to_read = 0;
3862 return (result);
3863 }
3864
3865 #if defined (COND_COMMAND)
3866 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
3867 {
3868 cond_lineno = line_number;
3869 parser_state |= PST_CONDEXPR;
3870 yylval.command = parse_cond_command ();
3871 if (cond_token != COND_END)
3872 {
3873 cond_error ();
3874 return (-1);
3875 }
3876 token_to_read = COND_END;
3877 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
3878 return (COND_CMD);
3879 }
3880 #endif
3881
3882 #if defined (ALIAS)
3883 /* This is a place to jump back to once we have successfully expanded a
3884 token with an alias and pushed the string with push_string () */
3885 re_read_token:
3886 #endif /* ALIAS */
3887
3888 /* Read a single word from input. Start by skipping blanks. */
3889 while ((character = shell_getc (1)) != EOF && whitespace (character))
3890 ;
3891
3892 if (character == EOF)
3893 {
3894 EOF_Reached = 1;
3895 return (yacc_EOF);
3896 }
3897
3898 if MBTEST(character == '#' && (!interactive || interactive_comments))
3899 {
3900 /* A comment. Discard until EOL or EOF, and then return a newline. */
3901 discard_until ('\n');
3902 shell_getc (0);
3903 character = '\n'; /* this will take the next if statement and return. */
3904 }
3905
3906 if (character == '\n')
3907 {
3908 /* If we're about to return an unquoted newline, we can go and collect
3909 the text of any pending here document. */
3910 if (need_here_doc)
3911 gather_here_documents ();
3912
3913 #if defined (ALIAS)
3914 parser_state &= ~PST_ALEXPNEXT;
3915 #endif /* ALIAS */
3916
3917 parser_state &= ~PST_ASSIGNOK;
3918
3919 return (character);
3920 }
3921
3922 /* Shell meta-characters. */
3923 if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
3924 {
3925 #if defined (ALIAS)
3926 /* Turn off alias tokenization iff this character sequence would
3927 not leave us ready to read a command. */
3928 if (character == '<' || character == '>')
3929 parser_state &= ~PST_ALEXPNEXT;
3930 #endif /* ALIAS */
3931
3932 parser_state &= ~PST_ASSIGNOK;
3933
3934 peek_char = shell_getc (1);
3935 if (character == peek_char)
3936 {
3937 switch (character)
3938 {
3939 case '<':
3940 /* If '<' then we could be at "<<" or at "<<-". We have to
3941 look ahead one more character. */
3942 peek_char = shell_getc (1);
3943 if (peek_char == '-')
3944 return (LESS_LESS_MINUS);
3945 else if (peek_char == '<')
3946 return (LESS_LESS_LESS);
3947 else
3948 {
3949 shell_ungetc (peek_char);
3950 return (LESS_LESS);
3951 }
3952
3953 case '>':
3954 return (GREATER_GREATER);
3955
3956 case ';':
3957 parser_state |= PST_CASEPAT;
3958 #if defined (ALIAS)
3959 parser_state &= ~PST_ALEXPNEXT;
3960 #endif /* ALIAS */
3961
3962 return (SEMI_SEMI);
3963
3964 case '&':
3965 return (AND_AND);
3966
3967 case '|':
3968 return (OR_OR);
3969
3970 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
3971 case '(': /* ) */
3972 result = parse_dparen (character);
3973 if (result == -2)
3974 break;
3975 else
3976 return result;
3977 #endif
3978 }
3979 }
3980 else if MBTEST(character == '<' && peek_char == '&')
3981 return (LESS_AND);
3982 else if MBTEST(character == '>' && peek_char == '&')
3983 return (GREATER_AND);
3984 else if MBTEST(character == '<' && peek_char == '>')
3985 return (LESS_GREATER);
3986 else if MBTEST(character == '>' && peek_char == '|')
3987 return (GREATER_BAR);
3988 else if MBTEST(peek_char == '>' && character == '&')
3989 return (AND_GREATER);
3990
3991 shell_ungetc (peek_char);
3992
3993 /* If we look like we are reading the start of a function
3994 definition, then let the reader know about it so that
3995 we will do the right thing with `{'. */
3996 if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
3997 {
3998 parser_state |= PST_ALLOWOPNBRC;
3999 #if defined (ALIAS)
4000 parser_state &= ~PST_ALEXPNEXT;
4001 #endif /* ALIAS */
4002 function_dstart = line_number;
4003 }
4004
4005 /* case pattern lists may be preceded by an optional left paren. If
4006 we're not trying to parse a case pattern list, the left paren
4007 indicates a subshell. */
4008 if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
4009 parser_state |= PST_SUBSHELL;
4010 /*(*/
4011 else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
4012 parser_state &= ~PST_CASEPAT;
4013 /*(*/
4014 else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
4015 parser_state &= ~PST_SUBSHELL;
4016
4017 #if defined (PROCESS_SUBSTITUTION)
4018 /* Check for the constructs which introduce process substitution.
4019 Shells running in `posix mode' don't do process substitution. */
4020 if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
4021 #endif /* PROCESS_SUBSTITUTION */
4022 return (character);
4023 }
4024
4025 /* Hack <&- (close stdin) case. Also <&N- (dup and close). */
4026 if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
4027 return (character);
4028
4029 /* Okay, if we got this far, we have to read a word. Read one,
4030 and then check it against the known ones. */
4031 result = read_token_word (character);
4032 #if defined (ALIAS)
4033 if (result == RE_READ_TOKEN)
4034 goto re_read_token;
4035 #endif
4036 return result;
4037 }
4038
4039 /*
4040 * Match a $(...) or other grouping construct. This has to handle embedded
4041 * quoted strings ('', ``, "") and nested constructs. It also must handle
4042 * reprompting the user, if necessary, after reading a newline, and returning
4043 * correct error values if it reads EOF.
4044 */
4045 #define P_FIRSTCLOSE 0x01
4046 #define P_ALLOWESC 0x02
4047 #define P_DQUOTE 0x04
4048 #define P_COMMAND 0x08 /* parsing a command, so look for comments */
4049
4050 static char matched_pair_error;
4051 static char *
4052 parse_matched_pair (qc, open, close, lenp, flags)
4053 int qc; /* `"' if this construct is within double quotes */
4054 int open, close;
4055 int *lenp, flags;
4056 {
4057 int count, ch, was_dollar, in_comment, check_comment;
4058 int pass_next_character, nestlen, ttranslen, start_lineno;
4059 char *ret, *nestret, *ttrans;
4060 int retind, retsize, rflags;
4061
4062 count = 1;
4063 pass_next_character = was_dollar = in_comment = 0;
4064 check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
4065
4066 /* RFLAGS is the set of flags we want to pass to recursive calls. */
4067 rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
4068
4069 ret = (char *)xmalloc (retsize = 64);
4070 retind = 0;
4071
4072 start_lineno = line_number;
4073 while (count)
4074 {
4075 #if 0
4076 ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
4077 #else
4078 ch = shell_getc (qc != '\'' && pass_next_character == 0);
4079 #endif
4080 if (ch == EOF)
4081 {
4082 free (ret);
4083 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
4084 EOF_Reached = 1; /* XXX */
4085 return (&matched_pair_error);
4086 }
4087
4088 /* Possible reprompting. */
4089 if (ch == '\n' && SHOULD_PROMPT ())
4090 prompt_again ();
4091
4092 if (in_comment)
4093 {
4094 /* Add this character. */
4095 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4096 ret[retind++] = ch;
4097
4098 if (ch == '\n')
4099 in_comment = 0;
4100
4101 continue;
4102 }
4103 /* Not exactly right yet */
4104 else if (check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind -1])))
4105 in_comment = 1;
4106
4107 if (pass_next_character) /* last char was backslash */
4108 {
4109 pass_next_character = 0;
4110 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
4111 {
4112 if (retind > 0) retind--; /* swallow previously-added backslash */
4113 continue;
4114 }
4115
4116 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
4117 if MBTEST(ch == CTLESC || ch == CTLNUL)
4118 ret[retind++] = CTLESC;
4119 ret[retind++] = ch;
4120 continue;
4121 }
4122 else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
4123 {
4124 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
4125 ret[retind++] = CTLESC;
4126 ret[retind++] = ch;
4127 continue;
4128 }
4129 else if MBTEST(ch == close) /* ending delimiter */
4130 count--;
4131 #if 1
4132 /* handle nested ${...} specially. */
4133 else if MBTEST(open != close && was_dollar && open == '{' && ch == open) /* } */
4134 count++;
4135 #endif
4136 else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
4137 count++;
4138
4139 /* Add this character. */
4140 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4141 ret[retind++] = ch;
4142
4143 if (open == '\'') /* '' inside grouping construct */
4144 {
4145 if MBTEST((flags & P_ALLOWESC) && ch == '\\')
4146 pass_next_character++;
4147 continue;
4148 }
4149
4150 if MBTEST(ch == '\\') /* backslashes */
4151 pass_next_character++;
4152
4153 if (open != close) /* a grouping construct */
4154 {
4155 if MBTEST(shellquote (ch))
4156 {
4157 /* '', ``, or "" inside $(...) or other grouping construct. */
4158 push_delimiter (dstack, ch);
4159 if MBTEST(was_dollar && ch == '\'') /* $'...' inside group */
4160 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
4161 else
4162 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
4163 pop_delimiter (dstack);
4164 if (nestret == &matched_pair_error)
4165 {
4166 free (ret);
4167 return &matched_pair_error;
4168 }
4169 if MBTEST(was_dollar && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
4170 {
4171 /* Translate $'...' here. */
4172 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
4173 xfree (nestret);
4174
4175 if ((rflags & P_DQUOTE) == 0)
4176 {
4177 nestret = sh_single_quote (ttrans);
4178 free (ttrans);
4179 nestlen = strlen (nestret);
4180 }
4181 else
4182 {
4183 nestret = ttrans;
4184 nestlen = ttranslen;
4185 }
4186 retind -= 2; /* back up before the $' */
4187 }
4188 else if MBTEST(was_dollar && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
4189 {
4190 /* Locale expand $"..." here. */
4191 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
4192 xfree (nestret);
4193
4194 nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
4195 free (ttrans);
4196 nestlen = ttranslen + 2;
4197 retind -= 2; /* back up before the $" */
4198 }
4199
4200 if (nestlen)
4201 {
4202 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
4203 strcpy (ret + retind, nestret);
4204 retind += nestlen;
4205 }
4206 FREE (nestret);
4207 }
4208 }
4209 /* Parse an old-style command substitution within double quotes as a
4210 single word. */
4211 /* XXX - sh and ksh93 don't do this - XXX */
4212 else if MBTEST(open == '"' && ch == '`')
4213 {
4214 nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
4215 add_nestret:
4216 if (nestret == &matched_pair_error)
4217 {
4218 free (ret);
4219 return &matched_pair_error;
4220 }
4221 if (nestlen)
4222 {
4223 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
4224 strcpy (ret + retind, nestret);
4225 retind += nestlen;
4226 }
4227 FREE (nestret);
4228 }
4229 else if MBTEST(qc == '`' && (ch == '"' || ch == '\'') && in_comment == 0)
4230 {
4231 nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags);
4232 goto add_nestret;
4233 }
4234 else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
4235 /* check for $(), $[], or ${} inside quoted string. */
4236 {
4237 if (open == ch) /* undo previous increment */
4238 count--;
4239 if (ch == '(') /* ) */
4240 nestret = parse_matched_pair (0, '(', ')', &nestlen, rflags);
4241 else if (ch == '{') /* } */
4242 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|rflags);
4243 else if (ch == '[') /* ] */
4244 nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
4245
4246 goto add_nestret;
4247 }
4248 was_dollar = MBTEST(ch == '$');
4249 }
4250
4251 ret[retind] = '\0';
4252 if (lenp)
4253 *lenp = retind;
4254 return ret;
4255 }
4256
4257 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
4258 /* Parse a double-paren construct. It can be either an arithmetic
4259 command, an arithmetic `for' command, or a nested subshell. Returns
4260 the parsed token, -1 on error, or -2 if we didn't do anything and
4261 should just go on. */
4262 static int
4263 parse_dparen (c)
4264 int c;
4265 {
4266 int cmdtyp, len, sline;
4267 char *wval, *wv2;
4268 WORD_DESC *wd;
4269
4270 #if defined (ARITH_FOR_COMMAND)
4271 if (last_read_token == FOR)
4272 {
4273 arith_for_lineno = line_number;
4274 cmdtyp = parse_arith_cmd (&wval, 0);
4275 if (cmdtyp == 1)
4276 {
4277 wd = alloc_word_desc ();
4278 wd->word = wval;
4279 wd = make_word (wval);
4280 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
4281 return (ARITH_FOR_EXPRS);
4282 }
4283 else
4284 return -1; /* ERROR */
4285 }
4286 #endif
4287
4288 #if defined (DPAREN_ARITHMETIC)
4289 if (reserved_word_acceptable (last_read_token))
4290 {
4291 sline = line_number;
4292
4293 cmdtyp = parse_arith_cmd (&wval, 0);
4294 if (cmdtyp == 1) /* arithmetic command */
4295 {
4296 wd = alloc_word_desc ();
4297 wd->word = wval;
4298 wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
4299 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
4300 return (ARITH_CMD);
4301 }
4302 else if (cmdtyp == 0) /* nested subshell */
4303 {
4304 push_string (wval, 0, (alias_t *)NULL);
4305 if ((parser_state & PST_CASEPAT) == 0)
4306 parser_state |= PST_SUBSHELL;
4307 return (c);
4308 }
4309 else /* ERROR */
4310 return -1;
4311 }
4312 #endif
4313
4314 return -2; /* XXX */
4315 }
4316
4317 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
4318 If not, assume it's a nested subshell for backwards compatibility and
4319 return 0. In any case, put the characters we've consumed into a locally-
4320 allocated buffer and make *ep point to that buffer. Return -1 on an
4321 error, for example EOF. */
4322 static int
4323 parse_arith_cmd (ep, adddq)
4324 char **ep;
4325 int adddq;
4326 {
4327 int exp_lineno, rval, c;
4328 char *ttok, *tokstr;
4329 int ttoklen;
4330
4331 exp_lineno = line_number;
4332 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
4333 rval = 1;
4334 if (ttok == &matched_pair_error)
4335 return -1;
4336 /* Check that the next character is the closing right paren. If
4337 not, this is a syntax error. ( */
4338 c = shell_getc (0);
4339 if MBTEST(c != ')')
4340 rval = 0;
4341
4342 tokstr = (char *)xmalloc (ttoklen + 4);
4343
4344 /* if ADDDQ != 0 then (( ... )) -> "..." */
4345 if (rval == 1 && adddq) /* arith cmd, add double quotes */
4346 {
4347 tokstr[0] = '"';
4348 strncpy (tokstr + 1, ttok, ttoklen - 1);
4349 tokstr[ttoklen] = '"';
4350 tokstr[ttoklen+1] = '\0';
4351 }
4352 else if (rval == 1) /* arith cmd, don't add double quotes */
4353 {
4354 strncpy (tokstr, ttok, ttoklen - 1);
4355 tokstr[ttoklen-1] = '\0';
4356 }
4357 else /* nested subshell */
4358 {
4359 tokstr[0] = '(';
4360 strncpy (tokstr + 1, ttok, ttoklen - 1);
4361 tokstr[ttoklen] = ')';
4362 tokstr[ttoklen+1] = c;
4363 tokstr[ttoklen+2] = '\0';
4364 }
4365
4366 *ep = tokstr;
4367 FREE (ttok);
4368 return rval;
4369 }
4370 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
4371
4372 #if defined (COND_COMMAND)
4373 static void
4374 cond_error ()
4375 {
4376 char *etext;
4377
4378 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
4379 parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
4380 else if (cond_token != COND_ERROR)
4381 {
4382 if (etext = error_token_from_token (cond_token))
4383 {
4384 parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
4385 free (etext);
4386 }
4387 else
4388 parser_error (cond_lineno, _("syntax error in conditional expression"));
4389 }
4390 }
4391
4392 static COND_COM *
4393 cond_expr ()
4394 {
4395 return (cond_or ());
4396 }
4397
4398 static COND_COM *
4399 cond_or ()
4400 {
4401 COND_COM *l, *r;
4402
4403 l = cond_and ();
4404 if (cond_token == OR_OR)
4405 {
4406 r = cond_or ();
4407 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
4408 }
4409 return l;
4410 }
4411
4412 static COND_COM *
4413 cond_and ()
4414 {
4415 COND_COM *l, *r;
4416
4417 l = cond_term ();
4418 if (cond_token == AND_AND)
4419 {
4420 r = cond_and ();
4421 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
4422 }
4423 return l;
4424 }
4425
4426 static int
4427 cond_skip_newlines ()
4428 {
4429 while ((cond_token = read_token (READ)) == '\n')
4430 {
4431 if (SHOULD_PROMPT ())
4432 prompt_again ();
4433 }
4434 return (cond_token);
4435 }
4436
4437 #define COND_RETURN_ERROR() \
4438 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
4439
4440 static COND_COM *
4441 cond_term ()
4442 {
4443 WORD_DESC *op;
4444 COND_COM *term, *tleft, *tright;
4445 int tok, lineno;
4446 char *etext;
4447
4448 /* Read a token. It can be a left paren, a `!', a unary operator, or a
4449 word that should be the first argument of a binary operator. Start by
4450 skipping newlines, since this is a compound command. */
4451 tok = cond_skip_newlines ();
4452 lineno = line_number;
4453 if (tok == COND_END)
4454 {
4455 COND_RETURN_ERROR ();
4456 }
4457 else if (tok == '(')
4458 {
4459 term = cond_expr ();
4460 if (cond_token != ')')
4461 {
4462 if (term)
4463 dispose_cond_node (term); /* ( */
4464 if (etext = error_token_from_token (cond_token))
4465 {
4466 parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
4467 free (etext);
4468 }
4469 else
4470 parser_error (lineno, _("expected `)'"));
4471 COND_RETURN_ERROR ();
4472 }
4473 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
4474 (void)cond_skip_newlines ();
4475 }
4476 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
4477 {
4478 if (tok == WORD)
4479 dispose_word (yylval.word); /* not needed */
4480 term = cond_term ();
4481 if (term)
4482 term->flags |= CMD_INVERT_RETURN;
4483 }
4484 else if (tok == WORD && test_unop (yylval.word->word))
4485 {
4486 op = yylval.word;
4487 tok = read_token (READ);
4488 if (tok == WORD)
4489 {
4490 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4491 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4492 }
4493 else
4494 {
4495 dispose_word (op);
4496 if (etext = error_token_from_token (tok))
4497 {
4498 parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
4499 free (etext);
4500 }
4501 else
4502 parser_error (line_number, _("unexpected argument to conditional unary operator"));
4503 COND_RETURN_ERROR ();
4504 }
4505
4506 (void)cond_skip_newlines ();
4507 }
4508 else if (tok == WORD) /* left argument to binary operator */
4509 {
4510 /* lhs */
4511 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4512
4513 /* binop */
4514 tok = read_token (READ);
4515 if (tok == WORD && test_binop (yylval.word->word))
4516 op = yylval.word;
4517 #if defined (COND_REGEXP)
4518 else if (tok == WORD && STREQ (yylval.word->word,"=~"))
4519 op = yylval.word;
4520 #endif
4521 else if (tok == '<' || tok == '>')
4522 op = make_word_from_token (tok); /* ( */
4523 /* There should be a check before blindly accepting the `)' that we have
4524 seen the opening `('. */
4525 else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
4526 {
4527 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
4528 the test command. Similarly for [[ x && expr ]] or
4529 [[ x || expr ]] or [[ (x) ]]. */
4530 op = make_word ("-n");
4531 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4532 cond_token = tok;
4533 return (term);
4534 }
4535 else
4536 {
4537 if (etext = error_token_from_token (tok))
4538 {
4539 parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
4540 free (etext);
4541 }
4542 else
4543 parser_error (line_number, _("conditional binary operator expected"));
4544 dispose_cond_node (tleft);
4545 COND_RETURN_ERROR ();
4546 }
4547
4548 /* rhs */
4549 tok = read_token (READ);
4550 if (tok == WORD)
4551 {
4552 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4553 term = make_cond_node (COND_BINARY, op, tleft, tright);
4554 }
4555 else
4556 {
4557 if (etext = error_token_from_token (tok))
4558 {
4559 parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
4560 free (etext);
4561 }
4562 else
4563 parser_error (line_number, _("unexpected argument to conditional binary operator"));
4564 dispose_cond_node (tleft);
4565 dispose_word (op);
4566 COND_RETURN_ERROR ();
4567 }
4568
4569 (void)cond_skip_newlines ();
4570 }
4571 else
4572 {
4573 if (tok < 256)
4574 parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
4575 else if (etext = error_token_from_token (tok))
4576 {
4577 parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
4578 free (etext);
4579 }
4580 else
4581 parser_error (line_number, _("unexpected token %d in conditional command"), tok);
4582 COND_RETURN_ERROR ();
4583 }
4584 return (term);
4585 }
4586
4587 /* This is kind of bogus -- we slip a mini recursive-descent parser in
4588 here to handle the conditional statement syntax. */
4589 static COMMAND *
4590 parse_cond_command ()
4591 {
4592 COND_COM *cexp;
4593
4594 cexp = cond_expr ();
4595 return (make_cond_command (cexp));
4596 }
4597 #endif
4598
4599 #if defined (ARRAY_VARS)
4600 /* When this is called, it's guaranteed that we don't care about anything
4601 in t beyond i. We do save and restore the chars, though. */
4602 static int
4603 token_is_assignment (t, i)
4604 char *t;
4605 int i;
4606 {
4607 unsigned char c, c1;
4608 int r;
4609
4610 c = t[i]; c1 = t[i+1];
4611 t[i] = '='; t[i+1] = '\0';
4612 r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
4613 t[i] = c; t[i+1] = c1;
4614 return r;
4615 }
4616
4617 /* XXX - possible changes here for `+=' */
4618 static int
4619 token_is_ident (t, i)
4620 char *t;
4621 int i;
4622 {
4623 unsigned char c;
4624 int r;
4625
4626 c = t[i];
4627 t[i] = '\0';
4628 r = legal_identifier (t);
4629 t[i] = c;
4630 return r;
4631 }
4632 #endif
4633
4634 static int
4635 read_token_word (character)
4636 int character;
4637 {
4638 /* The value for YYLVAL when a WORD is read. */
4639 WORD_DESC *the_word;
4640
4641 /* Index into the token that we are building. */
4642 int token_index;
4643
4644 /* ALL_DIGITS becomes zero when we see a non-digit. */
4645 int all_digit_token;
4646
4647 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
4648 int dollar_present;
4649
4650 /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
4651 assignment. */
4652 int compound_assignment;
4653
4654 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
4655 int quoted;
4656
4657 /* Non-zero means to ignore the value of the next character, and just
4658 to add it no matter what. */
4659 int pass_next_character;
4660
4661 /* The current delimiting character. */
4662 int cd;
4663 int result, peek_char;
4664 char *ttok, *ttrans;
4665 int ttoklen, ttranslen;
4666 intmax_t lvalue;
4667
4668 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
4669 token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
4670
4671 token_index = 0;
4672 all_digit_token = DIGIT (character);
4673 dollar_present = quoted = pass_next_character = compound_assignment = 0;
4674
4675 for (;;)
4676 {
4677 if (character == EOF)
4678 goto got_token;
4679
4680 if (pass_next_character)
4681 {
4682 pass_next_character = 0;
4683 goto got_character;
4684 }
4685
4686 cd = current_delimiter (dstack);
4687
4688 /* Handle backslashes. Quote lots of things when not inside of
4689 double-quotes, quote some things inside of double-quotes. */
4690 if MBTEST(character == '\\')
4691 {
4692 peek_char = shell_getc (0);
4693
4694 /* Backslash-newline is ignored in all cases except
4695 when quoted with single quotes. */
4696 if (peek_char == '\n')
4697 {
4698 character = '\n';
4699 goto next_character;
4700 }
4701 else
4702 {
4703 shell_ungetc (peek_char);
4704
4705 /* If the next character is to be quoted, note it now. */
4706 if (cd == 0 || cd == '`' ||
4707 (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
4708 pass_next_character++;
4709
4710 quoted = 1;
4711 goto got_character;
4712 }
4713 }
4714
4715 /* Parse a matched pair of quote characters. */
4716 if MBTEST(shellquote (character))
4717 {
4718 push_delimiter (dstack, character);
4719 ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
4720 pop_delimiter (dstack);
4721 if (ttok == &matched_pair_error)
4722 return -1; /* Bail immediately. */
4723 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4724 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4725 token[token_index++] = character;
4726 strcpy (token + token_index, ttok);
4727 token_index += ttoklen;
4728 all_digit_token = 0;
4729 quoted = 1;
4730 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
4731 FREE (ttok);
4732 goto next_character;
4733 }
4734
4735 #ifdef EXTENDED_GLOB
4736 /* Parse a ksh-style extended pattern matching specification. */
4737 if (extended_glob && PATTERN_CHAR (character))
4738 {
4739 peek_char = shell_getc (1);
4740 if MBTEST(peek_char == '(') /* ) */
4741 {
4742 push_delimiter (dstack, peek_char);
4743 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4744 pop_delimiter (dstack);
4745 if (ttok == &matched_pair_error)
4746 return -1; /* Bail immediately. */
4747 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4748 token_buffer_size,
4749 TOKEN_DEFAULT_GROW_SIZE);
4750 token[token_index++] = character;
4751 token[token_index++] = peek_char;
4752 strcpy (token + token_index, ttok);
4753 token_index += ttoklen;
4754 FREE (ttok);
4755 dollar_present = all_digit_token = 0;
4756 goto next_character;
4757 }
4758 else
4759 shell_ungetc (peek_char);
4760 }
4761 #endif /* EXTENDED_GLOB */
4762
4763 /* If the delimiter character is not single quote, parse some of
4764 the shell expansions that must be read as a single word. */
4765 if (shellexp (character))
4766 {
4767 peek_char = shell_getc (1);
4768 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
4769 if MBTEST(peek_char == '(' || \
4770 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
4771 {
4772 if (peek_char == '{') /* } */
4773 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
4774 else if (peek_char == '(') /* ) */
4775 {
4776 /* XXX - push and pop the `(' as a delimiter for use by
4777 the command-oriented-history code. This way newlines
4778 appearing in the $(...) string get added to the
4779 history literally rather than causing a possibly-
4780 incorrect `;' to be added. ) */
4781 push_delimiter (dstack, peek_char);
4782 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, P_COMMAND);
4783 pop_delimiter (dstack);
4784 }
4785 else
4786 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4787 if (ttok == &matched_pair_error)
4788 return -1; /* Bail immediately. */
4789 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4790 token_buffer_size,
4791 TOKEN_DEFAULT_GROW_SIZE);
4792 token[token_index++] = character;
4793 token[token_index++] = peek_char;
4794 strcpy (token + token_index, ttok);
4795 token_index += ttoklen;
4796 FREE (ttok);
4797 dollar_present = 1;
4798 all_digit_token = 0;
4799 goto next_character;
4800 }
4801 /* This handles $'...' and $"..." new-style quoted strings. */
4802 else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
4803 {
4804 int first_line;
4805
4806 first_line = line_number;
4807 push_delimiter (dstack, peek_char);
4808 ttok = parse_matched_pair (peek_char, peek_char, peek_char,
4809 &ttoklen,
4810 (peek_char == '\'') ? P_ALLOWESC : 0);
4811 pop_delimiter (dstack);
4812 if (ttok == &matched_pair_error)
4813 return -1;
4814 if (peek_char == '\'')
4815 {
4816 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4817 free (ttok);
4818
4819 /* Insert the single quotes and correctly quote any
4820 embedded single quotes (allowed because P_ALLOWESC was
4821 passed to parse_matched_pair). */
4822 ttok = sh_single_quote (ttrans);
4823 free (ttrans);
4824 ttranslen = strlen (ttok);
4825 ttrans = ttok;
4826 }
4827 else
4828 {
4829 /* Try to locale)-expand the converted string. */
4830 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4831 free (ttok);
4832
4833 /* Add the double quotes back */
4834 ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
4835 free (ttrans);
4836 ttranslen += 2;
4837 ttrans = ttok;
4838 }
4839
4840 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
4841 token_buffer_size,
4842 TOKEN_DEFAULT_GROW_SIZE);
4843 strcpy (token + token_index, ttrans);
4844 token_index += ttranslen;
4845 FREE (ttrans);
4846 quoted = 1;
4847 all_digit_token = 0;
4848 goto next_character;
4849 }
4850 /* This could eventually be extended to recognize all of the
4851 shell's single-character parameter expansions, and set flags.*/
4852 else if MBTEST(character == '$' && peek_char == '$')
4853 {
4854 ttok = (char *)xmalloc (3);
4855 ttok[0] = ttok[1] = '$';
4856 ttok[2] = '\0';
4857 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
4858 token_buffer_size,
4859 TOKEN_DEFAULT_GROW_SIZE);
4860 strcpy (token + token_index, ttok);
4861 token_index += 2;
4862 dollar_present = 1;
4863 all_digit_token = 0;
4864 FREE (ttok);
4865 goto next_character;
4866 }
4867 else
4868 shell_ungetc (peek_char);
4869 }
4870
4871 #if defined (ARRAY_VARS)
4872 /* Identify possible array subscript assignment; match [...] */
4873 else if MBTEST(character == '[' && token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) /* ] */
4874 {
4875 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4876 if (ttok == &matched_pair_error)
4877 return -1; /* Bail immediately. */
4878 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4879 token_buffer_size,
4880 TOKEN_DEFAULT_GROW_SIZE);
4881 token[token_index++] = character;
4882 strcpy (token + token_index, ttok);
4883 token_index += ttoklen;
4884 FREE (ttok);
4885 all_digit_token = 0;
4886 goto next_character;
4887 }
4888 /* Identify possible compound array variable assignment. */
4889 else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
4890 {
4891 peek_char = shell_getc (1);
4892 if MBTEST(peek_char == '(') /* ) */
4893 {
4894 ttok = parse_compound_assignment (&ttoklen);
4895
4896 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
4897 token_buffer_size,
4898 TOKEN_DEFAULT_GROW_SIZE);
4899
4900 token[token_index++] = '=';
4901 token[token_index++] = '(';
4902 if (ttok)
4903 {
4904 strcpy (token + token_index, ttok);
4905 token_index += ttoklen;
4906 }
4907 token[token_index++] = ')';
4908 FREE (ttok);
4909 all_digit_token = 0;
4910 compound_assignment = 1;
4911 #if 0
4912 goto next_character;
4913 #else
4914 goto got_token; /* ksh93 seems to do this */
4915 #endif
4916 }
4917 else
4918 shell_ungetc (peek_char);
4919 }
4920 #endif
4921
4922 /* When not parsing a multi-character word construct, shell meta-
4923 characters break words. */
4924 if MBTEST(shellbreak (character))
4925 {
4926 shell_ungetc (character);
4927 goto got_token;
4928 }
4929
4930 got_character:
4931
4932 all_digit_token &= DIGIT (character);
4933 dollar_present |= character == '$';
4934
4935 if (character == CTLESC || character == CTLNUL)
4936 token[token_index++] = CTLESC;
4937
4938 token[token_index++] = character;
4939
4940 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
4941 TOKEN_DEFAULT_GROW_SIZE);
4942
4943 next_character:
4944 if (character == '\n' && SHOULD_PROMPT ())
4945 prompt_again ();
4946
4947 /* We want to remove quoted newlines (that is, a \<newline> pair)
4948 unless we are within single quotes or pass_next_character is
4949 set (the shell equivalent of literal-next). */
4950 cd = current_delimiter (dstack);
4951 character = shell_getc (cd != '\'' && pass_next_character == 0);
4952 } /* end for (;;) */
4953
4954 got_token:
4955
4956 token[token_index] = '\0';
4957
4958 /* Check to see what thing we should return. If the last_read_token
4959 is a `<', or a `&', or the character which ended this token is
4960 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
4961 Otherwise, it is just a word, and should be returned as such. */
4962 if MBTEST(all_digit_token && (character == '<' || character == '>' || \
4963 last_read_token == LESS_AND || \
4964 last_read_token == GREATER_AND))
4965 {
4966 if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
4967 yylval.number = lvalue;
4968 else
4969 yylval.number = -1;
4970 return (NUMBER);
4971 }
4972
4973 /* Check for special case tokens. */
4974 result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
4975 if (result >= 0)
4976 return result;
4977
4978 #if defined (ALIAS)
4979 /* Posix.2 does not allow reserved words to be aliased, so check for all
4980 of them, including special cases, before expanding the current token
4981 as an alias. */
4982 if MBTEST(posixly_correct)
4983 CHECK_FOR_RESERVED_WORD (token);
4984
4985 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
4986 inhibits alias expansion. */
4987 if (expand_aliases && quoted == 0)
4988 {
4989 result = alias_expand_token (token);
4990 if (result == RE_READ_TOKEN)
4991 return (RE_READ_TOKEN);
4992 else if (result == NO_EXPANSION)
4993 parser_state &= ~PST_ALEXPNEXT;
4994 }
4995
4996 /* If not in Posix.2 mode, check for reserved words after alias
4997 expansion. */
4998 if MBTEST(posixly_correct == 0)
4999 #endif
5000 CHECK_FOR_RESERVED_WORD (token);
5001
5002 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
5003 the_word->word = (char *)xmalloc (1 + token_index);
5004 the_word->flags = 0;
5005 strcpy (the_word->word, token);
5006 if (dollar_present)
5007 the_word->flags |= W_HASDOLLAR;
5008 if (quoted)
5009 the_word->flags |= W_QUOTED;
5010 if (compound_assignment)
5011 the_word->flags |= W_COMPASSIGN;
5012 /* A word is an assignment if it appears at the beginning of a
5013 simple command, or after another assignment word. This is
5014 context-dependent, so it cannot be handled in the grammar. */
5015 if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
5016 {
5017 the_word->flags |= W_ASSIGNMENT;
5018 /* Don't perform word splitting on assignment statements. */
5019 if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
5020 the_word->flags |= W_NOSPLIT;
5021 }
5022
5023 if (command_token_position (last_read_token))
5024 {
5025 struct builtin *b;
5026 b = builtin_address_internal (token, 0);
5027 if (b && (b->flags & ASSIGNMENT_BUILTIN))
5028 parser_state |= PST_ASSIGNOK;
5029 }
5030
5031 yylval.word = the_word;
5032
5033 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
5034 ? ASSIGNMENT_WORD : WORD;
5035
5036 switch (last_read_token)
5037 {
5038 case FUNCTION:
5039 parser_state |= PST_ALLOWOPNBRC;
5040 function_dstart = line_number;
5041 break;
5042 case CASE:
5043 case SELECT:
5044 case FOR:
5045 if (word_top < MAX_CASE_NEST)
5046 word_top++;
5047 word_lineno[word_top] = line_number;
5048 break;
5049 }
5050
5051 return (result);
5052 }
5053
5054 /* Return 1 if TOKSYM is a token that after being read would allow
5055 a reserved word to be seen, else 0. */
5056 static int
5057 reserved_word_acceptable (toksym)
5058 int toksym;
5059 {
5060 switch (toksym)
5061 {
5062 case '\n':
5063 case ';':
5064 case '(':
5065 case ')':
5066 case '|':
5067 case '&':
5068 case '{':
5069 case '}': /* XXX */
5070 case AND_AND:
5071 case BANG:
5072 case DO:
5073 case DONE:
5074 case ELIF:
5075 case ELSE:
5076 case ESAC:
5077 case FI:
5078 case IF:
5079 case OR_OR:
5080 case SEMI_SEMI:
5081 case THEN:
5082 case TIME:
5083 case TIMEOPT:
5084 case UNTIL:
5085 case WHILE:
5086 case 0:
5087 return 1;
5088 default:
5089 return 0;
5090 }
5091 }
5092
5093 /* Return the index of TOKEN in the alist of reserved words, or -1 if
5094 TOKEN is not a shell reserved word. */
5095 int
5096 find_reserved_word (tokstr)
5097 char *tokstr;
5098 {
5099 int i;
5100 for (i = 0; word_token_alist[i].word; i++)
5101 if (STREQ (tokstr, word_token_alist[i].word))
5102 return i;
5103 return -1;
5104 }
5105
5106 #if 0
5107 #if defined (READLINE)
5108 /* Called after each time readline is called. This insures that whatever
5109 the new prompt string is gets propagated to readline's local prompt
5110 variable. */
5111 static void
5112 reset_readline_prompt ()
5113 {
5114 char *temp_prompt;
5115
5116 if (prompt_string_pointer)
5117 {
5118 temp_prompt = (*prompt_string_pointer)
5119 ? decode_prompt_string (*prompt_string_pointer)
5120 : (char *)NULL;
5121
5122 if (temp_prompt == 0)
5123 {
5124 temp_prompt = (char *)xmalloc (1);
5125 temp_prompt[0] = '\0';
5126 }
5127
5128 FREE (current_readline_prompt);
5129 current_readline_prompt = temp_prompt;
5130 }
5131 }
5132 #endif /* READLINE */
5133 #endif /* 0 */
5134
5135 #if defined (HISTORY)
5136 /* A list of tokens which can be followed by newlines, but not by
5137 semi-colons. When concatenating multiple lines of history, the
5138 newline separator for such tokens is replaced with a space. */
5139 static int no_semi_successors[] = {
5140 '\n', '{', '(', ')', ';', '&', '|',
5141 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
5142 0
5143 };
5144
5145 /* If we are not within a delimited expression, try to be smart
5146 about which separators can be semi-colons and which must be
5147 newlines. Returns the string that should be added into the
5148 history entry. */
5149 char *
5150 history_delimiting_chars ()
5151 {
5152 register int i;
5153
5154 if (dstack.delimiter_depth != 0)
5155 return ("\n");
5156
5157 /* First, handle some special cases. */
5158 /*(*/
5159 /* If we just read `()', assume it's a function definition, and don't
5160 add a semicolon. If the token before the `)' was not `(', and we're
5161 not in the midst of parsing a case statement, assume it's a
5162 parenthesized command and add the semicolon. */
5163 /*)(*/
5164 if (token_before_that == ')')
5165 {
5166 if (two_tokens_ago == '(') /*)*/ /* function def */
5167 return " ";
5168 /* This does not work for subshells inside case statement
5169 command lists. It's a suboptimal solution. */
5170 else if (parser_state & PST_CASESTMT) /* case statement pattern */
5171 return " ";
5172 else
5173 return "; "; /* (...) subshell */
5174 }
5175 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
5176 return " "; /* function def using `function name' without `()' */
5177
5178 else if (token_before_that == WORD && two_tokens_ago == FOR)
5179 {
5180 /* Tricky. `for i\nin ...' should not have a semicolon, but
5181 `for i\ndo ...' should. We do what we can. */
5182 for (i = shell_input_line_index; whitespace(shell_input_line[i]); i++)
5183 ;
5184 if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
5185 return " ";
5186 return ";";
5187 }
5188 else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
5189 return " ";
5190
5191 for (i = 0; no_semi_successors[i]; i++)
5192 {
5193 if (token_before_that == no_semi_successors[i])
5194 return (" ");
5195 }
5196
5197 return ("; ");
5198 }
5199 #endif /* HISTORY */
5200
5201 /* Issue a prompt, or prepare to issue a prompt when the next character
5202 is read. */
5203 static void
5204 prompt_again ()
5205 {
5206 char *temp_prompt;
5207
5208 if (interactive == 0 || expanding_alias()) /* XXX */
5209 return;
5210
5211 ps1_prompt = get_string_value ("PS1");
5212 ps2_prompt = get_string_value ("PS2");
5213
5214 if (!prompt_string_pointer)
5215 prompt_string_pointer = &ps1_prompt;
5216
5217 temp_prompt = *prompt_string_pointer
5218 ? decode_prompt_string (*prompt_string_pointer)
5219 : (char *)NULL;
5220
5221 if (temp_prompt == 0)
5222 {
5223 temp_prompt = (char *)xmalloc (1);
5224 temp_prompt[0] = '\0';
5225 }
5226
5227 current_prompt_string = *prompt_string_pointer;
5228 prompt_string_pointer = &ps2_prompt;
5229
5230 #if defined (READLINE)
5231 if (!no_line_editing)
5232 {
5233 FREE (current_readline_prompt);
5234 current_readline_prompt = temp_prompt;
5235 }
5236 else
5237 #endif /* READLINE */
5238 {
5239 FREE (current_decoded_prompt);
5240 current_decoded_prompt = temp_prompt;
5241 }
5242 }
5243
5244 int
5245 get_current_prompt_level ()
5246 {
5247 return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
5248 }
5249
5250 void
5251 set_current_prompt_level (x)
5252 int x;
5253 {
5254 prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
5255 current_prompt_string = *prompt_string_pointer;
5256 }
5257
5258 static void
5259 print_prompt ()
5260 {
5261 fprintf (stderr, "%s", current_decoded_prompt);
5262 fflush (stderr);
5263 }
5264
5265 /* Return a string which will be printed as a prompt. The string
5266 may contain special characters which are decoded as follows:
5267
5268 \a bell (ascii 07)
5269 \d the date in Day Mon Date format
5270 \e escape (ascii 033)
5271 \h the hostname up to the first `.'
5272 \H the hostname
5273 \j the number of active jobs
5274 \l the basename of the shell's tty device name
5275 \n CRLF
5276 \r CR
5277 \s the name of the shell
5278 \t the time in 24-hour hh:mm:ss format
5279 \T the time in 12-hour hh:mm:ss format
5280 \@ the time in 12-hour hh:mm am/pm format
5281 \A the time in 24-hour hh:mm format
5282 \D{fmt} the result of passing FMT to strftime(3)
5283 \u your username
5284 \v the version of bash (e.g., 2.00)
5285 \V the release of bash, version + patchlevel (e.g., 2.00.0)
5286 \w the current working directory
5287 \W the last element of $PWD
5288 \! the history number of this command
5289 \# the command number of this command
5290 \$ a $ or a # if you are root
5291 \nnn character code nnn in octal
5292 \\ a backslash
5293 \[ begin a sequence of non-printing chars
5294 \] end a sequence of non-printing chars
5295 */
5296 #define PROMPT_GROWTH 48
5297 char *
5298 decode_prompt_string (string)
5299 char *string;
5300 {
5301 WORD_LIST *list;
5302 char *result, *t;
5303 struct dstack save_dstack;
5304 int last_exit_value;
5305 #if defined (PROMPT_STRING_DECODE)
5306 int result_size, result_index;
5307 int c, n;
5308 char *temp, octal_string[4];
5309 struct tm *tm;
5310 time_t the_time;
5311 char timebuf[128];
5312 char *timefmt;
5313
5314 result = (char *)xmalloc (result_size = PROMPT_GROWTH);
5315 result[result_index = 0] = 0;
5316 temp = (char *)NULL;
5317
5318 while (c = *string++)
5319 {
5320 if (posixly_correct && c == '!')
5321 {
5322 if (*string == '!')
5323 {
5324 temp = savestring ("!");
5325 goto add_string;
5326 }
5327 else
5328 {
5329 #if !defined (HISTORY)
5330 temp = savestring ("1");
5331 #else /* HISTORY */
5332 temp = itos (history_number ());
5333 #endif /* HISTORY */
5334 string--; /* add_string increments string again. */
5335 goto add_string;
5336 }
5337 }
5338 if (c == '\\')
5339 {
5340 c = *string;
5341
5342 switch (c)
5343 {
5344 case '0':
5345 case '1':
5346 case '2':
5347 case '3':
5348 case '4':
5349 case '5':
5350 case '6':
5351 case '7':
5352 strncpy (octal_string, string, 3);
5353 octal_string[3] = '\0';
5354
5355 n = read_octal (octal_string);
5356 temp = (char *)xmalloc (3);
5357
5358 if (n == CTLESC || n == CTLNUL)
5359 {
5360 temp[0] = CTLESC;
5361 temp[1] = n;
5362 temp[2] = '\0';
5363 }
5364 else if (n == -1)
5365 {
5366 temp[0] = '\\';
5367 temp[1] = '\0';
5368 }
5369 else
5370 {
5371 temp[0] = n;
5372 temp[1] = '\0';
5373 }
5374
5375 for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
5376 string++;
5377
5378 c = 0; /* tested at add_string: */
5379 goto add_string;
5380
5381 case 'd':
5382 case 't':
5383 case 'T':
5384 case '@':
5385 case 'A':
5386 /* Make the current time/date into a string. */
5387 (void) time (&the_time);
5388 tm = localtime (&the_time);
5389
5390 if (c == 'd')
5391 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
5392 else if (c == 't')
5393 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
5394 else if (c == 'T')
5395 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
5396 else if (c == '@')
5397 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
5398 else if (c == 'A')
5399 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
5400
5401 if (n == 0)
5402 timebuf[0] = '\0';
5403 else
5404 timebuf[sizeof(timebuf) - 1] = '\0';
5405
5406 temp = savestring (timebuf);
5407 goto add_string;
5408
5409 case 'D': /* strftime format */
5410 if (string[1] != '{') /* } */
5411 goto not_escape;
5412
5413 (void) time (&the_time);
5414 tm = localtime (&the_time);
5415 string += 2; /* skip { */
5416 timefmt = xmalloc (strlen (string) + 3);
5417 for (t = timefmt; *string && *string != '}'; )
5418 *t++ = *string++;
5419 *t = '\0';
5420 c = *string; /* tested at add_string */
5421 if (timefmt[0] == '\0')
5422 {
5423 timefmt[0] = '%';
5424 timefmt[1] = 'X'; /* locale-specific current time */
5425 timefmt[2] = '\0';
5426 }
5427 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
5428 free (timefmt);
5429
5430 if (n == 0)
5431 timebuf[0] = '\0';
5432 else
5433 timebuf[sizeof(timebuf) - 1] = '\0';
5434
5435 if (promptvars || posixly_correct)
5436 /* Make sure that expand_prompt_string is called with a
5437 second argument of Q_DOUBLE_QUOTES if we use this
5438 function here. */
5439 temp = sh_backslash_quote_for_double_quotes (timebuf);
5440 else
5441 temp = savestring (timebuf);
5442 goto add_string;
5443
5444 case 'n':
5445 temp = (char *)xmalloc (3);
5446 temp[0] = no_line_editing ? '\n' : '\r';
5447 temp[1] = no_line_editing ? '\0' : '\n';
5448 temp[2] = '\0';
5449 goto add_string;
5450
5451 case 's':
5452 temp = base_pathname (shell_name);
5453 temp = savestring (temp);
5454 goto add_string;
5455
5456 case 'v':
5457 case 'V':
5458 temp = (char *)xmalloc (16);
5459 if (c == 'v')
5460 strcpy (temp, dist_version);
5461 else
5462 sprintf (temp, "%s.%d", dist_version, patch_level);
5463 goto add_string;
5464
5465 case 'w':
5466 case 'W':
5467 {
5468 /* Use the value of PWD because it is much more efficient. */
5469 char t_string[PATH_MAX], *t;
5470 int tlen;
5471
5472 temp = get_string_value ("PWD");
5473
5474 if (temp == 0)
5475 {
5476 if (getcwd (t_string, sizeof(t_string)) == 0)
5477 {
5478 t_string[0] = '.';
5479 tlen = 1;
5480 }
5481 else
5482 tlen = strlen (t_string);
5483 }
5484 else
5485 {
5486 tlen = sizeof (t_string) - 1;
5487 strncpy (t_string, temp, tlen);
5488 }
5489 t_string[tlen] = '\0';
5490
5491 #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
5492 #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
5493 /* Abbreviate \W as ~ if $PWD == $HOME */
5494 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
5495 {
5496 if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
5497 {
5498 t = strrchr (t_string, '/');
5499 if (t)
5500 strcpy (t_string, t + 1);
5501 }
5502 }
5503 #undef ROOT_PATH
5504 #undef DOUBLE_SLASH_ROOT
5505 else
5506 /* polite_directory_format is guaranteed to return a string
5507 no longer than PATH_MAX - 1 characters. */
5508 strcpy (t_string, polite_directory_format (t_string));
5509
5510 /* If we're going to be expanding the prompt string later,
5511 quote the directory name. */
5512 if (promptvars || posixly_correct)
5513 /* Make sure that expand_prompt_string is called with a
5514 second argument of Q_DOUBLE_QUOTES if we use this
5515 function here. */
5516 temp = sh_backslash_quote_for_double_quotes (t_string);
5517 else
5518 temp = savestring (t_string);
5519
5520 goto add_string;
5521 }
5522
5523 case 'u':
5524 if (current_user.user_name == 0)
5525 get_current_user_info ();
5526 temp = savestring (current_user.user_name);
5527 goto add_string;
5528
5529 case 'h':
5530 case 'H':
5531 temp = savestring (current_host_name);
5532 if (c == 'h' && (t = (char *)strchr (temp, '.')))
5533 *t = '\0';
5534 goto add_string;
5535
5536 case '#':
5537 temp = itos (current_command_number);
5538 goto add_string;
5539
5540 case '!':
5541 #if !defined (HISTORY)
5542 temp = savestring ("1");
5543 #else /* HISTORY */
5544 temp = itos (history_number ());
5545 #endif /* HISTORY */
5546 goto add_string;
5547
5548 case '$':
5549 t = temp = (char *)xmalloc (3);
5550 if ((promptvars || posixly_correct) && (current_user.euid != 0))
5551 *t++ = '\\';
5552 *t++ = current_user.euid == 0 ? '#' : '$';
5553 *t = '\0';
5554 goto add_string;
5555
5556 case 'j':
5557 temp = itos (count_all_jobs ());
5558 goto add_string;
5559
5560 case 'l':
5561 #if defined (HAVE_TTYNAME)
5562 temp = (char *)ttyname (fileno (stdin));
5563 t = temp ? base_pathname (temp) : "tty";
5564 temp = savestring (t);
5565 #else
5566 temp = savestring ("tty");
5567 #endif /* !HAVE_TTYNAME */
5568 goto add_string;
5569
5570 #if defined (READLINE)
5571 case '[':
5572 case ']':
5573 if (no_line_editing)
5574 {
5575 string++;
5576 break;
5577 }
5578 temp = (char *)xmalloc (3);
5579 temp[0] = '\001';
5580 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
5581 temp[2] = '\0';
5582 goto add_string;
5583 #endif /* READLINE */
5584
5585 case '\\':
5586 case 'a':
5587 case 'e':
5588 case 'r':
5589 temp = (char *)xmalloc (2);
5590 if (c == 'a')
5591 temp[0] = '\07';
5592 else if (c == 'e')
5593 temp[0] = '\033';
5594 else if (c == 'r')
5595 temp[0] = '\r';
5596 else /* (c == '\\') */
5597 temp[0] = c;
5598 temp[1] = '\0';
5599 goto add_string;
5600
5601 default:
5602 not_escape:
5603 temp = (char *)xmalloc (3);
5604 temp[0] = '\\';
5605 temp[1] = c;
5606 temp[2] = '\0';
5607
5608 add_string:
5609 if (c)
5610 string++;
5611 result =
5612 sub_append_string (temp, result, &result_index, &result_size);
5613 temp = (char *)NULL; /* Freed in sub_append_string (). */
5614 result[result_index] = '\0';
5615 break;
5616 }
5617 }
5618 else
5619 {
5620 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
5621 result[result_index++] = c;
5622 result[result_index] = '\0';
5623 }
5624 }
5625 #else /* !PROMPT_STRING_DECODE */
5626 result = savestring (string);
5627 #endif /* !PROMPT_STRING_DECODE */
5628
5629 /* Save the delimiter stack and point `dstack' to temp space so any
5630 command substitutions in the prompt string won't result in screwing
5631 up the parser's quoting state. */
5632 save_dstack = dstack;
5633 dstack = temp_dstack;
5634 dstack.delimiter_depth = 0;
5635
5636 /* Perform variable and parameter expansion and command substitution on
5637 the prompt string. */
5638 if (promptvars || posixly_correct)
5639 {
5640 last_exit_value = last_command_exit_value;
5641 list = expand_prompt_string (result, Q_DOUBLE_QUOTES);
5642 free (result);
5643 result = string_list (list);
5644 dispose_words (list);
5645 last_command_exit_value = last_exit_value;
5646 }
5647 else
5648 {
5649 t = dequote_string (result);
5650 free (result);
5651 result = t;
5652 }
5653
5654 dstack = save_dstack;
5655
5656 return (result);
5657 }
5658
5659 /************************************************
5660 * *
5661 * ERROR HANDLING *
5662 * *
5663 ************************************************/
5664
5665 /* Report a syntax error, and restart the parser. Call here for fatal
5666 errors. */
5667 int
5668 yyerror (msg)
5669 const char *msg;
5670 {
5671 report_syntax_error ((char *)NULL);
5672 reset_parser ();
5673 return (0);
5674 }
5675
5676 static char *
5677 error_token_from_token (token)
5678 int token;
5679 {
5680 char *t;
5681
5682 if (t = find_token_in_alist (token, word_token_alist, 0))
5683 return t;
5684
5685 if (t = find_token_in_alist (token, other_token_alist, 0))
5686 return t;
5687
5688 t = (char *)NULL;
5689 /* This stuff is dicy and needs closer inspection */
5690 switch (current_token)
5691 {
5692 case WORD:
5693 case ASSIGNMENT_WORD:
5694 if (yylval.word)
5695 t = savestring (yylval.word->word);
5696 break;
5697 case NUMBER:
5698 t = itos (yylval.number);
5699 break;
5700 case ARITH_CMD:
5701 if (yylval.word_list)
5702 t = string_list (yylval.word_list);
5703 break;
5704 case ARITH_FOR_EXPRS:
5705 if (yylval.word_list)
5706 t = string_list_internal (yylval.word_list, " ; ");
5707 break;
5708 case COND_CMD:
5709 t = (char *)NULL; /* punt */
5710 break;
5711 }
5712
5713 return t;
5714 }
5715
5716 static char *
5717 error_token_from_text ()
5718 {
5719 char *msg, *t;
5720 int token_end, i;
5721
5722 t = shell_input_line;
5723 i = shell_input_line_index;
5724 token_end = 0;
5725 msg = (char *)NULL;
5726
5727 if (i && t[i] == '\0')
5728 i--;
5729
5730 while (i && (whitespace (t[i]) || t[i] == '\n'))
5731 i--;
5732
5733 if (i)
5734 token_end = i + 1;
5735
5736 while (i && (member (t[i], " \n\t;|&") == 0))
5737 i--;
5738
5739 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
5740 i++;
5741
5742 /* Return our idea of the offending token. */
5743 if (token_end || (i == 0 && token_end == 0))
5744 {
5745 if (token_end)
5746 msg = substring (t, i, token_end);
5747 else /* one-character token */
5748 {
5749 msg = (char *)xmalloc (2);
5750 msg[0] = t[i];
5751 msg[1] = '\0';
5752 }
5753 }
5754
5755 return (msg);
5756 }
5757
5758 static void
5759 print_offending_line ()
5760 {
5761 char *msg;
5762 int token_end;
5763
5764 msg = savestring (shell_input_line);
5765 token_end = strlen (msg);
5766 while (token_end && msg[token_end - 1] == '\n')
5767 msg[--token_end] = '\0';
5768
5769 parser_error (line_number, "`%s'", msg);
5770 free (msg);
5771 }
5772
5773 /* Report a syntax error with line numbers, etc.
5774 Call here for recoverable errors. If you have a message to print,
5775 then place it in MESSAGE, otherwise pass NULL and this will figure
5776 out an appropriate message for you. */
5777 static void
5778 report_syntax_error (message)
5779 char *message;
5780 {
5781 char *msg;
5782
5783 if (message)
5784 {
5785 parser_error (line_number, "%s", message);
5786 if (interactive && EOF_Reached)
5787 EOF_Reached = 0;
5788 last_command_exit_value = EX_USAGE;
5789 return;
5790 }
5791
5792 /* If the line of input we're reading is not null, try to find the
5793 objectionable token. First, try to figure out what token the
5794 parser's complaining about by looking at current_token. */
5795 if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
5796 {
5797 parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
5798 free (msg);
5799
5800 if (interactive == 0)
5801 print_offending_line ();
5802
5803 last_command_exit_value = EX_USAGE;
5804 return;
5805 }
5806
5807 /* If looking at the current token doesn't prove fruitful, try to find the
5808 offending token by analyzing the text of the input line near the current
5809 input line index and report what we find. */
5810 if (shell_input_line && *shell_input_line)
5811 {
5812 msg = error_token_from_text ();
5813 if (msg)
5814 {
5815 parser_error (line_number, _("syntax error near `%s'"), msg);
5816 free (msg);
5817 }
5818
5819 /* If not interactive, print the line containing the error. */
5820 if (interactive == 0)
5821 print_offending_line ();
5822 }
5823 else
5824 {
5825 msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
5826 parser_error (line_number, "%s", msg);
5827 /* When the shell is interactive, this file uses EOF_Reached
5828 only for error reporting. Other mechanisms are used to
5829 decide whether or not to exit. */
5830 if (interactive && EOF_Reached)
5831 EOF_Reached = 0;
5832 }
5833
5834 last_command_exit_value = EX_USAGE;
5835 }
5836
5837 /* ??? Needed function. ??? We have to be able to discard the constructs
5838 created during parsing. In the case of error, we want to return
5839 allocated objects to the memory pool. In the case of no error, we want
5840 to throw away the information about where the allocated objects live.
5841 (dispose_command () will actually free the command.) */
5842 static void
5843 discard_parser_constructs (error_p)
5844 int error_p;
5845 {
5846 }
5847
5848 /************************************************
5849 * *
5850 * EOF HANDLING *
5851 * *
5852 ************************************************/
5853
5854 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
5855
5856 /* A flag denoting whether or not ignoreeof is set. */
5857 int ignoreeof = 0;
5858
5859 /* The number of times that we have encountered an EOF character without
5860 another character intervening. When this gets above the limit, the
5861 shell terminates. */
5862 int eof_encountered = 0;
5863
5864 /* The limit for eof_encountered. */
5865 int eof_encountered_limit = 10;
5866
5867 /* If we have EOF as the only input unit, this user wants to leave
5868 the shell. If the shell is not interactive, then just leave.
5869 Otherwise, if ignoreeof is set, and we haven't done this the
5870 required number of times in a row, print a message. */
5871 static void
5872 handle_eof_input_unit ()
5873 {
5874 if (interactive)
5875 {
5876 /* shell.c may use this to decide whether or not to write out the
5877 history, among other things. We use it only for error reporting
5878 in this file. */
5879 if (EOF_Reached)
5880 EOF_Reached = 0;
5881
5882 /* If the user wants to "ignore" eof, then let her do so, kind of. */
5883 if (ignoreeof)
5884 {
5885 if (eof_encountered < eof_encountered_limit)
5886 {
5887 fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
5888 login_shell ? "logout" : "exit");
5889 eof_encountered++;
5890 /* Reset the parsing state. */
5891 last_read_token = current_token = '\n';
5892 /* Reset the prompt string to be $PS1. */
5893 prompt_string_pointer = (char **)NULL;
5894 prompt_again ();
5895 return;
5896 }
5897 }
5898
5899 /* In this case EOF should exit the shell. Do it now. */
5900 reset_parser ();
5901 exit_builtin ((WORD_LIST *)NULL);
5902 }
5903 else
5904 {
5905 /* We don't write history files, etc., for non-interactive shells. */
5906 EOF_Reached = 1;
5907 }
5908 }
5909
5910 /************************************************
5911 * *
5912 * STRING PARSING FUNCTIONS *
5913 * *
5914 ************************************************/
5915
5916 /* It's very important that these two functions treat the characters
5917 between ( and ) identically. */
5918
5919 static WORD_LIST parse_string_error;
5920
5921 /* Take a string and run it through the shell parser, returning the
5922 resultant word list. Used by compound array assignment. */
5923 WORD_LIST *
5924 parse_string_to_word_list (s, flags, whom)
5925 char *s;
5926 int flags;
5927 const char *whom;
5928 {
5929 WORD_LIST *wl;
5930 int tok, orig_current_token, orig_line_number, orig_input_terminator;
5931 int orig_line_count;
5932 int old_echo_input, old_expand_aliases;
5933 #if defined (HISTORY)
5934 int old_remember_on_history, old_history_expansion_inhibited;
5935 #endif
5936
5937 #if defined (HISTORY)
5938 old_remember_on_history = remember_on_history;
5939 # if defined (BANG_HISTORY)
5940 old_history_expansion_inhibited = history_expansion_inhibited;
5941 # endif
5942 bash_history_disable ();
5943 #endif
5944
5945 orig_line_number = line_number;
5946 orig_line_count = current_command_line_count;
5947 orig_input_terminator = shell_input_line_terminator;
5948 old_echo_input = echo_input_at_read;
5949 old_expand_aliases = expand_aliases;
5950
5951 push_stream (1);
5952 last_read_token = WORD; /* WORD to allow reserved words here */
5953 current_command_line_count = 0;
5954 echo_input_at_read = expand_aliases = 0;
5955
5956 with_input_from_string (s, whom);
5957 wl = (WORD_LIST *)NULL;
5958
5959 if (flags & 1)
5960 parser_state |= PST_COMPASSIGN;
5961
5962 while ((tok = read_token (READ)) != yacc_EOF)
5963 {
5964 if (tok == '\n' && *bash_input.location.string == '\0')
5965 break;
5966 if (tok == '\n') /* Allow newlines in compound assignments */
5967 continue;
5968 if (tok != WORD && tok != ASSIGNMENT_WORD)
5969 {
5970 line_number = orig_line_number + line_number - 1;
5971 orig_current_token = current_token;
5972 current_token = tok;
5973 yyerror (NULL); /* does the right thing */
5974 current_token = orig_current_token;
5975 if (wl)
5976 dispose_words (wl);
5977 wl = &parse_string_error;
5978 break;
5979 }
5980 wl = make_word_list (yylval.word, wl);
5981 }
5982
5983 last_read_token = '\n';
5984 pop_stream ();
5985
5986 #if defined (HISTORY)
5987 remember_on_history = old_remember_on_history;
5988 # if defined (BANG_HISTORY)
5989 history_expansion_inhibited = old_history_expansion_inhibited;
5990 # endif /* BANG_HISTORY */
5991 #endif /* HISTORY */
5992
5993 echo_input_at_read = old_echo_input;
5994 expand_aliases = old_expand_aliases;
5995
5996 current_command_line_count = orig_line_count;
5997 shell_input_line_terminator = orig_input_terminator;
5998
5999 if (flags & 1)
6000 parser_state &= ~PST_COMPASSIGN;
6001
6002 if (wl == &parse_string_error)
6003 {
6004 last_command_exit_value = EXECUTION_FAILURE;
6005 if (interactive_shell == 0 && posixly_correct)
6006 jump_to_top_level (FORCE_EOF);
6007 else
6008 jump_to_top_level (DISCARD);
6009 }
6010
6011 return (REVERSE_LIST (wl, WORD_LIST *));
6012 }
6013
6014 static char *
6015 parse_compound_assignment (retlenp)
6016 int *retlenp;
6017 {
6018 WORD_LIST *wl, *rl;
6019 int tok, orig_line_number, orig_token_size;
6020 char *saved_token, *ret;
6021
6022 saved_token = token;
6023 orig_token_size = token_buffer_size;
6024 orig_line_number = line_number;
6025
6026 last_read_token = WORD; /* WORD to allow reserved words here */
6027
6028 token = (char *)NULL;
6029 token_buffer_size = 0;
6030
6031 wl = (WORD_LIST *)NULL; /* ( */
6032 parser_state |= PST_COMPASSIGN;
6033
6034 while ((tok = read_token (READ)) != ')')
6035 {
6036 if (tok == '\n') /* Allow newlines in compound assignments */
6037 {
6038 if (SHOULD_PROMPT ())
6039 prompt_again ();
6040 continue;
6041 }
6042 if (tok != WORD && tok != ASSIGNMENT_WORD)
6043 {
6044 current_token = tok; /* for error reporting */
6045 if (tok == yacc_EOF) /* ( */
6046 parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
6047 else
6048 yyerror(NULL); /* does the right thing */
6049 if (wl)
6050 dispose_words (wl);
6051 wl = &parse_string_error;
6052 break;
6053 }
6054 wl = make_word_list (yylval.word, wl);
6055 }
6056
6057 FREE (token);
6058 token = saved_token;
6059 token_buffer_size = orig_token_size;
6060
6061 parser_state &= ~PST_COMPASSIGN;
6062
6063 if (wl == &parse_string_error)
6064 {
6065 last_command_exit_value = EXECUTION_FAILURE;
6066 last_read_token = '\n'; /* XXX */
6067 if (interactive_shell == 0 && posixly_correct)
6068 jump_to_top_level (FORCE_EOF);
6069 else
6070 jump_to_top_level (DISCARD);
6071 }
6072
6073 last_read_token = WORD;
6074 if (wl)
6075 {
6076 rl = REVERSE_LIST (wl, WORD_LIST *);
6077 ret = string_list (rl);
6078 dispose_words (rl);
6079 }
6080 else
6081 ret = (char *)NULL;
6082
6083 if (retlenp)
6084 *retlenp = (ret && *ret) ? strlen (ret) : 0;
6085 return ret;
6086 }
6087
6088 /************************************************
6089 * *
6090 * SAVING AND RESTORING PARTIAL PARSE STATE *
6091 * *
6092 ************************************************/
6093
6094 sh_parser_state_t *
6095 save_parser_state (ps)
6096 sh_parser_state_t *ps;
6097 {
6098 #if defined (ARRAY_VARS)
6099 SHELL_VAR *v;
6100 #endif
6101
6102 if (ps == 0)
6103 ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
6104 if (ps == 0)
6105 return ((sh_parser_state_t *)NULL);
6106
6107 ps->parser_state = parser_state;
6108 ps->token_state = save_token_state ();
6109
6110 ps->input_line_terminator = shell_input_line_terminator;
6111 ps->eof_encountered = eof_encountered;
6112
6113 ps->current_command_line_count = current_command_line_count;
6114
6115 #if defined (HISTORY)
6116 ps->remember_on_history = remember_on_history;
6117 # if defined (BANG_HISTORY)
6118 ps->history_expansion_inhibited = history_expansion_inhibited;
6119 # endif
6120 #endif
6121
6122 ps->last_command_exit_value = last_command_exit_value;
6123 #if defined (ARRAY_VARS)
6124 v = find_variable ("PIPESTATUS");
6125 if (v && array_p (v) && array_cell (v))
6126 ps->pipestatus = array_copy (array_cell (v));
6127 else
6128 ps->pipestatus = (ARRAY *)NULL;
6129 #endif
6130
6131 ps->last_shell_builtin = last_shell_builtin;
6132 ps->this_shell_builtin = this_shell_builtin;
6133
6134 ps->expand_aliases = expand_aliases;
6135 ps->echo_input_at_read = echo_input_at_read;
6136
6137 return (ps);
6138 }
6139
6140 void
6141 restore_parser_state (ps)
6142 sh_parser_state_t *ps;
6143 {
6144 #if defined (ARRAY_VARS)
6145 SHELL_VAR *v;
6146 #endif
6147
6148 if (ps == 0)
6149 return;
6150
6151 parser_state = ps->parser_state;
6152 if (ps->token_state)
6153 {
6154 restore_token_state (ps->token_state);
6155 free (ps->token_state);
6156 }
6157
6158 shell_input_line_terminator = ps->input_line_terminator;
6159 eof_encountered = ps->eof_encountered;
6160
6161 current_command_line_count = ps->current_command_line_count;
6162
6163 #if defined (HISTORY)
6164 remember_on_history = ps->remember_on_history;
6165 # if defined (BANG_HISTORY)
6166 history_expansion_inhibited = ps->history_expansion_inhibited;
6167 # endif
6168 #endif
6169
6170 last_command_exit_value = ps->last_command_exit_value;
6171 #if defined (ARRAY_VARS)
6172 v = find_variable ("PIPESTATUS");
6173 if (v && array_p (v) && array_cell (v))
6174 {
6175 array_dispose (array_cell (v));
6176 var_setarray (v, ps->pipestatus);
6177 }
6178 #endif
6179
6180 last_shell_builtin = ps->last_shell_builtin;
6181 this_shell_builtin = ps->this_shell_builtin;
6182
6183 expand_aliases = ps->expand_aliases;
6184 echo_input_at_read = ps->echo_input_at_read;
6185 }
6186
6187 /************************************************
6188 * *
6189 * MULTIBYTE CHARACTER HANDLING *
6190 * *
6191 ************************************************/
6192
6193 #if defined (HANDLE_MULTIBYTE)
6194 static void
6195 set_line_mbstate ()
6196 {
6197 int i, previ, len, c;
6198 mbstate_t mbs, prevs;
6199 size_t mbclen;
6200
6201 if (shell_input_line == NULL)
6202 return;
6203 len = strlen (shell_input_line); /* XXX - shell_input_line_len ? */
6204 FREE (shell_input_line_property);
6205 shell_input_line_property = (char *)xmalloc (len + 1);
6206
6207 memset (&prevs, '\0', sizeof (mbstate_t));
6208 for (i = previ = 0; i < len; i++)
6209 {
6210 mbs = prevs;
6211
6212 c = shell_input_line[i];
6213 if (c == EOF)
6214 {
6215 int j;
6216 for (j = i; j < len; j++)
6217 shell_input_line_property[j] = 1;
6218 break;
6219 }
6220
6221 mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
6222 if (mbclen == 1 || mbclen == (size_t)-1)
6223 {
6224 mbclen = 1;
6225 previ = i + 1;
6226 }
6227 else if (mbclen == (size_t)-2)
6228 mbclen = 0;
6229 else if (mbclen > 1)
6230 {
6231 mbclen = 0;
6232 previ = i + 1;
6233 prevs = mbs;
6234 }
6235 else
6236 {
6237 /* XXX - what to do if mbrlen returns 0? (null wide character) */
6238 int j;
6239 for (j = i; j < len; j++)
6240 shell_input_line_property[j] = 1;
6241 break;
6242 }
6243
6244 shell_input_line_property[i] = mbclen;
6245 }
6246 }
6247 #endif /* HANDLE_MULTIBYTE */