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