source: vendor/bash/3.1-p17/y.tab.c@ 3274

Last change on this file since 3274 was 3231, checked in by bird, 18 years ago

eol style.

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