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