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