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