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