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