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