]> git.ipfire.org Git - thirdparty/bash.git/blame - parse.y
Imported from ../bash-2.0.tar.gz.
[thirdparty/bash.git] / parse.y
CommitLineData
726f6388
JA
1/* Yacc grammar for bash. */
2
3/* Copyright (C) 1989 Free Software Foundation, Inc.
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 1, or (at your option) any later
10 version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file LICENSE. If not, write to the Free Software
19 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21%{
ccc6cda3
JA
22#include "config.h"
23
726f6388 24#include "bashtypes.h"
726f6388 25#include "bashansi.h"
ccc6cda3
JA
26
27#if defined (HAVE_UNISTD_H)
28# include <unistd.h>
29#endif
30
31#if defined (HAVE_LOCALE_H)
32# include <locale.h>
33#endif
34
35#include <stdio.h>
36#include <signal.h>
37
38#include "memalloc.h"
39
726f6388 40#include "shell.h"
ccc6cda3 41#include "trap.h"
726f6388 42#include "flags.h"
ccc6cda3
JA
43#include "parser.h"
44#include "mailcheck.h"
45#include "builtins/common.h"
46#include "builtins/builtext.h"
726f6388
JA
47
48#if defined (READLINE)
ccc6cda3 49# include "bashline.h"
726f6388
JA
50# include <readline/readline.h>
51#endif /* READLINE */
52
53#if defined (HISTORY)
54# include "bashhist.h"
55# include <readline/history.h>
56#endif /* HISTORY */
57
58#if defined (JOB_CONTROL)
59# include "jobs.h"
60#endif /* JOB_CONTROL */
61
62#if defined (ALIAS)
63# include "alias.h"
64#endif /* ALIAS */
65
66#if defined (PROMPT_STRING_DECODE)
67#include <sys/param.h>
68#include <time.h>
69#include "maxpath.h"
70#endif /* PROMPT_STRING_DECODE */
71
ccc6cda3
JA
72#define RE_READ_TOKEN -99
73#define NO_EXPANSION -100
74
75#define YYDEBUG 0
76
726f6388 77extern int eof_encountered;
ccc6cda3 78extern int no_line_editing, running_under_emacs;
726f6388
JA
79extern int current_command_number;
80extern int interactive, interactive_shell, login_shell;
ccc6cda3 81extern int sourcelevel;
726f6388
JA
82extern int posixly_correct;
83extern int last_command_exit_value;
84extern int interrupt_immediately;
85extern char *shell_name, *current_host_name;
ccc6cda3
JA
86extern char *dist_version;
87extern int patch_level;
88extern int dump_translatable_strings;
726f6388 89extern Function *last_shell_builtin, *this_shell_builtin;
726f6388
JA
90#if defined (BUFFERED_INPUT)
91extern int bash_input_fd_changed;
92#endif
93
94/* **************************************************************** */
95/* */
96/* "Forward" declarations */
97/* */
98/* **************************************************************** */
99
ccc6cda3
JA
100static char *ansiexpand ();
101static char *localeexpand ();
726f6388
JA
102static int reserved_word_acceptable ();
103static int read_token ();
ccc6cda3
JA
104static int yylex ();
105static int read_token_word ();
106static void discard_parser_constructs ();
726f6388
JA
107
108static void report_syntax_error ();
109static void handle_eof_input_unit ();
110static void prompt_again ();
111static void reset_readline_prompt ();
112static void print_prompt ();
113
ccc6cda3
JA
114/* Default prompt strings */
115char *primary_prompt = PPROMPT;
116char *secondary_prompt = SPROMPT;
117
726f6388
JA
118/* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
119char *ps1_prompt, *ps2_prompt;
120
121/* Handle on the current prompt string. Indirectly points through
122 ps1_ or ps2_prompt. */
123char **prompt_string_pointer = (char **)NULL;
124char *current_prompt_string;
125
ccc6cda3
JA
126/* Non-zero means we expand aliases in commands. */
127int expand_aliases = 0;
128
129/* If non-zero, the decoded prompt string undergoes parameter and
130 variable substitution, command substitution, arithmetic substitution,
131 string expansion, process substitution, and quote removal in
132 decode_prompt_string. */
133int promptvars = 1;
134
726f6388
JA
135/* The decoded prompt string. Used if READLINE is not defined or if
136 editing is turned off. Analogous to current_readline_prompt. */
137static char *current_decoded_prompt;
138
139/* The number of lines read from input while creating the current command. */
ccc6cda3 140int current_command_line_count;
726f6388
JA
141
142/* Variables to manage the task of reading here documents, because we need to
143 defer the reading until after a complete command has been collected. */
144static REDIRECT *redir_stack[10];
ccc6cda3 145int need_here_doc;
726f6388
JA
146
147/* Where shell input comes from. History expansion is performed on each
148 line when the shell is interactive. */
149static char *shell_input_line = (char *)NULL;
ccc6cda3
JA
150static int shell_input_line_index;
151static int shell_input_line_size; /* Amount allocated for shell_input_line. */
152static int shell_input_line_len; /* strlen (shell_input_line) */
726f6388
JA
153
154/* Either zero or EOF. */
ccc6cda3
JA
155static int shell_input_line_terminator;
156
157/* The line number in a script on which a function definition starts. */
158static int function_dstart;
159
160/* The line number in a script on which a function body starts. */
161static int function_bstart;
726f6388
JA
162
163static REDIRECTEE redir;
164%}
165
166%union {
167 WORD_DESC *word; /* the word that we read. */
168 int number; /* the number that we read. */
169 WORD_LIST *word_list;
170 COMMAND *command;
171 REDIRECT *redirect;
172 ELEMENT element;
173 PATTERN_LIST *pattern;
174}
175
176/* Reserved words. Members of the first group are only recognized
177 in the case that they are preceded by a list_terminator. Members
178 of the second group are recognized only under special circumstances. */
179%token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION
ccc6cda3 180%token IN BANG TIME TIMEOPT
726f6388
JA
181
182/* More general tokens. yylex () knows how to make these. */
183%token <word> WORD ASSIGNMENT_WORD
184%token <number> NUMBER
185%token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND
186%token GREATER_AND SEMI_SEMI LESS_LESS_MINUS AND_GREATER LESS_GREATER
187%token GREATER_BAR
188
189/* The types that the various syntactical units return. */
190
ccc6cda3
JA
191%type <command> inputunit command pipeline pipeline_command
192%type <command> list list0 list1 compound_list simple_list simple_list1
193%type <command> simple_command shell_command
194%type <command> for_command select_command case_command group_command
195%type <command> function_def if_command elif_clause subshell
196%type <redirect> redirection redirection_list
726f6388 197%type <element> simple_command_element
ccc6cda3
JA
198%type <word_list> word_list pattern
199%type <pattern> pattern_list case_clause_sequence case_clause
200%type <number> timespec
726f6388
JA
201
202%start inputunit
203
204%left '&' ';' '\n' yacc_EOF
205%left AND_AND OR_OR
206%right '|'
207%%
208
209inputunit: simple_list '\n'
210 {
211 /* Case of regular command. Discard the error
212 safety net,and return the command just parsed. */
213 global_command = $1;
214 eof_encountered = 0;
215 discard_parser_constructs (0);
216 YYACCEPT;
217 }
218 | '\n'
219 {
220 /* Case of regular command, but not a very
221 interesting one. Return a NULL command. */
222 global_command = (COMMAND *)NULL;
223 YYACCEPT;
224 }
ccc6cda3 225 | error '\n'
726f6388
JA
226 {
227 /* Error during parsing. Return NULL command. */
228 global_command = (COMMAND *)NULL;
229 eof_encountered = 0;
230 discard_parser_constructs (1);
231 if (interactive)
232 {
233 YYACCEPT;
234 }
235 else
236 {
237 YYABORT;
238 }
239 }
240 | yacc_EOF
241 {
ccc6cda3 242 /* Case of EOF seen by itself. Do ignoreeof or
726f6388
JA
243 not. */
244 global_command = (COMMAND *)NULL;
245 handle_eof_input_unit ();
246 YYACCEPT;
247 }
248 ;
249
ccc6cda3
JA
250word_list: WORD
251 { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
252 | word_list WORD
726f6388
JA
253 { $$ = make_word_list ($2, $1); }
254 ;
255
256redirection: '>' WORD
257 {
258 redir.filename = $2;
259 $$ = make_redirection (1, r_output_direction, redir);
260 }
261 | '<' WORD
262 {
263 redir.filename = $2;
264 $$ = make_redirection (0, r_input_direction, redir);
265 }
266 | NUMBER '>' WORD
267 {
268 redir.filename = $3;
269 $$ = make_redirection ($1, r_output_direction, redir);
270 }
271 | NUMBER '<' WORD
272 {
273 redir.filename = $3;
274 $$ = make_redirection ($1, r_input_direction, redir);
275 }
276 | GREATER_GREATER WORD
277 {
278 redir.filename = $2;
279 $$ = make_redirection (1, r_appending_to, redir);
280 }
281 | NUMBER GREATER_GREATER WORD
282 {
283 redir.filename = $3;
284 $$ = make_redirection ($1, r_appending_to, redir);
285 }
286 | LESS_LESS WORD
287 {
288 redir.filename = $2;
289 $$ = make_redirection (0, r_reading_until, redir);
290 redir_stack[need_here_doc++] = $$;
291 }
292 | NUMBER LESS_LESS WORD
293 {
294 redir.filename = $3;
295 $$ = make_redirection ($1, r_reading_until, redir);
296 redir_stack[need_here_doc++] = $$;
297 }
298 | LESS_AND NUMBER
299 {
300 redir.dest = $2;
301 $$ = make_redirection (0, r_duplicating_input, redir);
302 }
303 | NUMBER LESS_AND NUMBER
304 {
305 redir.dest = $3;
306 $$ = make_redirection ($1, r_duplicating_input, redir);
307 }
308 | GREATER_AND NUMBER
309 {
310 redir.dest = $2;
311 $$ = make_redirection (1, r_duplicating_output, redir);
312 }
313 | NUMBER GREATER_AND NUMBER
314 {
315 redir.dest = $3;
316 $$ = make_redirection ($1, r_duplicating_output, redir);
317 }
318 | LESS_AND WORD
319 {
320 redir.filename = $2;
321 $$ = make_redirection (0, r_duplicating_input_word, redir);
322 }
323 | NUMBER LESS_AND WORD
324 {
325 redir.filename = $3;
326 $$ = make_redirection ($1, r_duplicating_input_word, redir);
327 }
328 | GREATER_AND WORD
329 {
330 redir.filename = $2;
331 $$ = make_redirection (1, r_duplicating_output_word, redir);
332 }
333 | NUMBER GREATER_AND WORD
334 {
335 redir.filename = $3;
336 $$ = make_redirection ($1, r_duplicating_output_word, redir);
337 }
338 | LESS_LESS_MINUS WORD
339 {
340 redir.filename = $2;
341 $$ = make_redirection
342 (0, r_deblank_reading_until, redir);
343 redir_stack[need_here_doc++] = $$;
344 }
345 | NUMBER LESS_LESS_MINUS WORD
346 {
347 redir.filename = $3;
348 $$ = make_redirection
349 ($1, r_deblank_reading_until, redir);
350 redir_stack[need_here_doc++] = $$;
351 }
352 | GREATER_AND '-'
353 {
354 redir.dest = 0L;
355 $$ = make_redirection (1, r_close_this, redir);
356 }
357 | NUMBER GREATER_AND '-'
358 {
359 redir.dest = 0L;
360 $$ = make_redirection ($1, r_close_this, redir);
361 }
362 | LESS_AND '-'
363 {
364 redir.dest = 0L;
365 $$ = make_redirection (0, r_close_this, redir);
366 }
367 | NUMBER LESS_AND '-'
368 {
369 redir.dest = 0L;
370 $$ = make_redirection ($1, r_close_this, redir);
371 }
372 | AND_GREATER WORD
373 {
374 redir.filename = $2;
375 $$ = make_redirection (1, r_err_and_out, redir);
376 }
377 | NUMBER LESS_GREATER WORD
378 {
379 redir.filename = $3;
380 $$ = make_redirection ($1, r_input_output, redir);
381 }
382 | LESS_GREATER WORD
383 {
726f6388 384 redir.filename = $2;
ccc6cda3
JA
385 $$ = make_redirection (0, r_input_output, redir);
386 }
726f6388
JA
387 | GREATER_BAR WORD
388 {
389 redir.filename = $2;
390 $$ = make_redirection (1, r_output_force, redir);
391 }
392 | NUMBER GREATER_BAR WORD
393 {
394 redir.filename = $3;
395 $$ = make_redirection ($1, r_output_force, redir);
396 }
397 ;
398
399simple_command_element: WORD
400 { $$.word = $1; $$.redirect = 0; }
401 | ASSIGNMENT_WORD
402 { $$.word = $1; $$.redirect = 0; }
403 | redirection
404 { $$.redirect = $1; $$.word = 0; }
405 ;
406
ccc6cda3 407redirection_list: redirection
726f6388
JA
408 {
409 $$ = $1;
410 }
ccc6cda3
JA
411 | redirection_list redirection
412 {
413 register REDIRECT *t;
726f6388 414
ccc6cda3
JA
415 for (t = $1; t->next; t = t->next)
416 ;
417 t->next = $2;
726f6388
JA
418 $$ = $1;
419 }
420 ;
421
422simple_command: simple_command_element
423 { $$ = make_simple_command ($1, (COMMAND *)NULL); }
424 | simple_command simple_command_element
425 { $$ = make_simple_command ($2, $1); }
426 ;
427
428command: simple_command
429 { $$ = clean_simple_command ($1); }
430 | shell_command
431 { $$ = $1; }
ccc6cda3 432 | shell_command redirection_list
726f6388 433 {
ccc6cda3
JA
434 COMMAND *tc;
435
436 tc = $1;
437 /* According to Posix.2 3.9.5, redirections
438 specified after the body of a function should
439 be attached to the function and performed when
440 the function is executed, not as part of the
441 function definition command. */
442 if (tc->type == cm_function_def)
443 {
444 tc = tc->value.Function_def->command;
445 if (tc->type == cm_group)
446 tc = tc->value.Group->command;
447 }
448 if (tc->redirects)
726f6388
JA
449 {
450 register REDIRECT *t;
ccc6cda3 451 for (t = tc->redirects; t->next; t = t->next)
726f6388
JA
452 ;
453 t->next = $2;
454 }
455 else
ccc6cda3 456 tc->redirects = $2;
726f6388
JA
457 $$ = $1;
458 }
459 ;
460
ccc6cda3
JA
461shell_command: for_command
462 { $$ = $1; }
463 | case_command
464 { $$ = $1; }
465 | WHILE compound_list DO compound_list DONE
726f6388 466 { $$ = make_while_command ($2, $4); }
ccc6cda3 467 | UNTIL compound_list DO compound_list DONE
726f6388
JA
468 { $$ = make_until_command ($2, $4); }
469 | select_command
470 { $$ = $1; }
471 | if_command
472 { $$ = $1; }
473 | subshell
474 { $$ = $1; }
475 | group_command
476 { $$ = $1; }
477 | function_def
478 { $$ = $1; }
479 ;
480
ccc6cda3
JA
481for_command: FOR WORD newline_list DO list DONE
482 { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5); }
483 | FOR WORD newline_list '{' list '}'
484 { $$ = make_for_command ($2, add_string_to_list ("$@", (WORD_LIST *)NULL), $5); }
485 | FOR WORD ';' newline_list DO list DONE
486 { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6); }
487 | FOR WORD ';' newline_list '{' list '}'
488 { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6); }
489 | FOR WORD newline_list IN word_list list_terminator newline_list DO list DONE
490 { $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9); }
491 | FOR WORD newline_list IN word_list list_terminator newline_list '{' list '}'
492 { $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9); }
493 ;
494
495select_command: SELECT WORD newline_list DO list DONE
726f6388 496 {
726f6388 497 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5);
726f6388 498 }
ccc6cda3 499 | SELECT WORD newline_list '{' list '}'
726f6388 500 {
726f6388 501 $$ = make_select_command ($2, add_string_to_list ("$@", (WORD_LIST *)NULL), $5);
726f6388 502 }
ccc6cda3 503 | SELECT WORD ';' newline_list DO list DONE
726f6388 504 {
726f6388 505 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6);
726f6388 506 }
ccc6cda3 507 | SELECT WORD ';' newline_list '{' list '}'
726f6388 508 {
726f6388 509 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6);
726f6388 510 }
ccc6cda3 511 | SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE
726f6388 512 {
726f6388 513 $$ = make_select_command ($2, (WORD_LIST *)reverse_list ($5), $9);
726f6388 514 }
ccc6cda3 515 | SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}'
726f6388 516 {
726f6388 517 $$ = make_select_command ($2, (WORD_LIST *)reverse_list ($5), $9);
726f6388
JA
518 }
519 ;
520
ccc6cda3
JA
521case_command: CASE WORD newline_list IN newline_list ESAC
522 { $$ = make_case_command ($2, (PATTERN_LIST *)NULL); }
523 | CASE WORD newline_list IN case_clause_sequence newline_list ESAC
524 { $$ = make_case_command ($2, $5); }
525 | CASE WORD newline_list IN case_clause ESAC
526 { $$ = make_case_command ($2, $5); }
527 ;
726f6388 528
ccc6cda3
JA
529function_def: WORD '(' ')' newline_list group_command
530 { $$ = make_function_def ($1, $5, function_dstart, function_bstart); }
726f6388 531
726f6388 532
ccc6cda3
JA
533 | FUNCTION WORD '(' ')' newline_list group_command
534 { $$ = make_function_def ($2, $6, function_dstart, function_bstart); }
726f6388 535
ccc6cda3
JA
536 | FUNCTION WORD newline_list group_command
537 { $$ = make_function_def ($2, $4, function_dstart, function_bstart); }
726f6388
JA
538 ;
539
ccc6cda3 540subshell: '(' compound_list ')'
726f6388
JA
541 { $2->flags |= CMD_WANT_SUBSHELL; $$ = $2; }
542 ;
ccc6cda3
JA
543
544if_command: IF compound_list THEN compound_list FI
726f6388 545 { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
ccc6cda3 546 | IF compound_list THEN compound_list ELSE compound_list FI
726f6388 547 { $$ = make_if_command ($2, $4, $6); }
ccc6cda3 548 | IF compound_list THEN compound_list elif_clause FI
726f6388
JA
549 { $$ = make_if_command ($2, $4, $5); }
550 ;
551
552
553group_command: '{' list '}'
554 { $$ = make_group_command ($2); }
555 ;
556
ccc6cda3 557elif_clause: ELIF compound_list THEN compound_list
726f6388 558 { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
ccc6cda3 559 | ELIF compound_list THEN compound_list ELSE compound_list
726f6388 560 { $$ = make_if_command ($2, $4, $6); }
ccc6cda3 561 | ELIF compound_list THEN compound_list elif_clause
726f6388
JA
562 { $$ = make_if_command ($2, $4, $5); }
563 ;
564
ccc6cda3
JA
565case_clause: pattern_list
566 | case_clause_sequence pattern_list
726f6388
JA
567 { $2->next = $1; $$ = $2; }
568 ;
569
ccc6cda3 570pattern_list: newline_list pattern ')' compound_list
726f6388 571 { $$ = make_pattern_list ($2, $4); }
ccc6cda3 572 | newline_list pattern ')' newline_list
726f6388 573 { $$ = make_pattern_list ($2, (COMMAND *)NULL); }
ccc6cda3 574 | newline_list '(' pattern ')' compound_list
726f6388 575 { $$ = make_pattern_list ($3, $5); }
ccc6cda3 576 | newline_list '(' pattern ')' newline_list
726f6388
JA
577 { $$ = make_pattern_list ($3, (COMMAND *)NULL); }
578 ;
579
ccc6cda3
JA
580case_clause_sequence: pattern_list SEMI_SEMI
581 | case_clause_sequence pattern_list SEMI_SEMI
726f6388
JA
582 { $2->next = $1; $$ = $2; }
583 ;
584
726f6388
JA
585pattern: WORD
586 { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
587 | pattern '|' WORD
588 { $$ = make_word_list ($3, $1); }
589 ;
590
591/* A list allows leading or trailing newlines and
592 newlines as operators (equivalent to semicolons).
593 It must end with a newline or semicolon.
594 Lists are used within commands such as if, for, while. */
595
ccc6cda3 596list: newline_list list0
726f6388
JA
597 {
598 $$ = $2;
599 if (need_here_doc)
600 gather_here_documents ();
601 }
602 ;
603
ccc6cda3
JA
604compound_list: list
605 | newline_list list1
606 {
607 $$ = $2;
608 }
609 ;
610
611list0: list1 '\n' newline_list
612 | list1 '&' newline_list
726f6388
JA
613 {
614 if ($1->type == cm_connection)
615 $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
616 else
617 $$ = command_connect ($1, (COMMAND *)NULL, '&');
618 }
ccc6cda3 619 | list1 ';' newline_list
726f6388
JA
620
621 ;
622
ccc6cda3 623list1: list1 AND_AND newline_list list1
726f6388 624 { $$ = command_connect ($1, $4, AND_AND); }
ccc6cda3 625 | list1 OR_OR newline_list list1
726f6388 626 { $$ = command_connect ($1, $4, OR_OR); }
ccc6cda3 627 | list1 '&' newline_list list1
726f6388
JA
628 {
629 if ($1->type == cm_connection)
630 $$ = connect_async_list ($1, $4, '&');
631 else
632 $$ = command_connect ($1, $4, '&');
633 }
ccc6cda3 634 | list1 ';' newline_list list1
726f6388 635 { $$ = command_connect ($1, $4, ';'); }
ccc6cda3 636 | list1 '\n' newline_list list1
726f6388 637 { $$ = command_connect ($1, $4, ';'); }
ccc6cda3 638 | pipeline_command
726f6388 639 { $$ = $1; }
726f6388
JA
640 ;
641
642list_terminator:'\n'
643 | ';'
644 | yacc_EOF
645 ;
646
ccc6cda3
JA
647newline_list:
648 | newline_list '\n'
726f6388
JA
649 ;
650
651/* A simple_list is a list that contains no significant newlines
652 and no leading or trailing newlines. Newlines are allowed
653 only following operators, where they are not significant.
654
655 This is what an inputunit consists of. */
656
657simple_list: simple_list1
658 {
659 $$ = $1;
660 if (need_here_doc)
661 gather_here_documents ();
662 }
663 | simple_list1 '&'
664 {
665 if ($1->type == cm_connection)
666 $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
667 else
668 $$ = command_connect ($1, (COMMAND *)NULL, '&');
669 if (need_here_doc)
670 gather_here_documents ();
671 }
672 | simple_list1 ';'
673 {
674 $$ = $1;
675 if (need_here_doc)
676 gather_here_documents ();
677 }
678 ;
679
ccc6cda3 680simple_list1: simple_list1 AND_AND newline_list simple_list1
726f6388 681 { $$ = command_connect ($1, $4, AND_AND); }
ccc6cda3 682 | simple_list1 OR_OR newline_list simple_list1
726f6388
JA
683 { $$ = command_connect ($1, $4, OR_OR); }
684 | simple_list1 '&' simple_list1
685 {
686 if ($1->type == cm_connection)
687 $$ = connect_async_list ($1, $3, '&');
688 else
689 $$ = command_connect ($1, $3, '&');
690 }
691 | simple_list1 ';' simple_list1
692 { $$ = command_connect ($1, $3, ';'); }
ccc6cda3
JA
693
694 | pipeline_command
695 { $$ = $1; }
696 ;
697
698pipeline_command: pipeline
726f6388
JA
699 { $$ = $1; }
700 | BANG pipeline
701 {
702 $2->flags |= CMD_INVERT_RETURN;
703 $$ = $2;
704 }
ccc6cda3
JA
705 | timespec pipeline
706 {
707 $2->flags |= $1;
708 $$ = $2;
709 }
710 | timespec BANG pipeline
711 {
712 $3->flags |= $1;
713 $$ = $3;
714 }
715 | BANG timespec pipeline
716 {
717 $3->flags |= $2|CMD_INVERT_RETURN;
718 $$ = $3;
719 }
726f6388
JA
720 ;
721
722pipeline:
ccc6cda3 723 pipeline '|' newline_list pipeline
726f6388
JA
724 { $$ = command_connect ($1, $4, '|'); }
725 | command
726 { $$ = $1; }
727 ;
ccc6cda3
JA
728
729timespec: TIME
730 { $$ = CMD_TIME_PIPELINE; }
731 | TIME TIMEOPT
732 { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
733 ;
726f6388
JA
734%%
735
ccc6cda3
JA
736/* Possible states for the parser that require it to do special things. */
737#define PST_CASEPAT 0x001 /* in a case pattern list */
738#define PST_ALEXPNEXT 0x002 /* expand next word for aliases */
739#define PST_ALLOWOPNBRC 0x004 /* allow open brace for function def */
740#define PST_NEEDCLOSBRC 0x008 /* need close brace */
741#define PST_DBLPAREN 0x010 /* double-paren parsing */
742#define PST_SUBSHELL 0x020 /* ( ... ) subshell */
743#define PST_CMDSUBST 0x040 /* $( ... ) command substitution */
744#define PST_CASESTMT 0x080 /* parsing a case statement */
745
726f6388
JA
746/* Initial size to allocate for tokens, and the
747 amount to grow them by. */
748#define TOKEN_DEFAULT_GROW_SIZE 512
749
ccc6cda3
JA
750/* Shell meta-characters that, when unquoted, separate words. */
751#define shellmeta(c) (strchr ("()<>;&|", (c)) != 0)
752#define shellbreak(c) (strchr ("()<>;&| \t\n", (c)) != 0)
753#define shellquote(c) ((c) == '"' || (c) == '`' || (c) == '\'')
754#define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>')
755
726f6388 756/* The token currently being read. */
ccc6cda3 757static int current_token;
726f6388
JA
758
759/* The last read token, or NULL. read_token () uses this for context
760 checking. */
ccc6cda3 761static int last_read_token;
726f6388
JA
762
763/* The token read prior to last_read_token. */
ccc6cda3
JA
764static int token_before_that;
765
766/* The token read prior to token_before_that. */
767static int two_tokens_ago;
726f6388
JA
768
769/* If non-zero, it is the token that we want read_token to return
770 regardless of what text is (or isn't) present to be read. This
ccc6cda3
JA
771 is reset by read_token. If token_to_read == WORD or
772 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
773static int token_to_read;
774static WORD_DESC *word_desc_to_read;
775
776/* The current parser state. */
777static int parser_state;
726f6388
JA
778
779/* Global var is non-zero when end of file has been reached. */
780int EOF_Reached = 0;
781
ccc6cda3
JA
782void
783debug_parser (i)
784 int i;
785{
786#if YYDEBUG != 0
787 yydebug = i;
788#endif
789}
790
726f6388
JA
791/* yy_getc () returns the next available character from input or EOF.
792 yy_ungetc (c) makes `c' the next character to read.
793 init_yy_io (get, unget, type, location) makes the function GET the
794 installed function for getting the next character, makes UNGET the
795 installed function for un-getting a character, sets the type of stream
796 (either string or file) from TYPE, and makes LOCATION point to where
797 the input is coming from. */
798
799/* Unconditionally returns end-of-file. */
ccc6cda3 800int
726f6388
JA
801return_EOF ()
802{
803 return (EOF);
804}
805
806/* Variable containing the current get and unget functions.
807 See ./input.h for a clearer description. */
808BASH_INPUT bash_input;
809
ccc6cda3
JA
810/* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
811 is non-null, avoiding a memory leak. */
726f6388
JA
812void
813initialize_bash_input ()
814{
ccc6cda3
JA
815 bash_input.type = st_none;
816 FREE (bash_input.name);
726f6388
JA
817 bash_input.name = (char *)NULL;
818 bash_input.location.file = (FILE *)NULL;
819 bash_input.location.string = (char *)NULL;
820 bash_input.getter = (Function *)NULL;
821 bash_input.ungetter = (Function *)NULL;
822}
823
824/* Set the contents of the current bash input stream from
825 GET, UNGET, TYPE, NAME, and LOCATION. */
826void
827init_yy_io (get, unget, type, name, location)
828 Function *get, *unget;
829 int type;
830 char *name;
831 INPUT_STREAM location;
832{
833 bash_input.type = type;
834 FREE (bash_input.name);
ccc6cda3 835 bash_input.name = name ? savestring (name) : (char *)NULL;
726f6388 836
ccc6cda3 837 /* XXX */
726f6388
JA
838#if defined (CRAY)
839 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
840#else
841 bash_input.location = location;
842#endif
843 bash_input.getter = get;
844 bash_input.ungetter = unget;
845}
846
847/* Call this to get the next character of input. */
ccc6cda3 848int
726f6388
JA
849yy_getc ()
850{
851 return (*(bash_input.getter)) ();
852}
853
854/* Call this to unget C. That is, to make C the next character
855 to be read. */
ccc6cda3 856int
726f6388
JA
857yy_ungetc (c)
858 int c;
859{
860 return (*(bash_input.ungetter)) (c);
861}
862
863#if defined (BUFFERED_INPUT)
864int
865input_file_descriptor ()
866{
867 switch (bash_input.type)
868 {
869 case st_stream:
870 return (fileno (bash_input.location.file));
871 case st_bstream:
872 return (bash_input.location.buffered_fd);
ccc6cda3 873 case st_stdin:
726f6388
JA
874 default:
875 return (fileno (stdin));
876 }
877}
878#endif /* BUFFERED_INPUT */
879
880/* **************************************************************** */
881/* */
882/* Let input be read from readline (). */
883/* */
884/* **************************************************************** */
885
886#if defined (READLINE)
887char *current_readline_prompt = (char *)NULL;
888char *current_readline_line = (char *)NULL;
889int current_readline_line_index = 0;
890
891static int
892yy_readline_get ()
893{
ccc6cda3
JA
894 SigHandler *old_sigint;
895 int line_len, c;
896
726f6388
JA
897 if (!current_readline_line)
898 {
726f6388
JA
899 if (!bash_readline_initialized)
900 initialize_readline ();
901
902#if defined (JOB_CONTROL)
903 if (job_control)
904 give_terminal_to (shell_pgrp);
905#endif /* JOB_CONTROL */
906
907 if (signal_is_ignored (SIGINT) == 0)
908 {
909 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
910 interrupt_immediately++;
911 }
912
ccc6cda3
JA
913 current_readline_line = readline (current_readline_prompt ?
914 current_readline_prompt : "");
726f6388
JA
915
916 if (signal_is_ignored (SIGINT) == 0)
917 {
918 interrupt_immediately--;
919 set_signal_handler (SIGINT, old_sigint);
920 }
921
ccc6cda3
JA
922#if 0
923 /* Reset the prompt to the decoded value of prompt_string_pointer. */
726f6388 924 reset_readline_prompt ();
ccc6cda3 925#endif
726f6388 926
ccc6cda3 927 if (current_readline_line == 0)
726f6388
JA
928 return (EOF);
929
ccc6cda3 930 current_readline_line_index = 0;
726f6388 931 line_len = strlen (current_readline_line);
ccc6cda3 932
726f6388
JA
933 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
934 current_readline_line[line_len++] = '\n';
935 current_readline_line[line_len] = '\0';
936 }
937
ccc6cda3 938 if (current_readline_line[current_readline_line_index] == 0)
726f6388
JA
939 {
940 free (current_readline_line);
941 current_readline_line = (char *)NULL;
942 return (yy_readline_get ());
943 }
944 else
945 {
ccc6cda3 946 c = (unsigned char)current_readline_line[current_readline_line_index++];
726f6388
JA
947 return (c);
948 }
949}
950
951static int
952yy_readline_unget (c)
ccc6cda3 953 int c;
726f6388
JA
954{
955 if (current_readline_line_index && current_readline_line)
956 current_readline_line[--current_readline_line_index] = c;
957 return (c);
958}
959
ccc6cda3 960void
726f6388
JA
961with_input_from_stdin ()
962{
963 INPUT_STREAM location;
964
965 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
966 {
967 location.string = current_readline_line;
968 init_yy_io (yy_readline_get, yy_readline_unget,
969 st_stdin, "readline stdin", location);
970 }
971}
972
973#else /* !READLINE */
974
975void
976with_input_from_stdin ()
977{
978 with_input_from_stream (stdin, "stdin");
979}
980#endif /* !READLINE */
981
982/* **************************************************************** */
983/* */
984/* Let input come from STRING. STRING is zero terminated. */
985/* */
986/* **************************************************************** */
987
988static int
989yy_string_get ()
990{
ccc6cda3 991 register char *string;
726f6388
JA
992 register int c;
993
994 string = bash_input.location.string;
995 c = EOF;
996
997 /* If the string doesn't exist, or is empty, EOF found. */
998 if (string && *string)
999 {
ccc6cda3 1000 c = *(unsigned char *)string++;
726f6388
JA
1001 bash_input.location.string = string;
1002 }
1003 return (c);
1004}
1005
1006static int
1007yy_string_unget (c)
1008 int c;
1009{
1010 *(--bash_input.location.string) = c;
1011 return (c);
1012}
1013
1014void
1015with_input_from_string (string, name)
ccc6cda3 1016 char *string, *name;
726f6388
JA
1017{
1018 INPUT_STREAM location;
1019
1020 location.string = string;
726f6388
JA
1021 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
1022}
1023
1024/* **************************************************************** */
1025/* */
1026/* Let input come from STREAM. */
1027/* */
1028/* **************************************************************** */
1029
1030static int
1031yy_stream_get ()
1032{
1033 int result = EOF;
1034
1035 if (bash_input.location.file)
ccc6cda3
JA
1036 {
1037#if !defined (HAVE_RESTARTABLE_SYSCALLS)
1038 result = getc_with_restart (bash_input.location.file);
1039#else /* HAVE_RESTARTABLE_SYSCALLS */
1040 result = getc (bash_input.location.file);
1041 result = (feof (bash_input.location.file)) ? EOF : (unsigned char)result;
1042#endif /* HAVE_RESTARTABLE_SYSCALLS */
1043 }
726f6388
JA
1044 return (result);
1045}
1046
1047static int
1048yy_stream_unget (c)
1049 int c;
1050{
ccc6cda3 1051#if !defined (HAVE_RESTARTABLE_SYSCALLS)
726f6388 1052 return (ungetc_with_restart (c, bash_input.location.file));
ccc6cda3 1053#else /* HAVE_RESTARTABLE_SYSCALLS */
726f6388 1054 return (ungetc (c, bash_input.location.file));
ccc6cda3 1055#endif /* HAVE_RESTARTABLE_SYSCALLS */
726f6388
JA
1056}
1057
1058void
1059with_input_from_stream (stream, name)
1060 FILE *stream;
1061 char *name;
1062{
1063 INPUT_STREAM location;
1064
1065 location.file = stream;
1066 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
1067}
1068
1069typedef struct stream_saver {
1070 struct stream_saver *next;
1071 BASH_INPUT bash_input;
1072 int line;
1073#if defined (BUFFERED_INPUT)
1074 BUFFERED_STREAM *bstream;
1075#endif /* BUFFERED_INPUT */
1076} STREAM_SAVER;
1077
1078/* The globally known line number. */
1079int line_number = 0;
1080
1081STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
1082
ccc6cda3
JA
1083void
1084push_stream (reset_lineno)
1085 int reset_lineno;
726f6388
JA
1086{
1087 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1088
1089 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1090
1091#if defined (BUFFERED_INPUT)
1092 saver->bstream = (BUFFERED_STREAM *)NULL;
1093 /* If we have a buffered stream, clear out buffers[fd]. */
1094 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1095 {
1096 saver->bstream = buffers[bash_input.location.buffered_fd];
1097 buffers[bash_input.location.buffered_fd] = (BUFFERED_STREAM *)NULL;
1098 }
1099#endif /* BUFFERED_INPUT */
1100
1101 saver->line = line_number;
1102 bash_input.name = (char *)NULL;
1103 saver->next = stream_list;
1104 stream_list = saver;
ccc6cda3
JA
1105 EOF_Reached = 0;
1106 if (reset_lineno)
1107 line_number = 0;
726f6388
JA
1108}
1109
ccc6cda3 1110void
726f6388
JA
1111pop_stream ()
1112{
726f6388
JA
1113 if (!stream_list)
1114 EOF_Reached = 1;
1115 else
1116 {
1117 STREAM_SAVER *saver = stream_list;
1118
1119 EOF_Reached = 0;
1120 stream_list = stream_list->next;
1121
1122 init_yy_io (saver->bash_input.getter,
1123 saver->bash_input.ungetter,
1124 saver->bash_input.type,
1125 saver->bash_input.name,
1126 saver->bash_input.location);
1127
1128#if defined (BUFFERED_INPUT)
1129 /* If we have a buffered stream, restore buffers[fd]. */
1130 /* If the input file descriptor was changed while this was on the
1131 save stack, update the buffered fd to the new file descriptor and
1132 re-establish the buffer <-> bash_input fd correspondence. */
1133 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1134 {
1135 if (bash_input_fd_changed)
1136 {
1137 bash_input_fd_changed = 0;
1138 if (default_buffered_input >= 0)
1139 {
1140 bash_input.location.buffered_fd = default_buffered_input;
1141 saver->bstream->b_fd = default_buffered_input;
1142 }
1143 }
1144 buffers[bash_input.location.buffered_fd] = saver->bstream;
1145 }
1146#endif /* BUFFERED_INPUT */
1147
1148 line_number = saver->line;
1149
1150 FREE (saver->bash_input.name);
1151 free (saver);
1152 }
1153}
1154
1155/* Return 1 if a stream of type TYPE is saved on the stack. */
1156int
1157stream_on_stack (type)
ccc6cda3 1158 enum stream_type type;
726f6388
JA
1159{
1160 register STREAM_SAVER *s;
ccc6cda3 1161
726f6388
JA
1162 for (s = stream_list; s; s = s->next)
1163 if (s->bash_input.type == type)
1164 return 1;
1165 return 0;
1166}
1167
726f6388
JA
1168/*
1169 * This is used to inhibit alias expansion and reserved word recognition
ccc6cda3
JA
1170 * inside case statement pattern lists. A `case statement pattern list' is:
1171 *
726f6388
JA
1172 * everything between the `in' in a `case word in' and the next ')'
1173 * or `esac'
1174 * everything between a `;;' and the next `)' or `esac'
1175 */
726f6388
JA
1176
1177#if defined (ALIAS)
ccc6cda3
JA
1178
1179#define END_OF_ALIAS 0
1180
726f6388
JA
1181/*
1182 * Pseudo-global variables used in implementing token-wise alias expansion.
1183 */
1184
726f6388 1185/*
ccc6cda3 1186 * Pushing and popping strings. This works together with shell_getc to
726f6388
JA
1187 * implement alias expansion on a per-token basis.
1188 */
1189
1190typedef struct string_saver {
1191 struct string_saver *next;
1192 int expand_alias; /* Value to set expand_alias to when string is popped. */
1193 char *saved_line;
ccc6cda3 1194 alias_t *expander; /* alias that caused this line to be pushed. */
726f6388
JA
1195 int saved_line_size, saved_line_index, saved_line_terminator;
1196} STRING_SAVER;
1197
1198STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1199
726f6388
JA
1200/*
1201 * Push the current shell_input_line onto a stack of such lines and make S
1202 * the current input. Used when expanding aliases. EXPAND is used to set
1203 * the value of expand_next_token when the string is popped, so that the
1204 * word after the alias in the original line is handled correctly when the
1205 * alias expands to multiple words. TOKEN is the token that was expanded
1206 * into S; it is saved and used to prevent infinite recursive expansion.
1207 */
1208static void
ccc6cda3 1209push_string (s, expand, ap)
726f6388
JA
1210 char *s;
1211 int expand;
ccc6cda3 1212 alias_t *ap;
726f6388
JA
1213{
1214 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
1215
1216 temp->expand_alias = expand;
1217 temp->saved_line = shell_input_line;
1218 temp->saved_line_size = shell_input_line_size;
1219 temp->saved_line_index = shell_input_line_index;
1220 temp->saved_line_terminator = shell_input_line_terminator;
ccc6cda3 1221 temp->expander = ap;
726f6388
JA
1222 temp->next = pushed_string_list;
1223 pushed_string_list = temp;
1224
ccc6cda3 1225 ap->flags |= AL_BEINGEXPANDED;
726f6388
JA
1226
1227 shell_input_line = s;
1228 shell_input_line_size = strlen (s);
1229 shell_input_line_index = 0;
1230 shell_input_line_terminator = '\0';
ccc6cda3 1231 parser_state &= ~PST_ALEXPNEXT;
726f6388
JA
1232}
1233
1234/*
1235 * Make the top of the pushed_string stack be the current shell input.
1236 * Only called when there is something on the stack. Called from shell_getc
1237 * when it thinks it has consumed the string generated by an alias expansion
1238 * and needs to return to the original input line.
1239 */
1240static void
1241pop_string ()
1242{
1243 STRING_SAVER *t;
1244
1245 FREE (shell_input_line);
1246 shell_input_line = pushed_string_list->saved_line;
1247 shell_input_line_index = pushed_string_list->saved_line_index;
1248 shell_input_line_size = pushed_string_list->saved_line_size;
1249 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
ccc6cda3
JA
1250
1251 if (pushed_string_list->expand_alias)
1252 parser_state |= PST_ALEXPNEXT;
1253 else
1254 parser_state &= ~PST_ALEXPNEXT;
726f6388
JA
1255
1256 t = pushed_string_list;
1257 pushed_string_list = pushed_string_list->next;
ccc6cda3
JA
1258
1259 t->expander->flags &= ~AL_BEINGEXPANDED;
1260
1261 free ((char *)t);
726f6388
JA
1262}
1263
1264static void
1265free_string_list ()
1266{
ccc6cda3 1267 register STRING_SAVER *t, *t1;
726f6388 1268
ccc6cda3 1269 for (t = pushed_string_list; t; )
726f6388
JA
1270 {
1271 t1 = t->next;
1272 FREE (t->saved_line);
ccc6cda3 1273 t->expander->flags &= ~AL_BEINGEXPANDED;
726f6388
JA
1274 free ((char *)t);
1275 t = t1;
1276 }
1277 pushed_string_list = (STRING_SAVER *)NULL;
1278}
1279
726f6388 1280#endif /* ALIAS */
ccc6cda3 1281
726f6388
JA
1282/* Return a line of text, taken from wherever yylex () reads input.
1283 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
1284 is non-zero, we remove unquoted \<newline> pairs. This is used by
1285 read_secondary_line to read here documents. */
1286static char *
1287read_a_line (remove_quoted_newline)
1288 int remove_quoted_newline;
1289{
1290 static char *line_buffer = (char *)NULL;
1291 static int buffer_size = 0;
1292 int indx = 0, c, peekc, pass_next;
1293
ccc6cda3
JA
1294#if defined (READLINE)
1295 if (interactive && bash_input.type != st_string && no_line_editing)
1296#else
1297 if (interactive && bash_input.type != st_string)
1298#endif
1299 print_prompt ();
1300
726f6388
JA
1301 pass_next = 0;
1302 while (1)
1303 {
1304 c = yy_getc ();
1305
1306 /* Allow immediate exit if interrupted during input. */
1307 QUIT;
1308
1309 if (c == 0)
1310 continue;
1311
1312 /* If there is no more input, then we return NULL. */
1313 if (c == EOF)
1314 {
ccc6cda3
JA
1315 if (interactive && bash_input.type == st_stream)
1316 clearerr (stdin);
726f6388
JA
1317 if (indx == 0)
1318 return ((char *)NULL);
1319 c = '\n';
1320 }
1321
1322 /* `+2' in case the final character in the buffer is a newline. */
ccc6cda3 1323 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
726f6388
JA
1324
1325 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
1326 here document with an unquoted delimiter. In this case,
1327 the line will be expanded as if it were in double quotes.
1328 We allow a backslash to escape the next character, but we
1329 need to treat the backslash specially only if a backslash
1330 quoting a backslash-newline pair appears in the line. */
1331 if (pass_next)
1332 {
1333 line_buffer[indx++] = c;
1334 pass_next = 0;
1335 }
1336 else if (c == '\\' && remove_quoted_newline)
1337 {
1338 peekc = yy_getc ();
1339 if (peekc == '\n')
1340 continue; /* Make the unquoted \<newline> pair disappear. */
1341 else
1342 {
1343 yy_ungetc (peekc);
1344 pass_next = 1;
1345 line_buffer[indx++] = c; /* Preserve the backslash. */
1346 }
1347 }
1348 else
1349 line_buffer[indx++] = c;
1350
1351 if (c == '\n')
1352 {
1353 line_buffer[indx] = '\0';
1354 return (line_buffer);
1355 }
1356 }
1357}
1358
1359/* Return a line as in read_a_line (), but insure that the prompt is
1360 the secondary prompt. This is used to read the lines of a here
1361 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
1362 newlines quoted with backslashes while reading the line. It is
1363 non-zero unless the delimiter of the here document was quoted. */
1364char *
1365read_secondary_line (remove_quoted_newline)
1366 int remove_quoted_newline;
1367{
1368 prompt_string_pointer = &ps2_prompt;
1369 prompt_again ();
1370 return (read_a_line (remove_quoted_newline));
1371}
1372
726f6388
JA
1373/* **************************************************************** */
1374/* */
1375/* YYLEX () */
1376/* */
1377/* **************************************************************** */
1378
1379/* Reserved words. These are only recognized as the first word of a
1380 command. */
1381STRING_INT_ALIST word_token_alist[] = {
1382 { "if", IF },
1383 { "then", THEN },
1384 { "else", ELSE },
1385 { "elif", ELIF },
1386 { "fi", FI },
1387 { "case", CASE },
1388 { "esac", ESAC },
1389 { "for", FOR },
1390#if defined (SELECT_COMMAND)
1391 { "select", SELECT },
1392#endif
1393 { "while", WHILE },
1394 { "until", UNTIL },
1395 { "do", DO },
1396 { "done", DONE },
1397 { "in", IN },
1398 { "function", FUNCTION },
ccc6cda3
JA
1399#if defined (COMMAND_TIMING)
1400 { "time", TIME },
1401#endif
726f6388
JA
1402 { "{", '{' },
1403 { "}", '}' },
1404 { "!", BANG },
1405 { (char *)NULL, 0}
1406};
1407
ccc6cda3
JA
1408/* These are used by read_token_word, but appear up here so that shell_getc
1409 can use them to decide when to add otherwise blank lines to the history. */
1410
1411/* The primary delimiter stack. */
1412struct dstack dstack = { (char *)NULL, 0, 0 };
1413
1414/* A temporary delimiter stack to be used when decoding prompt strings.
1415 This is needed because command substitutions in prompt strings (e.g., PS2)
1416 can screw up the parser's quoting state. */
1417static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
1418
1419/* Macro for accessing the top delimiter on the stack. Returns the
1420 delimiter or zero if none. */
1421#define current_delimiter(ds) \
1422 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
1423
1424#define push_delimiter(ds, character) \
1425 do \
1426 { \
1427 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
1428 ds.delimiters = xrealloc \
1429 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
1430 ds.delimiters[ds.delimiter_depth] = character; \
1431 ds.delimiter_depth++; \
1432 } \
1433 while (0)
1434
1435#define pop_delimiter(ds) ds.delimiter_depth--
1436
726f6388
JA
1437/* Return the next shell input character. This always reads characters
1438 from shell_input_line; when that line is exhausted, it is time to
1439 read the next line. This is called by read_token when the shell is
1440 processing normal command input. */
ccc6cda3 1441
726f6388
JA
1442static int
1443shell_getc (remove_quoted_newline)
1444 int remove_quoted_newline;
1445{
ccc6cda3 1446 register int i;
726f6388 1447 int c;
ccc6cda3 1448 static int mustpop = 0;
726f6388
JA
1449
1450 QUIT;
1451
1452#if defined (ALIAS)
1453 /* If shell_input_line[shell_input_line_index] == 0, but there is
1454 something on the pushed list of strings, then we don't want to go
1455 off and get another line. We let the code down below handle it. */
1456
1457 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
1458 (pushed_string_list == (STRING_SAVER *)NULL)))
1459#else /* !ALIAS */
1460 if (!shell_input_line || !shell_input_line[shell_input_line_index])
1461#endif /* !ALIAS */
1462 {
726f6388
JA
1463 line_number++;
1464
1465 restart_read:
1466
1467 /* Allow immediate exit if interrupted during input. */
1468 QUIT;
1469
1470 i = 0;
1471 shell_input_line_terminator = 0;
1472
1473#if defined (JOB_CONTROL)
1474 /* This can cause a problem when reading a command as the result
1475 of a trap, when the trap is called from flush_child. This call
1476 had better not cause jobs to disappear from the job table in
1477 that case, or we will have big trouble. */
1478 notify_and_cleanup ();
1479#else /* !JOB_CONTROL */
1480 cleanup_dead_jobs ();
1481#endif /* !JOB_CONTROL */
1482
1483#if defined (READLINE)
1484 if (interactive && bash_input.type != st_string && no_line_editing)
1485#else
1486 if (interactive && bash_input.type != st_string)
1487#endif
1488 print_prompt ();
1489
1490 if (bash_input.type == st_stream)
1491 clearerr (stdin);
1492
1493 while (c = yy_getc ())
1494 {
1495 /* Allow immediate exit if interrupted during input. */
1496 QUIT;
1497
ccc6cda3 1498 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
726f6388
JA
1499
1500 if (c == EOF)
1501 {
1502 if (bash_input.type == st_stream)
1503 clearerr (stdin);
1504
ccc6cda3 1505 if (i == 0)
726f6388
JA
1506 shell_input_line_terminator = EOF;
1507
1508 shell_input_line[i] = '\0';
1509 break;
1510 }
1511
1512 shell_input_line[i++] = c;
1513
1514 if (c == '\n')
1515 {
1516 shell_input_line[--i] = '\0';
1517 current_command_line_count++;
1518 break;
1519 }
1520 }
1521 shell_input_line_index = 0;
1522 shell_input_line_len = i; /* == strlen (shell_input_line) */
1523
1524#if defined (HISTORY)
ccc6cda3 1525 if (remember_on_history && shell_input_line && shell_input_line[0])
726f6388
JA
1526 {
1527 char *expansions;
ccc6cda3
JA
1528# if defined (BANG_HISTORY)
1529 int old_hist;
1530
1531 /* If the current delimiter is a single quote, we should not be
1532 performing history expansion, even if we're on a different
1533 line from the original single quote. */
1534 old_hist = history_expansion_inhibited;
1535 if (current_delimiter (dstack) == '\'')
1536 history_expansion_inhibited = 1;
1537# endif
726f6388 1538 expansions = pre_process_line (shell_input_line, 1, 1);
ccc6cda3
JA
1539# if defined (BANG_HISTORY)
1540 history_expansion_inhibited = old_hist;
1541# endif
726f6388
JA
1542
1543 free (shell_input_line);
1544 shell_input_line = expansions;
1545 shell_input_line_len = shell_input_line ?
1546 strlen (shell_input_line) :
1547 0;
1548 if (!shell_input_line_len)
1549 current_command_line_count--;
1550
1551 /* We have to force the xrealloc below because we don't know the
1552 true allocated size of shell_input_line anymore. */
1553 shell_input_line_size = shell_input_line_len;
1554 }
ccc6cda3
JA
1555 /* XXX - this is grotesque */
1556 else if (remember_on_history && shell_input_line &&
1557 shell_input_line[0] == '\0' &&
1558 current_command_line_count > 1 && current_delimiter (dstack))
1559 {
1560 /* We know shell_input_line[0] == 0 and we're reading some sort of
1561 quoted string. This means we've got a line consisting of only
1562 a newline in a quoted string. We want to make sure this line
1563 gets added to the history. */
1564 maybe_add_history (shell_input_line);
1565 }
1566
726f6388
JA
1567#endif /* HISTORY */
1568
1569 if (shell_input_line)
1570 {
1571 /* Lines that signify the end of the shell's input should not be
1572 echoed. */
1573 if (echo_input_at_read && (shell_input_line[0] ||
1574 shell_input_line_terminator != EOF))
1575 fprintf (stderr, "%s\n", shell_input_line);
1576 }
1577 else
1578 {
1579 shell_input_line_size = 0;
1580 prompt_string_pointer = &current_prompt_string;
1581 prompt_again ();
1582 goto restart_read;
1583 }
1584
1585 /* Add the newline to the end of this string, iff the string does
1586 not already end in an EOF character. */
1587 if (shell_input_line_terminator != EOF)
1588 {
ccc6cda3 1589 if (shell_input_line_len + 3 > shell_input_line_size)
726f6388
JA
1590 shell_input_line = xrealloc (shell_input_line,
1591 1 + (shell_input_line_size += 2));
1592
ccc6cda3
JA
1593 shell_input_line[shell_input_line_len] = '\n';
1594 shell_input_line[shell_input_line_len + 1] = '\0';
726f6388
JA
1595 }
1596 }
ccc6cda3 1597
726f6388
JA
1598 c = shell_input_line[shell_input_line_index];
1599
1600 if (c)
1601 shell_input_line_index++;
1602
1603 if (c == '\\' && remove_quoted_newline &&
1604 shell_input_line[shell_input_line_index] == '\n')
1605 {
1606 prompt_again ();
ccc6cda3
JA
1607 line_number++;
1608 goto restart_read;
726f6388
JA
1609 }
1610
1611#if defined (ALIAS)
1612 /* If C is NULL, we have reached the end of the current input string. If
1613 pushed_string_list is non-empty, it's time to pop to the previous string
1614 because we have fully consumed the result of the last alias expansion.
1615 Do it transparently; just return the next character of the string popped
1616 to. */
1617 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
1618 {
ccc6cda3
JA
1619 if (mustpop)
1620 {
1621 pop_string ();
1622 c = shell_input_line[shell_input_line_index];
1623 if (c)
1624 shell_input_line_index++;
1625 mustpop--;
1626 }
1627 else
1628 {
1629 mustpop++;
1630 c = ' ';
1631 }
726f6388
JA
1632 }
1633#endif /* ALIAS */
1634
1635 if (!c && shell_input_line_terminator == EOF)
ccc6cda3 1636 return ((shell_input_line_index != 0) ? '\n' : EOF);
726f6388
JA
1637
1638 return ((unsigned char)c);
1639}
1640
1641/* Put C back into the input for the shell. */
1642static void
1643shell_ungetc (c)
1644 int c;
1645{
1646 if (shell_input_line && shell_input_line_index)
1647 shell_input_line[--shell_input_line_index] = c;
1648}
1649
ccc6cda3
JA
1650static void
1651shell_ungetchar ()
1652{
1653 if (shell_input_line && shell_input_line_index)
1654 shell_input_line_index--;
1655}
1656
1657/* Discard input until CHARACTER is seen, then push that character back
1658 onto the input stream. */
726f6388
JA
1659static void
1660discard_until (character)
1661 int character;
1662{
1663 int c;
1664
1665 while ((c = shell_getc (0)) != EOF && c != character)
1666 ;
1667
1668 if (c != EOF)
1669 shell_ungetc (c);
1670}
726f6388
JA
1671
1672void
1673execute_prompt_command (command)
1674 char *command;
1675{
1676 Function *temp_last, *temp_this;
1677 char *last_lastarg;
1678 int temp_exit_value, temp_eof_encountered;
1679
1680 temp_last = last_shell_builtin;
1681 temp_this = this_shell_builtin;
1682 temp_exit_value = last_command_exit_value;
1683 temp_eof_encountered = eof_encountered;
1684 last_lastarg = get_string_value ("_");
1685 if (last_lastarg)
1686 last_lastarg = savestring (last_lastarg);
1687
1688 parse_and_execute (savestring (command), "PROMPT_COMMAND", 0);
1689
1690 last_shell_builtin = temp_last;
1691 this_shell_builtin = temp_this;
1692 last_command_exit_value = temp_exit_value;
1693 eof_encountered = temp_eof_encountered;
1694
1695 bind_variable ("_", last_lastarg);
1696 FREE (last_lastarg);
1697
ccc6cda3 1698 if (token_to_read == '\n') /* reset_parser was called */
726f6388
JA
1699 token_to_read = 0;
1700}
1701
ccc6cda3
JA
1702/* Place to remember the token. We try to keep the buffer
1703 at a reasonable size, but it can grow. */
1704static char *token = (char *)NULL;
1705
1706/* Current size of the token buffer. */
1707static int token_buffer_size;
1708
726f6388
JA
1709/* Command to read_token () explaining what we want it to do. */
1710#define READ 0
1711#define RESET 1
1712#define prompt_is_ps1 \
1713 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
1714
1715/* Function for yyparse to call. yylex keeps track of
1716 the last two tokens read, and calls read_token. */
ccc6cda3 1717static int
726f6388
JA
1718yylex ()
1719{
ccc6cda3 1720 if (interactive && (current_token == 0 || current_token == '\n'))
726f6388
JA
1721 {
1722 /* Before we print a prompt, we might have to check mailboxes.
1723 We do this only if it is time to do so. Notice that only here
1724 is the mail alarm reset; nothing takes place in check_mail ()
1725 except the checking of mail. Please don't change this. */
1726 if (prompt_is_ps1 && time_to_check_mail ())
1727 {
1728 check_mail ();
1729 reset_mail_timer ();
1730 }
1731
1732 /* Avoid printing a prompt if we're not going to read anything, e.g.
1733 after resetting the parser with read_token (RESET). */
1734 if (token_to_read == 0 && interactive)
1735 prompt_again ();
1736 }
1737
ccc6cda3 1738 two_tokens_ago = token_before_that;
726f6388
JA
1739 token_before_that = last_read_token;
1740 last_read_token = current_token;
1741 current_token = read_token (READ);
1742 return (current_token);
1743}
1744
726f6388
JA
1745/* When non-zero, we have read the required tokens
1746 which allow ESAC to be the next one read. */
ccc6cda3 1747static int esacs_needed_count;
726f6388
JA
1748
1749void
1750gather_here_documents ()
1751{
1752 int r = 0;
1753 while (need_here_doc)
1754 {
1755 make_here_document (redir_stack[r++]);
1756 need_here_doc--;
1757 }
1758}
1759
726f6388
JA
1760/* When non-zero, an open-brace used to create a group is awaiting a close
1761 brace partner. */
ccc6cda3 1762static int open_brace_count;
726f6388
JA
1763
1764#define command_token_position(token) \
1765 (((token) == ASSIGNMENT_WORD) || \
1766 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
1767
1768#define assignment_acceptable(token) command_token_position(token) && \
ccc6cda3 1769 ((parser_state & PST_CASEPAT) == 0)
726f6388
JA
1770
1771/* Check to see if TOKEN is a reserved word and return the token
1772 value if it is. */
1773#define CHECK_FOR_RESERVED_WORD(tok) \
1774 do { \
1775 if (!dollar_present && !quoted && \
1776 reserved_word_acceptable (last_read_token)) \
1777 { \
1778 int i; \
1779 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
1780 if (STREQ (tok, word_token_alist[i].word)) \
1781 { \
ccc6cda3 1782 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
726f6388 1783 break; \
726f6388 1784 if (word_token_alist[i].token == ESAC) \
ccc6cda3
JA
1785 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
1786 else if (word_token_alist[i].token == CASE) \
1787 parser_state |= PST_CASESTMT; \
1788 else if (word_token_alist[i].token == '{') \
1789 open_brace_count++; \
1790 else if (word_token_alist[i].token == '}' && open_brace_count) \
1791 open_brace_count--; \
726f6388
JA
1792 return (word_token_alist[i].token); \
1793 } \
1794 } \
1795 } while (0)
1796
ccc6cda3
JA
1797#if defined (ALIAS)
1798
1799 /* OK, we have a token. Let's try to alias expand it, if (and only if)
1800 it's eligible.
1801
1802 It is eligible for expansion if the shell is in interactive mode, and
1803 the token is unquoted and the last token read was a command
1804 separator (or expand_next_token is set), and we are currently
1805 processing an alias (pushed_string_list is non-empty) and this
1806 token is not the same as the current or any previously
1807 processed alias.
1808
1809 Special cases that disqualify:
1810 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
1811static int
1812alias_expand_token (token)
1813 char *token;
726f6388 1814{
ccc6cda3
JA
1815 char *expanded;
1816 alias_t *ap;
726f6388 1817
ccc6cda3
JA
1818 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
1819 (parser_state & PST_CASEPAT) == 0)
726f6388 1820 {
ccc6cda3
JA
1821 ap = find_alias (token);
1822
1823 /* Currently expanding this token. */
1824 if (ap && (ap->flags & AL_BEINGEXPANDED))
1825 return (NO_EXPANSION);
1826
1827 expanded = ap ? savestring (ap->value) : (char *)NULL;
1828 if (expanded)
1829 {
1830 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
1831 return (RE_READ_TOKEN);
1832 }
1833 else
1834 /* This is an eligible token that does not have an expansion. */
1835 return (NO_EXPANSION);
726f6388 1836 }
ccc6cda3
JA
1837 return (NO_EXPANSION);
1838}
1839#endif /* ALIAS */
726f6388 1840
ccc6cda3
JA
1841/* Handle special cases of token recognition:
1842 IN is recognized if the last token was WORD and the token
1843 before that was FOR or CASE or SELECT.
1844
1845 DO is recognized if the last token was WORD and the token
1846 before that was FOR or SELECT.
1847
1848 ESAC is recognized if the last token caused `esacs_needed_count'
1849 to be set
1850
1851 `{' is recognized if the last token as WORD and the token
1852 before that was FUNCTION.
1853
1854 `}' is recognized if there is an unclosed `{' prsent.
1855*/
1856
1857static int
1858special_case_tokens (token)
1859 char *token;
1860{
1861 if ((last_read_token == WORD) &&
1862#if defined (SELECT_COMMAND)
1863 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
1864#else
1865 ((token_before_that == FOR) || (token_before_that == CASE)) &&
1866#endif
1867 (token[0] == 'i' && token[1] == 'n' && token[2] == 0))
726f6388 1868 {
ccc6cda3
JA
1869 if (token_before_that == CASE)
1870 {
1871 parser_state |= PST_CASEPAT;
1872 esacs_needed_count++;
1873 }
1874 return (IN);
1875 }
726f6388 1876
ccc6cda3
JA
1877 if (last_read_token == WORD &&
1878#if defined (SELECT_COMMAND)
1879 (token_before_that == FOR || token_before_that == SELECT) &&
1880#else
1881 (token_before_that == FOR) &&
1882#endif
1883 (token[0] == 'd' && token[1] == 'o' && token[2] == '\0'))
1884 return (DO);
1885
1886 /* Ditto for ESAC in the CASE case.
1887 Specifically, this handles "case word in esac", which is a legal
1888 construct, certainly because someone will pass an empty arg to the
1889 case construct, and we don't want it to barf. Of course, we should
1890 insist that the case construct has at least one pattern in it, but
1891 the designers disagree. */
1892 if (esacs_needed_count)
1893 {
1894 esacs_needed_count--;
1895 if (STREQ (token, "esac"))
726f6388 1896 {
ccc6cda3
JA
1897 parser_state &= ~PST_CASEPAT;
1898 return (ESAC);
726f6388 1899 }
ccc6cda3 1900 }
726f6388 1901
ccc6cda3
JA
1902 /* The start of a shell function definition. */
1903 if (parser_state & PST_ALLOWOPNBRC)
1904 {
1905 parser_state &= ~PST_ALLOWOPNBRC;
1906 if (token[0] == '{' && token[1] == '\0') /* } */
726f6388 1907 {
ccc6cda3
JA
1908 open_brace_count++;
1909 function_bstart = line_number;
1910 return ('{'); /* } */
726f6388 1911 }
ccc6cda3
JA
1912 }
1913
1914 if (open_brace_count && reserved_word_acceptable (last_read_token) && token[0] == '}' && !token[1])
1915 {
1916 open_brace_count--; /* { */
1917 return ('}');
1918 }
1919
1920 /* Handle -p after `time'. */
1921 if (last_read_token == TIME && token[0] == '-' && token[1] == 'p' && !token[2])
1922 return (TIMEOPT);
726f6388 1923
ccc6cda3
JA
1924 return (-1);
1925}
1926
1927/* Called from shell.c when Control-C is typed at top level. Or
1928 by the error rule at top level. */
1929void
1930reset_parser ()
1931{
1932 dstack.delimiter_depth = 0; /* No delimiters found so far. */
1933 open_brace_count = 0;
1934
1935 parser_state = 0;
1936
1937#if defined (ALIAS)
1938 if (pushed_string_list)
1939 {
1940 free_string_list ();
1941 pushed_string_list = (STRING_SAVER *)NULL;
1942 }
726f6388
JA
1943#endif /* ALIAS */
1944
ccc6cda3
JA
1945 if (shell_input_line)
1946 {
1947 free (shell_input_line);
1948 shell_input_line = (char *)NULL;
1949 shell_input_line_size = shell_input_line_index = 0;
1950 }
1951
1952 FREE (word_desc_to_read);
1953 word_desc_to_read = (WORD_DESC *)NULL;
1954
1955 last_read_token = '\n';
1956 token_to_read = '\n';
1957}
1958
1959/* Read the next token. Command can be READ (normal operation) or
1960 RESET (to normalize state). */
1961static int
1962read_token (command)
1963 int command;
1964{
1965 int character; /* Current character. */
1966 int peek_char; /* Temporary look-ahead character. */
1967 int result; /* The thing to return. */
1968
1969 if (command == RESET)
1970 {
1971 reset_parser ();
726f6388
JA
1972 return ('\n');
1973 }
1974
1975 if (token_to_read)
1976 {
ccc6cda3
JA
1977 result = token_to_read;
1978 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
1979 yylval.word = word_desc_to_read;
726f6388 1980 token_to_read = 0;
ccc6cda3 1981 return (result);
726f6388
JA
1982 }
1983
1984#if defined (ALIAS)
726f6388
JA
1985 /* This is a place to jump back to once we have successfully expanded a
1986 token with an alias and pushed the string with push_string () */
1987 re_read_token:
726f6388
JA
1988#endif /* ALIAS */
1989
1990 /* Read a single word from input. Start by skipping blanks. */
ccc6cda3
JA
1991 while ((character = shell_getc (1)) != EOF && whitespace (character))
1992 ;
726f6388
JA
1993
1994 if (character == EOF)
1995 {
1996 EOF_Reached = 1;
1997 return (yacc_EOF);
1998 }
1999
2000 if (character == '#' && (!interactive || interactive_comments))
2001 {
2002 /* A comment. Discard until EOL or EOF, and then return a newline. */
2003 discard_until ('\n');
2004 shell_getc (0);
ccc6cda3 2005 character = '\n'; /* this will take the next if statement and return. */
726f6388
JA
2006 }
2007
2008 if (character == '\n')
2009 {
2010 /* If we're about to return an unquoted newline, we can go and collect
2011 the text of any pending here document. */
2012 if (need_here_doc)
2013 gather_here_documents ();
2014
2015#if defined (ALIAS)
ccc6cda3 2016 parser_state &= ~PST_ALEXPNEXT;
726f6388
JA
2017#endif /* ALIAS */
2018
2019 return (character);
2020 }
2021
ccc6cda3
JA
2022 /* Shell meta-characters. */
2023 if (shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
726f6388
JA
2024 {
2025#if defined (ALIAS)
2026 /* Turn off alias tokenization iff this character sequence would
2027 not leave us ready to read a command. */
2028 if (character == '<' || character == '>')
ccc6cda3 2029 parser_state &= ~PST_ALEXPNEXT;
726f6388
JA
2030#endif /* ALIAS */
2031
ccc6cda3
JA
2032 peek_char = shell_getc (1);
2033 if (character == peek_char)
726f6388
JA
2034 {
2035 switch (character)
2036 {
ccc6cda3 2037 case '<':
726f6388
JA
2038 /* If '<' then we could be at "<<" or at "<<-". We have to
2039 look ahead one more character. */
726f6388
JA
2040 peek_char = shell_getc (1);
2041 if (peek_char == '-')
2042 return (LESS_LESS_MINUS);
2043 else
2044 {
2045 shell_ungetc (peek_char);
2046 return (LESS_LESS);
2047 }
2048
2049 case '>':
2050 return (GREATER_GREATER);
2051
2052 case ';':
ccc6cda3 2053 parser_state |= PST_CASEPAT;
726f6388 2054#if defined (ALIAS)
ccc6cda3 2055 parser_state &= ~PST_ALEXPNEXT;
726f6388
JA
2056#endif /* ALIAS */
2057 return (SEMI_SEMI);
2058
2059 case '&':
2060 return (AND_AND);
2061
2062 case '|':
2063 return (OR_OR);
ccc6cda3
JA
2064
2065#if defined (DPAREN_ARITHMETIC)
2066 case '(': /* ) */
2067 if (reserved_word_acceptable (last_read_token))
726f6388 2068 {
ccc6cda3
JA
2069 parser_state |= PST_DBLPAREN;
2070 yylval.word = make_word ("let");
2071 return (WORD);
726f6388 2072 }
ccc6cda3
JA
2073 break;
2074#endif
726f6388 2075 }
726f6388 2076 }
ccc6cda3
JA
2077 else if (character == '<' && peek_char == '&')
2078 return (LESS_AND);
2079 else if (character == '>' && peek_char == '&')
2080 return (GREATER_AND);
2081 else if (character == '<' && peek_char == '>')
2082 return (LESS_GREATER);
2083 else if (character == '>' && peek_char == '|')
2084 return (GREATER_BAR);
2085 else if (peek_char == '>' && character == '&')
2086 return (AND_GREATER);
2087
726f6388
JA
2088 shell_ungetc (peek_char);
2089
2090 /* If we look like we are reading the start of a function
2091 definition, then let the reader know about it so that
2092 we will do the right thing with `{'. */
ccc6cda3 2093 if (character == ')' && last_read_token == '(' && token_before_that == WORD)
726f6388 2094 {
ccc6cda3 2095 parser_state |= PST_ALLOWOPNBRC;
726f6388 2096#if defined (ALIAS)
ccc6cda3 2097 parser_state &= ~PST_ALEXPNEXT;
726f6388 2098#endif /* ALIAS */
ccc6cda3 2099 function_dstart = line_number;
726f6388
JA
2100 }
2101
ccc6cda3
JA
2102 /* case pattern lists may be preceded by an optional left paren. If
2103 we're not trying to parse a case pattern list, the left paren
2104 indicates a subshell. */
2105 if (character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
2106 parser_state |= PST_SUBSHELL;
2107 /*(*/
2108 else if ((parser_state & PST_CASEPAT) && character == ')')
2109 parser_state &= ~PST_CASEPAT;
2110 /*(*/
2111 else if ((parser_state & PST_SUBSHELL) && character == ')')
2112 parser_state &= ~PST_SUBSHELL;
726f6388
JA
2113
2114#if defined (PROCESS_SUBSTITUTION)
2115 /* Check for the constructs which introduce process substitution.
2116 Shells running in `posix mode' don't do process substitution. */
2117 if (posixly_correct ||
ccc6cda3 2118 ((character != '>' && character != '<') || peek_char != '('))
726f6388
JA
2119#endif /* PROCESS_SUBSTITUTION */
2120 return (character);
2121 }
2122
2123 /* Hack <&- (close stdin) case. */
ccc6cda3
JA
2124 if (character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
2125 return (character);
2126
726f6388
JA
2127 /* Okay, if we got this far, we have to read a word. Read one,
2128 and then check it against the known ones. */
ccc6cda3
JA
2129 result = read_token_word (character);
2130#if defined (ALIAS)
2131 if (result == RE_READ_TOKEN)
2132 goto re_read_token;
2133#endif
2134 return result;
2135}
726f6388 2136
ccc6cda3
JA
2137/* Match a $(...) or other grouping construct. This has to handle embedded
2138 quoted strings ('', ``, "") and nested constructs. It also must handle
2139 reprompting the user, if necessary, after reading a newline, and returning
2140 correct error values if it reads EOF. */
2141static char matched_pair_error;
2142static char *
2143parse_matched_pair (qc, open, close, lenp, flags)
2144 int qc; /* `"' if this construct is within double quotes */
2145 int open, close;
2146 int *lenp, flags;
2147{
2148 int count, ch, was_dollar;
2149 int pass_next_character, nestlen, start_lineno;
2150 char *ret, *nestret;
2151 int retind, retsize;
726f6388 2152
ccc6cda3
JA
2153 count = 1;
2154 pass_next_character = was_dollar = 0;
726f6388 2155
ccc6cda3
JA
2156 ret = xmalloc (retsize = 64);
2157 retind = 0;
726f6388 2158
ccc6cda3
JA
2159 start_lineno = line_number;
2160 while (count)
2161 {
2162 ch = shell_getc (qc != '\'' && pass_next_character == 0);
2163 if (ch == EOF)
2164 {
2165 free (ret);
2166 parser_error (start_lineno, "unexpected EOF while looking for matching `%c'", close);
2167 EOF_Reached = 1; /* XXX */
2168 return (&matched_pair_error);
2169 }
726f6388 2170
ccc6cda3
JA
2171 /* Possible reprompting. */
2172 if (ch == '\n' && interactive &&
2173 (bash_input.type == st_stdin || bash_input.type == st_stream))
2174 prompt_again ();
726f6388 2175
ccc6cda3
JA
2176 if (pass_next_character) /* last char was backslash */
2177 {
2178 pass_next_character = 0;
2179 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
2180 {
2181 if (retind > 0) retind--; /* swallow previously-added backslash */
2182 continue;
2183 }
726f6388 2184
ccc6cda3
JA
2185 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2186 if (ch == CTLESC || ch == CTLNUL)
2187 ret[retind++] = CTLESC;
2188 ret[retind++] = ch;
2189 continue;
2190 }
2191 else if (ch == CTLESC || ch == CTLNUL) /* special shell escapes */
2192 {
2193 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2194 ret[retind++] = CTLESC;
2195 ret[retind++] = ch;
2196 continue;
2197 }
2198 else if (ch == close) /* ending delimiter */
2199 count--;
2200 else if (ch == open) /* nested begin */
2201 count++;
726f6388 2202
ccc6cda3
JA
2203 /* Add this character. */
2204 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
2205 ret[retind++] = ch;
726f6388 2206
ccc6cda3
JA
2207 if (open == '\'') /* '' inside grouping construct */
2208 continue;
726f6388 2209
ccc6cda3
JA
2210 if (ch == '\\') /* backslashes */
2211 pass_next_character++;
726f6388 2212
ccc6cda3
JA
2213 if (open != close) /* a grouping construct */
2214 {
2215 if (shellquote (ch))
2216 {
2217 /* '', ``, or "" inside $(...) or other grouping construct. */
2218 push_delimiter (dstack, ch);
2219 nestret = parse_matched_pair (ch, ch, ch, &nestlen, 0);
2220 pop_delimiter (dstack);
2221 if (nestret == &matched_pair_error)
2222 {
2223 free (ret);
2224 return &matched_pair_error;
2225 }
2226 if (nestlen)
2227 {
2228 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2229 strcpy (ret + retind, nestret);
2230 retind += nestlen;
2231 }
2232 FREE (nestret);
2233 }
2234 }
2235 /* Parse an old-style command substitution within double quotes as a
2236 single word. */
2237 /* XXX - sh and ksh93 don't do this - XXX */
2238 else if (open == '"' && ch == '`')
2239 {
2240 nestret = parse_matched_pair (0, '`', '`', &nestlen, 0);
2241 if (nestret == &matched_pair_error)
2242 {
2243 free (ret);
2244 return &matched_pair_error;
2245 }
2246 if (nestlen)
2247 {
2248 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2249 strcpy (ret + retind, nestret);
2250 retind += nestlen;
2251 }
2252 FREE (nestret);
2253 }
2254 else if (was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
2255 /* check for $(), $[], or ${} inside quoted string. */
2256 {
2257 if (open == ch) /* undo previous increment */
2258 count--;
2259 if (ch == '(') /* ) */
2260 nestret = parse_matched_pair (0, '(', ')', &nestlen, 0);
2261 else if (ch == '{') /* } */
2262 nestret = parse_matched_pair (0, '{', '}', &nestlen, 0);
2263 else if (ch == '[') /* ] */
2264 nestret = parse_matched_pair (0, '[', ']', &nestlen, 0);
2265 if (nestret == &matched_pair_error)
2266 {
2267 free (ret);
2268 return &matched_pair_error;
2269 }
2270 if (nestlen)
2271 {
2272 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2273 strcpy (ret + retind, nestret);
2274 retind += nestlen;
2275 }
2276 FREE (nestret);
2277 }
2278 was_dollar = (ch == '$');
2279 }
726f6388 2280
ccc6cda3
JA
2281 ret[retind] = '\0';
2282 if (lenp)
2283 *lenp = retind;
2284 return ret;
2285}
726f6388 2286
ccc6cda3
JA
2287static int
2288read_token_word (character)
2289 int character;
2290{
2291 /* The value for YYLVAL when a WORD is read. */
2292 WORD_DESC *the_word;
726f6388 2293
ccc6cda3
JA
2294 /* Index into the token that we are building. */
2295 int token_index;
726f6388 2296
ccc6cda3
JA
2297 /* ALL_DIGITS becomes zero when we see a non-digit. */
2298 int all_digits;
726f6388 2299
ccc6cda3
JA
2300 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
2301 int dollar_present;
726f6388 2302
ccc6cda3
JA
2303 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
2304 int quoted;
726f6388 2305
ccc6cda3
JA
2306 /* Non-zero means to ignore the value of the next character, and just
2307 to add it no matter what. */
2308 int pass_next_character;
726f6388 2309
ccc6cda3
JA
2310 /* The current delimiting character. */
2311 int cd;
2312 int result, peek_char;
2313 char *ttok, *ttrans;
2314 int ttoklen, ttranslen;
726f6388 2315
ccc6cda3
JA
2316 if (token_buffer_size < TOKEN_DEFAULT_GROW_SIZE)
2317 {
2318 FREE (token);
2319 token = xmalloc (token_buffer_size = TOKEN_DEFAULT_GROW_SIZE);
2320 }
726f6388 2321
ccc6cda3
JA
2322 token_index = 0;
2323 all_digits = digit (character);
2324 dollar_present = quoted = pass_next_character = 0;
726f6388 2325
ccc6cda3
JA
2326 for (;;)
2327 {
2328 if (character == EOF)
2329 goto got_token;
726f6388 2330
ccc6cda3
JA
2331 if (pass_next_character)
2332 {
2333 pass_next_character = 0;
2334 goto got_character;
2335 }
726f6388 2336
ccc6cda3 2337 cd = current_delimiter (dstack);
726f6388 2338
ccc6cda3
JA
2339 /* Handle backslashes. Quote lots of things when not inside of
2340 double-quotes, quote some things inside of double-quotes. */
2341 if (character == '\\')
2342 {
2343 peek_char = shell_getc (0);
726f6388 2344
ccc6cda3
JA
2345 /* Backslash-newline is ignored in all cases except
2346 when quoted with single quotes. */
2347 if (peek_char == '\n')
2348 {
2349 character = '\n';
2350 goto next_character;
2351 }
2352 else
2353 {
2354 shell_ungetc (peek_char);
726f6388 2355
ccc6cda3
JA
2356 /* If the next character is to be quoted, note it now. */
2357 if (cd == 0 || cd == '`' ||
2358 (cd == '"' && member (peek_char, slashify_in_quotes)))
2359 pass_next_character++;
726f6388 2360
ccc6cda3
JA
2361 quoted = 1;
2362 goto got_character;
2363 }
2364 }
726f6388 2365
ccc6cda3
JA
2366#if defined (DPAREN_ARITHMETIC)
2367 /* Parse a ksh-style ((...)) expression. */
2368 if (parser_state & PST_DBLPAREN)
2369 {
2370 int exp_lineno;
726f6388 2371
ccc6cda3
JA
2372 /* If we've already consumed a right paren that should be part of
2373 the expression, push it back so the paren matching code won't
2374 return prematurely. */
2375 if (character == '(') /* ) */
726f6388 2376 shell_ungetc (character);
ccc6cda3
JA
2377 exp_lineno = line_number;
2378 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
2379 parser_state &= ~PST_DBLPAREN;
2380 if (ttok == &matched_pair_error)
2381 return -1;
2382 /* Check that the next character is the closing right paren. If
2383 not, this is a syntax error. ( */
2384 if (shell_getc (0) != ')')
2385 {
2386 FREE (ttok); /* ( */
2387 parser_error (exp_lineno, "missing closing `)' for arithmetic expression");
2388 return -1;
2389 }
2390 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
2391 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
2392 token[token_index++] = '"';
2393 if (character != '(') /* ) */
2394 token[token_index++] = character;
2395 strncpy (token + token_index, ttok, ttoklen - 1);
2396 token_index += ttoklen - 1;
2397 token[token_index++] = '"';
2398 FREE (ttok);
2399 dollar_present = all_digits = 0;
2400 quoted = 1;
2401 goto got_token;
2402 }
2403#endif /* DPAREN_ARITHMETIC */
726f6388 2404
ccc6cda3
JA
2405 /* Parse a matched pair of quote characters. */
2406 if (shellquote (character))
2407 {
2408 push_delimiter (dstack, character);
2409 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
2410 pop_delimiter (dstack);
2411 if (ttok == &matched_pair_error)
2412 return -1; /* Bail immediately. */
2413 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
2414 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
2415 token[token_index++] = character;
2416 strcpy (token + token_index, ttok);
2417 token_index += ttoklen;
2418 all_digits = 0;
2419 quoted = 1;
2420 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
2421 FREE (ttok);
2422 goto next_character;
2423 }
726f6388 2424
ccc6cda3
JA
2425 /* If the delimiter character is not single quote, parse some of
2426 the shell expansions that must be read as a single word. */
2427#if defined (PROCESS_SUBSTITUTION)
2428 if (character == '$' || character == '<' || character == '>')
2429#else
2430 if (character == '$')
2431#endif /* !PROCESS_SUBSTITUTION */
2432 {
2433 peek_char = shell_getc (1);
2434 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
2435 if (peek_char == '(' ||
2436 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
2437 {
2438 if (peek_char == '{') /* } */
2439 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, 0);
2440 else if (peek_char == '(') /* ) */
2441 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
2442 else
2443 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
2444 if (ttok == &matched_pair_error)
2445 return -1; /* Bail immediately. */
2446 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
2447 token_buffer_size,
2448 TOKEN_DEFAULT_GROW_SIZE);
2449 token[token_index++] = character;
2450 token[token_index++] = peek_char;
2451 strcpy (token + token_index, ttok);
2452 token_index += ttoklen;
2453 FREE (ttok);
2454 dollar_present = 1;
2455 all_digits = 0;
2456 goto next_character;
2457 }
2458 /* This handles $'...' and $"..." new-style quoted strings. */
2459 else if (character == '$' && (peek_char == '\'' || peek_char == '"'))
2460 {
2461 ttok = parse_matched_pair (peek_char, peek_char, peek_char, &ttoklen, 0);
2462 if (ttok == &matched_pair_error)
2463 return -1;
2464 if (peek_char == '\'')
2465 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
2466 else
2467 ttrans = localeexpand (ttok, 0, ttoklen - 1, &ttranslen);
2468 free (ttok);
2469 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
2470 token_buffer_size,
2471 TOKEN_DEFAULT_GROW_SIZE);
2472 token[token_index++] = peek_char;
2473 strcpy (token + token_index, ttrans);
2474 token_index += ttranslen;
2475 token[token_index++] = peek_char;
2476 FREE (ttrans);
2477 quoted = 1;
2478 all_digits = 0;
2479 goto next_character;
2480 }
2481 else
2482 shell_ungetc (peek_char);
2483 }
726f6388 2484
ccc6cda3
JA
2485#if defined (ARRAY_VARS)
2486 /* Identify possible compound array variable assignment. */
2487 else if (character == '=')
2488 {
2489 peek_char = shell_getc (1);
2490 if (peek_char == '(') /* ) */
2491 {
2492 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
2493 if (ttok == &matched_pair_error)
2494 return -1; /* Bail immediately. */
2495 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
2496 token_buffer_size,
2497 TOKEN_DEFAULT_GROW_SIZE);
2498 token[token_index++] = character;
2499 token[token_index++] = peek_char;
2500 strcpy (token + token_index, ttok);
2501 token_index += ttoklen;
2502 FREE (ttok);
2503 all_digits = 0;
2504 goto next_character;
2505 }
2506 else
2507 shell_ungetc (peek_char);
2508 }
2509#endif
726f6388 2510
ccc6cda3
JA
2511 /* When not parsing a multi-character word construct, shell meta-
2512 characters break words. */
2513 if (shellbreak (character))
2514 {
2515 shell_ungetc (character);
2516 goto got_token;
2517 }
726f6388 2518
ccc6cda3 2519 got_character:
726f6388 2520
ccc6cda3
JA
2521 all_digits &= digit (character);
2522 dollar_present |= character == '$';
726f6388 2523
ccc6cda3
JA
2524 if (character == CTLESC || character == CTLNUL)
2525 token[token_index++] = CTLESC;
726f6388 2526
ccc6cda3 2527 token[token_index++] = character;
726f6388 2528
ccc6cda3
JA
2529 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
2530 TOKEN_DEFAULT_GROW_SIZE);
726f6388 2531
ccc6cda3
JA
2532 next_character:
2533 if (character == '\n' && interactive &&
2534 (bash_input.type == st_stdin || bash_input.type == st_stream))
2535 prompt_again ();
726f6388 2536
ccc6cda3
JA
2537 /* We want to remove quoted newlines (that is, a \<newline> pair)
2538 unless we are within single quotes or pass_next_character is
2539 set (the shell equivalent of literal-next). */
2540 cd = current_delimiter (dstack);
2541 character = shell_getc (cd != '\'' && pass_next_character == 0);
2542 } /* end for (;;) */
726f6388 2543
ccc6cda3 2544got_token:
726f6388 2545
ccc6cda3 2546 token[token_index] = '\0';
726f6388 2547
ccc6cda3
JA
2548 /* Check to see what thing we should return. If the last_read_token
2549 is a `<', or a `&', or the character which ended this token is
2550 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
2551 Otherwise, it is just a word, and should be returned as such. */
2552 if (all_digits && (character == '<' || character == '>' ||
2553 last_read_token == LESS_AND ||
2554 last_read_token == GREATER_AND))
726f6388 2555 {
ccc6cda3
JA
2556 yylval.number = atoi (token);
2557 return (NUMBER);
726f6388
JA
2558 }
2559
ccc6cda3
JA
2560 /* Check for special case tokens. */
2561 result = special_case_tokens (token);
2562 if (result >= 0)
2563 return result;
726f6388
JA
2564
2565#if defined (ALIAS)
ccc6cda3
JA
2566 /* Posix.2 does not allow reserved words to be aliased, so check for all
2567 of them, including special cases, before expanding the current token
2568 as an alias. */
2569 if (posixly_correct)
2570 CHECK_FOR_RESERVED_WORD (token);
2571
2572 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
2573 inhibits alias expansion. */
2574 if (expand_aliases && quoted == 0)
2575 {
2576 result = alias_expand_token (token);
2577 if (result == RE_READ_TOKEN)
2578 return (RE_READ_TOKEN);
2579 else if (result == NO_EXPANSION)
2580 parser_state &= ~PST_ALEXPNEXT;
2581 }
726f6388 2582
ccc6cda3
JA
2583 /* If not in Posix.2 mode, check for reserved words after alias
2584 expansion. */
2585 if (posixly_correct == 0)
2586#endif
2587 CHECK_FOR_RESERVED_WORD (token);
2588
2589 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
2590 the_word->word = xmalloc (1 + token_index);
2591 the_word->flags = 0;
2592 strcpy (the_word->word, token);
2593 if (dollar_present)
2594 the_word->flags |= W_HASDOLLAR;
2595 if (quoted)
2596 the_word->flags |= W_QUOTED;
2597 /* A word is an assignment if it appears at the beginning of a
2598 simple command, or after another assignment word. This is
2599 context-dependent, so it cannot be handled in the grammar. */
2600 if (assignment (token))
2601 {
2602 the_word->flags |= W_ASSIGNMENT;
2603 /* Don't perform word splitting on assignment statements. */
2604 if (assignment_acceptable (last_read_token))
2605 the_word->flags |= W_NOSPLIT;
2606 }
726f6388 2607
ccc6cda3 2608 yylval.word = the_word;
726f6388 2609
ccc6cda3
JA
2610 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
2611 ? ASSIGNMENT_WORD : WORD;
726f6388 2612
ccc6cda3
JA
2613 if (last_read_token == FUNCTION)
2614 {
2615 parser_state |= PST_ALLOWOPNBRC;
2616 function_dstart = line_number;
2617 }
726f6388 2618
ccc6cda3
JA
2619 return (result);
2620}
726f6388 2621
ccc6cda3
JA
2622/* $'...' ANSI-C expand the portion of STRING between START and END and
2623 return the result. The result cannot be longer than the input string. */
2624static char *
2625ansiexpand (string, start, end, lenp)
2626 char *string;
2627 int start, end, *lenp;
2628{
2629 char *temp, *t;
2630 int len, tlen;
726f6388 2631
ccc6cda3
JA
2632 temp = xmalloc (end - start + 1);
2633 for (tlen = 0, len = start; len < end; )
2634 temp[tlen++] = string[len++];
2635 temp[tlen] = '\0';
726f6388 2636
ccc6cda3
JA
2637 if (*temp)
2638 {
2639 t = ansicstr (temp, tlen, (int *)NULL);
2640 free (temp);
2641 if (lenp)
2642 *lenp = strlen (t);
2643 return (t);
2644 }
2645 else
2646 {
2647 if (lenp)
2648 *lenp = 0;
2649 return (temp);
2650 }
2651}
726f6388 2652
ccc6cda3
JA
2653/* $"..." -- Translate the portion of STRING between START and END
2654 according to current locale using gettext (if available) and return
2655 the result. The caller will take care of leaving the quotes intact.
2656 The string will be left without the leading `$' by the caller.
2657 If translation is performed, the translated string will be double-quoted
2658 by the caller. The length of the translated string is returned in LENP,
2659 if non-null. */
2660static char *
2661localeexpand (string, start, end, lenp)
2662 char *string;
2663 int start, end, *lenp;
2664{
2665 int len, tlen;
2666 char *temp, *t;
726f6388 2667
ccc6cda3
JA
2668 temp = xmalloc (end - start + 1);
2669 for (tlen = 0, len = start; len < end; )
2670 temp[tlen++] = string[len++];
2671 temp[tlen] = '\0';
2672
2673 /* If we're just dumping translatable strings, don't do anything. */
2674 if (dump_translatable_strings)
2675 {
2676 printf ("\"%s\"\n", temp);
2677 if (lenp)
2678 *lenp = tlen;
2679 return (temp);
2680 }
2681 else if (*temp)
2682 {
2683 t = localetrans (temp, tlen, &len);
2684 free (temp);
2685 if (lenp)
2686 *lenp = len;
2687 return (t);
2688 }
2689 else
2690 {
2691 if (lenp)
2692 *lenp = 0;
2693 return (temp);
2694 }
726f6388
JA
2695}
2696
2697/* Return 1 if TOKEN is a token that after being read would allow
2698 a reserved word to be seen, else 0. */
2699static int
2700reserved_word_acceptable (token)
2701 int token;
2702{
726f6388
JA
2703 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
2704 token == '|' || token == '&' || token == '{' ||
726f6388
JA
2705 token == '}' || /* XXX */
2706 token == AND_AND ||
2707 token == BANG ||
ccc6cda3 2708 token == TIME || token == TIMEOPT ||
726f6388
JA
2709 token == DO ||
2710 token == ELIF ||
2711 token == ELSE ||
2712 token == FI ||
2713 token == IF ||
2714 token == OR_OR ||
2715 token == SEMI_SEMI ||
2716 token == THEN ||
2717 token == UNTIL ||
2718 token == WHILE ||
2719 token == DONE || /* XXX these two are experimental */
2720 token == ESAC ||
2721 token == 0)
2722 return (1);
2723 else
2724 return (0);
2725}
2726
2727/* Return the index of TOKEN in the alist of reserved words, or -1 if
2728 TOKEN is not a shell reserved word. */
2729int
2730find_reserved_word (token)
2731 char *token;
2732{
2733 int i;
ccc6cda3 2734 for (i = 0; word_token_alist[i].word; i++)
726f6388
JA
2735 if (STREQ (token, word_token_alist[i].word))
2736 return i;
2737 return -1;
2738}
2739
ccc6cda3 2740#if 0
726f6388
JA
2741#if defined (READLINE)
2742/* Called after each time readline is called. This insures that whatever
2743 the new prompt string is gets propagated to readline's local prompt
2744 variable. */
2745static void
2746reset_readline_prompt ()
2747{
ccc6cda3
JA
2748 char *temp_prompt;
2749
726f6388
JA
2750 if (prompt_string_pointer)
2751 {
ccc6cda3 2752 temp_prompt = (*prompt_string_pointer)
726f6388
JA
2753 ? decode_prompt_string (*prompt_string_pointer)
2754 : (char *)NULL;
2755
2756 if (temp_prompt == 0)
2757 {
2758 temp_prompt = xmalloc (1);
2759 temp_prompt[0] = '\0';
2760 }
2761
2762 FREE (current_readline_prompt);
726f6388
JA
2763 current_readline_prompt = temp_prompt;
2764 }
2765}
2766#endif /* READLINE */
ccc6cda3 2767#endif /* 0 */
726f6388
JA
2768
2769#if defined (HISTORY)
2770/* A list of tokens which can be followed by newlines, but not by
2771 semi-colons. When concatenating multiple lines of history, the
2772 newline separator for such tokens is replaced with a space. */
2773static int no_semi_successors[] = {
2774 '\n', '{', '(', ')', ';', '&', '|',
ccc6cda3 2775 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
726f6388
JA
2776 0
2777};
2778
2779/* If we are not within a delimited expression, try to be smart
2780 about which separators can be semi-colons and which must be
ccc6cda3
JA
2781 newlines. Returns the string that should be added into the
2782 history entry. */
726f6388
JA
2783char *
2784history_delimiting_chars ()
2785{
ccc6cda3
JA
2786 register int i;
2787
2788 if (dstack.delimiter_depth != 0)
2789 return ("\n");
2790
2791 /* First, handle some special cases. */
2792 /*(*/
2793 /* If we just read `()', assume it's a function definition, and don't
2794 add a semicolon. If the token before the `)' was not `(', and we're
2795 not in the midst of parsing a case statement, assume it's a
2796 parenthesized command and add the semicolon. */
2797 /*)(*/
2798 if (token_before_that == ')')
726f6388 2799 {
ccc6cda3
JA
2800 if (two_tokens_ago == '(') /*)*/ /* function def */
2801 return " ";
2802 /* This does not work for subshells inside case statement
2803 command lists. It's a suboptimal solution. */
2804 else if (parser_state & PST_CASESTMT) /* case statement pattern */
2805 return " ";
2806 else
2807 return "; "; /* (...) subshell */
2808 }
726f6388 2809
ccc6cda3
JA
2810 for (i = 0; no_semi_successors[i]; i++)
2811 {
2812 if (token_before_that == no_semi_successors[i])
2813 return (" ");
726f6388 2814 }
ccc6cda3
JA
2815
2816 return ("; ");
726f6388
JA
2817}
2818#endif /* HISTORY */
2819
2820/* Issue a prompt, or prepare to issue a prompt when the next character
2821 is read. */
2822static void
2823prompt_again ()
2824{
2825 char *temp_prompt;
2826
2827 if (!interactive) /* XXX */
2828 return;
2829
2830 ps1_prompt = get_string_value ("PS1");
2831 ps2_prompt = get_string_value ("PS2");
2832
2833 if (!prompt_string_pointer)
2834 prompt_string_pointer = &ps1_prompt;
2835
ccc6cda3 2836 temp_prompt = *prompt_string_pointer
726f6388
JA
2837 ? decode_prompt_string (*prompt_string_pointer)
2838 : (char *)NULL;
2839
2840 if (temp_prompt == 0)
2841 {
2842 temp_prompt = xmalloc (1);
2843 temp_prompt[0] = '\0';
2844 }
2845
2846 current_prompt_string = *prompt_string_pointer;
2847 prompt_string_pointer = &ps2_prompt;
2848
2849#if defined (READLINE)
2850 if (!no_line_editing)
2851 {
2852 FREE (current_readline_prompt);
2853 current_readline_prompt = temp_prompt;
2854 }
2855 else
2856#endif /* READLINE */
2857 {
2858 FREE (current_decoded_prompt);
2859 current_decoded_prompt = temp_prompt;
2860 }
2861}
2862
2863static void
2864print_prompt ()
2865{
2866 fprintf (stderr, "%s", current_decoded_prompt);
2867 fflush (stderr);
2868}
2869
2870/* Return a string which will be printed as a prompt. The string
2871 may contain special characters which are decoded as follows:
ccc6cda3
JA
2872
2873 \a bell (ascii 07)
2874 \e escape (ascii 033)
2875 \d the date in Day Mon Date format
2876 \h the hostname up to the first `.'
2877 \H the hostname
726f6388
JA
2878 \n CRLF
2879 \s the name of the shell
ccc6cda3
JA
2880 \t the time in 24-hour hh:mm:ss format
2881 \T the time in 12-hour hh:mm:ss format
2882 \@ the time in 12-hour am/pm format
2883 \v the version of bash (e.g., 2.00)
2884 \V the release of bash, version + patchlevel (e.g., 2.00.0)
726f6388 2885 \w the current working directory
ccc6cda3 2886 \W the last element of $PWD
726f6388 2887 \u your username
726f6388
JA
2888 \# the command number of this command
2889 \! the history number of this command
2890 \$ a $ or a # if you are root
ccc6cda3 2891 \nnn character code nnn in octal
726f6388 2892 \\ a backslash
ccc6cda3
JA
2893 \[ begin a sequence of non-printing chars
2894 \] end a sequence of non-printing chars
726f6388
JA
2895*/
2896#define PROMPT_GROWTH 50
2897char *
2898decode_prompt_string (string)
2899 char *string;
2900{
726f6388 2901 WORD_LIST *list;
ccc6cda3
JA
2902 char *result, *t;
2903 struct dstack save_dstack;
726f6388 2904#if defined (PROMPT_STRING_DECODE)
ccc6cda3
JA
2905 int result_size, result_index;
2906 int c, n;
2907 char *temp, octal_string[4];
2908 time_t the_time;
726f6388 2909
ccc6cda3
JA
2910 result = xmalloc (result_size = PROMPT_GROWTH);
2911 result[result_index = 0] = 0;
2912 temp = (char *)NULL;
726f6388
JA
2913
2914 while (c = *string++)
2915 {
2916 if (posixly_correct && c == '!')
2917 {
2918 if (*string == '!')
2919 {
2920 temp = savestring ("!");
2921 goto add_string;
2922 }
2923 else
2924 {
2925#if !defined (HISTORY)
2926 temp = savestring ("1");
2927#else /* HISTORY */
2928 temp = itos (history_number ());
2929#endif /* HISTORY */
2930 string--; /* add_string increments string again. */
2931 goto add_string;
2932 }
ccc6cda3 2933 }
726f6388
JA
2934 if (c == '\\')
2935 {
2936 c = *string;
2937
2938 switch (c)
2939 {
2940 case '0':
2941 case '1':
2942 case '2':
2943 case '3':
2944 case '4':
2945 case '5':
2946 case '6':
2947 case '7':
ccc6cda3
JA
2948 strncpy (octal_string, string, 3);
2949 octal_string[3] = '\0';
726f6388 2950
ccc6cda3
JA
2951 n = read_octal (octal_string);
2952 temp = xmalloc (3);
726f6388 2953
ccc6cda3
JA
2954 if (n == CTLESC || n == CTLNUL)
2955 {
2956 string += 3;
2957 temp[0] = CTLESC;
2958 temp[1] = n;
2959 temp[2] = '\0';
2960 }
2961 else if (n == -1)
2962 {
2963 temp[0] = '\\';
2964 temp[1] = '\0';
2965 }
2966 else
2967 {
2968 string += 3;
2969 temp[0] = n;
2970 temp[1] = '\0';
2971 }
726f6388 2972
ccc6cda3
JA
2973 c = 0;
2974 goto add_string;
726f6388 2975
726f6388
JA
2976 case 't':
2977 case 'd':
ccc6cda3
JA
2978 case 'T':
2979 case '@':
726f6388 2980 /* Make the current time/date into a string. */
ccc6cda3
JA
2981 the_time = time (0);
2982 temp = ctime (&the_time);
726f6388 2983
ccc6cda3
JA
2984 temp = (c != 'd') ? savestring (temp + 11) : savestring (temp);
2985 temp[(c != 'd') ? 8 : 10] = '\0';
726f6388 2986
ccc6cda3
JA
2987 /* quick and dirty conversion to 12-hour time */
2988 if (c == 'T' || c == '@')
2989 {
2990 if (c == '@')
2991 {
2992 temp[5] = 'a'; /* am/pm format */
2993 temp[6] = 'm';
2994 temp[7] = '\0';
2995 }
2996 c = temp[2];
2997 temp[2] = '\0';
2998 n = atoi (temp);
2999 temp[2] = c;
3000 n -= 12;
3001 if (n > 0)
3002 {
3003 temp[0] = (n / 10) + '0';
3004 temp[1] = (n % 10) + '0';
3005 }
3006 if (n >= 0 && temp[5] == 'a')
3007 temp[5] = 'p';
3008 }
3009 goto add_string;
726f6388
JA
3010
3011 case 'n':
ccc6cda3
JA
3012 temp = xmalloc (3);
3013 temp[0] = no_line_editing ? '\n' : '\r';
3014 temp[1] = no_line_editing ? '\0' : '\n';
3015 temp[2] = '\0';
726f6388
JA
3016 goto add_string;
3017
3018 case 's':
ccc6cda3
JA
3019 temp = base_pathname (shell_name);
3020 temp = savestring (temp);
3021 goto add_string;
3022
3023 case 'v':
3024 case 'V':
3025 temp = xmalloc (8);
3026 if (c == 'v')
3027 strcpy (temp, dist_version);
3028 else
3029 sprintf (temp, "%s.%d", dist_version, patch_level);
3030 goto add_string;
3031
726f6388
JA
3032 case 'w':
3033 case 'W':
3034 {
ccc6cda3
JA
3035 /* Use the value of PWD because it is much more efficient. */
3036 char t_string[PATH_MAX];
726f6388
JA
3037
3038 temp = get_string_value ("PWD");
3039
ccc6cda3
JA
3040 if (temp == 0)
3041 {
3042 if (getcwd (t_string, sizeof(t_string)) == 0)
3043 {
3044 t_string[0] = '.';
3045 t_string[1] = '\0';
3046 }
3047 }
726f6388
JA
3048 else
3049 strcpy (t_string, temp);
726f6388
JA
3050
3051 if (c == 'W')
3052 {
ccc6cda3
JA
3053 t = strrchr (t_string, '/');
3054 if (t && t != t_string)
3055 strcpy (t_string, t + 1);
726f6388
JA
3056 }
3057 else
ccc6cda3
JA
3058 strcpy (t_string, polite_directory_format (t_string));
3059
3060 /* If we're going to be expanding the prompt string later,
3061 quote the directory name. */
3062 if (promptvars || posixly_correct)
3063 temp = backslash_quote (t_string);
3064 else
3065 temp = savestring (t_string);
3066
726f6388
JA
3067 goto add_string;
3068 }
ccc6cda3 3069
726f6388 3070 case 'u':
ccc6cda3
JA
3071 temp = savestring (current_user.user_name);
3072 goto add_string;
726f6388
JA
3073
3074 case 'h':
ccc6cda3
JA
3075 case 'H':
3076 temp = savestring (current_host_name);
3077 if (c == 'h' && (t = (char *)strchr (temp, '.')))
3078 *t = '\0';
3079 goto add_string;
726f6388
JA
3080
3081 case '#':
ccc6cda3
JA
3082 temp = itos (current_command_number);
3083 goto add_string;
726f6388
JA
3084
3085 case '!':
726f6388 3086#if !defined (HISTORY)
ccc6cda3 3087 temp = savestring ("1");
726f6388 3088#else /* HISTORY */
ccc6cda3 3089 temp = itos (history_number ());
726f6388 3090#endif /* HISTORY */
ccc6cda3 3091 goto add_string;
726f6388
JA
3092
3093 case '$':
ccc6cda3
JA
3094 temp = xmalloc (2);
3095 temp[0] = current_user.euid == 0 ? '#' : '$';
3096 temp[1] = '\0';
726f6388
JA
3097 goto add_string;
3098
3099#if defined (READLINE)
3100 case '[':
3101 case ']':
ccc6cda3 3102 temp = xmalloc (3);
726f6388
JA
3103 temp[0] = '\001';
3104 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
3105 temp[2] = '\0';
3106 goto add_string;
ccc6cda3 3107#endif /* READLINE */
726f6388
JA
3108
3109 case '\\':
ccc6cda3
JA
3110 temp = xmalloc (2);
3111 temp[0] = c;
3112 temp[1] = '\0';
3113 goto add_string;
3114
3115 case 'a':
3116 case 'e':
3117 temp = xmalloc (2);
3118 temp[0] = (c == 'a') ? '\07' : '\033';
3119 temp[1] = '\0';
726f6388
JA
3120 goto add_string;
3121
3122 default:
ccc6cda3
JA
3123 temp = xmalloc (3);
3124 temp[0] = '\\';
726f6388 3125 temp[1] = c;
ccc6cda3 3126 temp[2] = '\0';
726f6388
JA
3127
3128 add_string:
3129 if (c)
3130 string++;
3131 result =
3132 sub_append_string (temp, result, &result_index, &result_size);
ccc6cda3 3133 temp = (char *)NULL; /* Freed in sub_append_string (). */
726f6388
JA
3134 result[result_index] = '\0';
3135 break;
3136 }
3137 }
3138 else
3139 {
ccc6cda3 3140 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
726f6388
JA
3141 result[result_index++] = c;
3142 result[result_index] = '\0';
3143 }
3144 }
3145#else /* !PROMPT_STRING_DECODE */
3146 result = savestring (string);
3147#endif /* !PROMPT_STRING_DECODE */
3148
ccc6cda3
JA
3149 /* Save the delimiter stack and point `dstack' to temp space so any
3150 command substitutions in the prompt string won't result in screwing
3151 up the parser's quoting state. */
3152 save_dstack = dstack;
3153 dstack = temp_dstack;
3154 dstack.delimiter_depth = 0;
3155
726f6388
JA
3156 /* Perform variable and parameter expansion and command substitution on
3157 the prompt string. */
ccc6cda3
JA
3158 if (promptvars || posixly_correct)
3159 {
3160 list = expand_string_unsplit (result, Q_DOUBLE_QUOTES);
3161 free (result);
3162 result = string_list (list);
3163 dispose_words (list);
3164 }
3165 else
3166 {
3167 t = dequote_string (result);
3168 free (result);
3169 result = t;
3170 }
3171
3172 dstack = save_dstack;
726f6388
JA
3173
3174 return (result);
3175}
3176
3177/* Report a syntax error, and restart the parser. Call here for fatal
3178 errors. */
ccc6cda3 3179int
726f6388
JA
3180yyerror ()
3181{
3182 report_syntax_error ((char *)NULL);
3183 reset_parser ();
ccc6cda3 3184 return (0);
726f6388
JA
3185}
3186
3187/* Report a syntax error with line numbers, etc.
3188 Call here for recoverable errors. If you have a message to print,
3189 then place it in MESSAGE, otherwise pass NULL and this will figure
3190 out an appropriate message for you. */
3191static void
3192report_syntax_error (message)
3193 char *message;
3194{
ccc6cda3
JA
3195 char *msg, *t;
3196 int token_end, i;
3197 char msg2[2];
3198
726f6388
JA
3199 if (message)
3200 {
ccc6cda3
JA
3201 parser_error (line_number, "%s", message);
3202 if (interactive && EOF_Reached)
3203 EOF_Reached = 0;
726f6388
JA
3204 last_command_exit_value = EX_USAGE;
3205 return;
3206 }
3207
ccc6cda3
JA
3208 /* If the line of input we're reading is not null, try to find the
3209 objectionable token. */
726f6388
JA
3210 if (shell_input_line && *shell_input_line)
3211 {
ccc6cda3
JA
3212 t = shell_input_line;
3213 i = shell_input_line_index;
3214 token_end = 0;
726f6388 3215
ccc6cda3 3216 if (i && t[i] == '\0')
726f6388
JA
3217 i--;
3218
ccc6cda3 3219 while (i && (whitespace (t[i]) || t[i] == '\n'))
726f6388
JA
3220 i--;
3221
3222 if (i)
3223 token_end = i + 1;
3224
ccc6cda3 3225 while (i && (member (t[i], " \n\t;|&") == 0))
726f6388
JA
3226 i--;
3227
ccc6cda3 3228 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
726f6388
JA
3229 i++;
3230
ccc6cda3
JA
3231 /* Print the offending token. */
3232 if (token_end || (i == 0 && token_end == 0))
726f6388 3233 {
ccc6cda3
JA
3234 if (token_end)
3235 {
3236 msg = xmalloc (1 + (token_end - i));
3237 strncpy (msg, t + i, token_end - i);
3238 msg[token_end - i] = '\0';
3239 }
3240 else /* one-character token */
3241 {
3242 msg2[0] = t[i];
3243 msg2[1] = '\0';
3244 msg = msg2;
3245 }
726f6388 3246
ccc6cda3 3247 parser_error (line_number, "syntax error near unexpected token `%s'", msg);
726f6388 3248
ccc6cda3
JA
3249 if (msg != msg2)
3250 free (msg);
726f6388
JA
3251 }
3252
ccc6cda3
JA
3253 /* If not interactive, print the line containing the error. */
3254 if (interactive == 0)
726f6388 3255 {
ccc6cda3
JA
3256 msg = savestring (shell_input_line);
3257 token_end = strlen (msg);
3258 while (token_end && msg[token_end - 1] == '\n')
3259 msg[--token_end] = '\0';
726f6388 3260
ccc6cda3
JA
3261 parser_error (line_number, "`%s'", msg);
3262 free (msg);
726f6388
JA
3263 }
3264 }
3265 else
3266 {
ccc6cda3
JA
3267 msg = EOF_Reached ? "syntax error: unexpected end of file" : "syntax error";
3268 parser_error (line_number, "%s", msg);
3269 /* When the shell is interactive, this file uses EOF_Reached
3270 only for error reporting. Other mechanisms are used to
3271 decide whether or not to exit. */
3272 if (interactive && EOF_Reached)
3273 EOF_Reached = 0;
726f6388
JA
3274 }
3275 last_command_exit_value = EX_USAGE;
3276}
3277
3278/* ??? Needed function. ??? We have to be able to discard the constructs
3279 created during parsing. In the case of error, we want to return
3280 allocated objects to the memory pool. In the case of no error, we want
3281 to throw away the information about where the allocated objects live.
3282 (dispose_command () will actually free the command. */
ccc6cda3 3283static void
726f6388
JA
3284discard_parser_constructs (error_p)
3285 int error_p;
3286{
3287}
ccc6cda3 3288
726f6388
JA
3289/* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
3290
3291/* A flag denoting whether or not ignoreeof is set. */
3292int ignoreeof = 0;
3293
3294/* The number of times that we have encountered an EOF character without
3295 another character intervening. When this gets above the limit, the
3296 shell terminates. */
3297int eof_encountered = 0;
3298
3299/* The limit for eof_encountered. */
3300int eof_encountered_limit = 10;
3301
3302/* If we have EOF as the only input unit, this user wants to leave
3303 the shell. If the shell is not interactive, then just leave.
3304 Otherwise, if ignoreeof is set, and we haven't done this the
3305 required number of times in a row, print a message. */
3306static void
3307handle_eof_input_unit ()
3308{
3309 if (interactive)
3310 {
3311 /* shell.c may use this to decide whether or not to write out the
3312 history, among other things. We use it only for error reporting
3313 in this file. */
3314 if (EOF_Reached)
3315 EOF_Reached = 0;
3316
3317 /* If the user wants to "ignore" eof, then let her do so, kind of. */
3318 if (ignoreeof)
3319 {
3320 if (eof_encountered < eof_encountered_limit)
3321 {
3322 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
3323 login_shell ? "logout" : "exit");
3324 eof_encountered++;
3325 /* Reset the prompt string to be $PS1. */
3326 prompt_string_pointer = (char **)NULL;
3327 prompt_again ();
3328 last_read_token = current_token = '\n';
3329 return;
ccc6cda3 3330 }
726f6388
JA
3331 }
3332
3333 /* In this case EOF should exit the shell. Do it now. */
3334 reset_parser ();
3335 exit_builtin ((WORD_LIST *)NULL);
3336 }
3337 else
3338 {
3339 /* We don't write history files, etc., for non-interactive shells. */
3340 EOF_Reached = 1;
3341 }
3342}