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