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