]> git.ipfire.org Git - thirdparty/bash.git/blame - parse.y
Bash-4.4 patch 19
[thirdparty/bash.git] / parse.y
CommitLineData
3185942a 1/* parse.y - Yacc grammar for bash. */
726f6388 2
a0c0a00f 3/* Copyright (C) 1989-2015 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
726f6388 11
3185942a
JA
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
726f6388 16
3185942a
JA
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
726f6388
JA
20
21%{
ccc6cda3
JA
22#include "config.h"
23
726f6388 24#include "bashtypes.h"
726f6388 25#include "bashansi.h"
ccc6cda3 26
28ef6c31
JA
27#include "filecntl.h"
28
ccc6cda3
JA
29#if defined (HAVE_UNISTD_H)
30# include <unistd.h>
31#endif
32
33#if defined (HAVE_LOCALE_H)
34# include <locale.h>
35#endif
36
37#include <stdio.h>
f73dda09 38#include "chartypes.h"
ccc6cda3
JA
39#include <signal.h>
40
41#include "memalloc.h"
42
b80f6443
JA
43#include "bashintl.h"
44
7117c2d2
JA
45#define NEED_STRFTIME_DECL /* used in externs.h */
46
726f6388 47#include "shell.h"
ac50fbac 48#include "typemax.h" /* SIZE_MAX if needed */
ccc6cda3 49#include "trap.h"
726f6388 50#include "flags.h"
ccc6cda3
JA
51#include "parser.h"
52#include "mailcheck.h"
f73dda09 53#include "test.h"
95732b49 54#include "builtins.h"
ccc6cda3
JA
55#include "builtins/common.h"
56#include "builtins/builtext.h"
726f6388 57
7117c2d2
JA
58#include "shmbutil.h"
59
726f6388 60#if defined (READLINE)
ccc6cda3 61# include "bashline.h"
726f6388
JA
62# include <readline/readline.h>
63#endif /* READLINE */
64
65#if defined (HISTORY)
66# include "bashhist.h"
67# include <readline/history.h>
68#endif /* HISTORY */
69
70#if defined (JOB_CONTROL)
71# include "jobs.h"
a0c0a00f
CR
72#else
73extern int cleanup_dead_jobs __P((void));
726f6388
JA
74#endif /* JOB_CONTROL */
75
76#if defined (ALIAS)
77# include "alias.h"
b80f6443
JA
78#else
79typedef void *alias_t;
726f6388
JA
80#endif /* ALIAS */
81
82#if defined (PROMPT_STRING_DECODE)
cce855bc
JA
83# ifndef _MINIX
84# include <sys/param.h>
85# endif
86# include <time.h>
7117c2d2
JA
87# if defined (TM_IN_SYS_TIME)
88# include <sys/types.h>
89# include <sys/time.h>
90# endif /* TM_IN_SYS_TIME */
cce855bc 91# include "maxpath.h"
726f6388
JA
92#endif /* PROMPT_STRING_DECODE */
93
ccc6cda3
JA
94#define RE_READ_TOKEN -99
95#define NO_EXPANSION -100
96
7117c2d2
JA
97#ifdef DEBUG
98# define YYDEBUG 1
99#else
100# define YYDEBUG 0
101#endif
102
103#if defined (HANDLE_MULTIBYTE)
104# define last_shell_getc_is_singlebyte \
105 ((shell_input_line_index > 1) \
106 ? shell_input_line_property[shell_input_line_index - 1] \
107 : 1)
108# define MBTEST(x) ((x) && last_shell_getc_is_singlebyte)
109#else
110# define last_shell_getc_is_singlebyte 1
111# define MBTEST(x) ((x))
112#endif
ccc6cda3 113
cce855bc 114#if defined (EXTENDED_GLOB)
cce855bc
JA
115extern int extended_glob;
116#endif
117
726f6388 118extern int eof_encountered;
ccc6cda3 119extern int no_line_editing, running_under_emacs;
726f6388 120extern int current_command_number;
3185942a 121extern int sourcelevel, parse_and_execute_level;
726f6388
JA
122extern int posixly_correct;
123extern int last_command_exit_value;
0001803f 124extern pid_t last_command_subst_pid;
726f6388 125extern char *shell_name, *current_host_name;
ccc6cda3
JA
126extern char *dist_version;
127extern int patch_level;
cce855bc 128extern int dump_translatable_strings, dump_po_strings;
f73dda09 129extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
a0c0a00f 130extern int here_doc_first_line;
726f6388
JA
131#if defined (BUFFERED_INPUT)
132extern int bash_input_fd_changed;
133#endif
134
bb70624e 135extern int errno;
726f6388
JA
136/* **************************************************************** */
137/* */
138/* "Forward" declarations */
139/* */
140/* **************************************************************** */
141
f73dda09
JA
142#ifdef DEBUG
143static void debug_parser __P((int));
144#endif
145
146static int yy_getc __P((void));
147static int yy_ungetc __P((int));
148
149#if defined (READLINE)
150static int yy_readline_get __P((void));
151static int yy_readline_unget __P((int));
152#endif
153
154static int yy_string_get __P((void));
155static int yy_string_unget __P((int));
3185942a 156static void rewind_input_string __P((void));
f73dda09
JA
157static int yy_stream_get __P((void));
158static int yy_stream_unget __P((int));
159
160static int shell_getc __P((int));
161static void shell_ungetc __P((int));
162static void discard_until __P((int));
163
164#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
165static void push_string __P((char *, int, alias_t *));
166static void pop_string __P((void));
167static void free_string_list __P((void));
168#endif
169
170static char *read_a_line __P((int));
171
f73dda09
JA
172static int reserved_word_acceptable __P((int));
173static int yylex __P((void));
90a39f32
CR
174
175static void push_heredoc __P((REDIRECT *));
176static char *mk_alexpansion __P((char *));
f73dda09
JA
177static int alias_expand_token __P((char *));
178static int time_command_acceptable __P((void));
179static int special_case_tokens __P((char *));
180static int read_token __P((int));
181static char *parse_matched_pair __P((int, int, int, int *, int));
3185942a 182static char *parse_comsub __P((int, int, int, int *, int));
7117c2d2
JA
183#if defined (ARRAY_VARS)
184static char *parse_compound_assignment __P((int *));
185#endif
f73dda09 186#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
7117c2d2 187static int parse_dparen __P((int));
b80f6443 188static int parse_arith_cmd __P((char **, int));
f73dda09 189#endif
cce855bc 190#if defined (COND_COMMAND)
7117c2d2 191static void cond_error __P((void));
f73dda09
JA
192static COND_COM *cond_expr __P((void));
193static COND_COM *cond_or __P((void));
194static COND_COM *cond_and __P((void));
195static COND_COM *cond_term __P((void));
196static int cond_skip_newlines __P((void));
197static COMMAND *parse_cond_command __P((void));
cce855bc 198#endif
7117c2d2
JA
199#if defined (ARRAY_VARS)
200static int token_is_assignment __P((char *, int));
201static int token_is_ident __P((char *, int));
202#endif
f73dda09
JA
203static int read_token_word __P((int));
204static void discard_parser_constructs __P((int));
726f6388 205
7117c2d2
JA
206static char *error_token_from_token __P((int));
207static char *error_token_from_text __P((void));
208static void print_offending_line __P((void));
f73dda09 209static void report_syntax_error __P((char *));
7117c2d2 210
f73dda09
JA
211static void handle_eof_input_unit __P((void));
212static void prompt_again __P((void));
d166f048 213#if 0
f73dda09 214static void reset_readline_prompt __P((void));
d166f048 215#endif
f73dda09 216static void print_prompt __P((void));
726f6388 217
7117c2d2
JA
218#if defined (HANDLE_MULTIBYTE)
219static void set_line_mbstate __P((void));
220static char *shell_input_line_property = NULL;
221#else
222# define set_line_mbstate()
223#endif
224
f73dda09 225extern int yyerror __P((const char *));
d166f048 226
7117c2d2
JA
227#ifdef DEBUG
228extern int yydebug;
229#endif
230
ccc6cda3
JA
231/* Default prompt strings */
232char *primary_prompt = PPROMPT;
233char *secondary_prompt = SPROMPT;
234
726f6388
JA
235/* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
236char *ps1_prompt, *ps2_prompt;
237
a0c0a00f
CR
238/* Displayed after reading a command but before executing it in an interactive shell */
239char *ps0_prompt;
240
726f6388
JA
241/* Handle on the current prompt string. Indirectly points through
242 ps1_ or ps2_prompt. */
243char **prompt_string_pointer = (char **)NULL;
244char *current_prompt_string;
245
ccc6cda3
JA
246/* Non-zero means we expand aliases in commands. */
247int expand_aliases = 0;
248
249/* If non-zero, the decoded prompt string undergoes parameter and
250 variable substitution, command substitution, arithmetic substitution,
251 string expansion, process substitution, and quote removal in
252 decode_prompt_string. */
253int promptvars = 1;
254
b80f6443
JA
255/* If non-zero, $'...' and $"..." are expanded when they appear within
256 a ${...} expansion, even when the expansion appears within double
257 quotes. */
258int extended_quote = 1;
259
726f6388 260/* The number of lines read from input while creating the current command. */
ccc6cda3 261int current_command_line_count;
726f6388 262
495aee44
CR
263/* The number of lines in a command saved while we run parse_and_execute */
264int saved_command_line_count;
265
3185942a
JA
266/* The token that currently denotes the end of parse. */
267int shell_eof_token;
268
269/* The token currently being read. */
270int current_token;
271
0001803f
CR
272/* The current parser state. */
273int parser_state;
274
726f6388
JA
275/* Variables to manage the task of reading here documents, because we need to
276 defer the reading until after a complete command has been collected. */
90a39f32 277static REDIRECT *redir_stack[HEREDOC_MAX];
ccc6cda3 278int need_here_doc;
726f6388
JA
279
280/* Where shell input comes from. History expansion is performed on each
281 line when the shell is interactive. */
282static char *shell_input_line = (char *)NULL;
ac50fbac
CR
283static size_t shell_input_line_index;
284static size_t shell_input_line_size; /* Amount allocated for shell_input_line. */
285static size_t shell_input_line_len; /* strlen (shell_input_line) */
726f6388
JA
286
287/* Either zero or EOF. */
ccc6cda3
JA
288static int shell_input_line_terminator;
289
290/* The line number in a script on which a function definition starts. */
291static int function_dstart;
292
293/* The line number in a script on which a function body starts. */
294static int function_bstart;
726f6388 295
bb70624e
JA
296/* The line number in a script at which an arithmetic for command starts. */
297static int arith_for_lineno;
298
0001803f
CR
299/* The decoded prompt string. Used if READLINE is not defined or if
300 editing is turned off. Analogous to current_readline_prompt. */
301static char *current_decoded_prompt;
3185942a
JA
302
303/* The last read token, or NULL. read_token () uses this for context
304 checking. */
305static int last_read_token;
306
307/* The token read prior to last_read_token. */
308static int token_before_that;
309
310/* The token read prior to token_before_that. */
311static int two_tokens_ago;
312
0001803f
CR
313static int global_extglob;
314
b80f6443
JA
315/* The line number in a script where the word in a `case WORD', `select WORD'
316 or `for WORD' begins. This is a nested command maximum, since the array
317 index is decremented after a case, select, or for command is parsed. */
318#define MAX_CASE_NEST 128
90a39f32 319static int word_lineno[MAX_CASE_NEST+1];
b80f6443
JA
320static int word_top = -1;
321
322/* If non-zero, it is the token that we want read_token to return
323 regardless of what text is (or isn't) present to be read. This
324 is reset by read_token. If token_to_read == WORD or
325 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
326static int token_to_read;
327static WORD_DESC *word_desc_to_read;
328
0001803f 329static REDIRECTEE source;
726f6388
JA
330static REDIRECTEE redir;
331%}
332
333%union {
334 WORD_DESC *word; /* the word that we read. */
335 int number; /* the number that we read. */
336 WORD_LIST *word_list;
337 COMMAND *command;
338 REDIRECT *redirect;
339 ELEMENT element;
340 PATTERN_LIST *pattern;
341}
342
343/* Reserved words. Members of the first group are only recognized
344 in the case that they are preceded by a list_terminator. Members
cce855bc
JA
345 of the second group are for [[...]] commands. Members of the
346 third group are recognized only under special circumstances. */
3185942a 347%token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION COPROC
cce855bc 348%token COND_START COND_END COND_ERROR
495aee44 349%token IN BANG TIME TIMEOPT TIMEIGN
726f6388
JA
350
351/* More general tokens. yylex () knows how to make these. */
0001803f 352%token <word> WORD ASSIGNMENT_WORD REDIR_WORD
726f6388 353%token <number> NUMBER
bb70624e 354%token <word_list> ARITH_CMD ARITH_FOR_EXPRS
cce855bc 355%token <command> COND_CMD
7117c2d2 356%token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND LESS_LESS_LESS
3185942a
JA
357%token GREATER_AND SEMI_SEMI SEMI_AND SEMI_SEMI_AND
358%token LESS_LESS_MINUS AND_GREATER AND_GREATER_GREATER LESS_GREATER
359%token GREATER_BAR BAR_AND
726f6388
JA
360
361/* The types that the various syntactical units return. */
362
ccc6cda3
JA
363%type <command> inputunit command pipeline pipeline_command
364%type <command> list list0 list1 compound_list simple_list simple_list1
365%type <command> simple_command shell_command
366%type <command> for_command select_command case_command group_command
cce855bc
JA
367%type <command> arith_command
368%type <command> cond_command
bb70624e 369%type <command> arith_for_command
3185942a 370%type <command> coproc
28ef6c31 371%type <command> function_def function_body if_command elif_clause subshell
ccc6cda3 372%type <redirect> redirection redirection_list
726f6388 373%type <element> simple_command_element
ccc6cda3
JA
374%type <word_list> word_list pattern
375%type <pattern> pattern_list case_clause_sequence case_clause
376%type <number> timespec
b80f6443 377%type <number> list_terminator
726f6388
JA
378
379%start inputunit
380
381%left '&' ';' '\n' yacc_EOF
382%left AND_AND OR_OR
3185942a 383%right '|' BAR_AND
726f6388
JA
384%%
385
7117c2d2 386inputunit: simple_list simple_list_terminator
726f6388
JA
387 {
388 /* Case of regular command. Discard the error
389 safety net,and return the command just parsed. */
390 global_command = $1;
391 eof_encountered = 0;
7117c2d2 392 /* discard_parser_constructs (0); */
3185942a
JA
393 if (parser_state & PST_CMDSUBST)
394 parser_state |= PST_EOFTOKEN;
726f6388
JA
395 YYACCEPT;
396 }
397 | '\n'
398 {
399 /* Case of regular command, but not a very
400 interesting one. Return a NULL command. */
401 global_command = (COMMAND *)NULL;
3185942a
JA
402 if (parser_state & PST_CMDSUBST)
403 parser_state |= PST_EOFTOKEN;
726f6388
JA
404 YYACCEPT;
405 }
ccc6cda3 406 | error '\n'
726f6388
JA
407 {
408 /* Error during parsing. Return NULL command. */
409 global_command = (COMMAND *)NULL;
410 eof_encountered = 0;
7117c2d2 411 /* discard_parser_constructs (1); */
3185942a 412 if (interactive && parse_and_execute_level == 0)
726f6388
JA
413 {
414 YYACCEPT;
415 }
416 else
417 {
418 YYABORT;
419 }
420 }
421 | yacc_EOF
422 {
ccc6cda3 423 /* Case of EOF seen by itself. Do ignoreeof or
726f6388
JA
424 not. */
425 global_command = (COMMAND *)NULL;
426 handle_eof_input_unit ();
427 YYACCEPT;
428 }
429 ;
430
ccc6cda3
JA
431word_list: WORD
432 { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
433 | word_list WORD
726f6388
JA
434 { $$ = make_word_list ($2, $1); }
435 ;
436
437redirection: '>' WORD
438 {
0001803f 439 source.dest = 1;
726f6388 440 redir.filename = $2;
0001803f 441 $$ = make_redirection (source, r_output_direction, redir, 0);
726f6388
JA
442 }
443 | '<' WORD
444 {
0001803f 445 source.dest = 0;
726f6388 446 redir.filename = $2;
0001803f 447 $$ = make_redirection (source, r_input_direction, redir, 0);
726f6388
JA
448 }
449 | NUMBER '>' WORD
450 {
0001803f 451 source.dest = $1;
726f6388 452 redir.filename = $3;
0001803f 453 $$ = make_redirection (source, r_output_direction, redir, 0);
726f6388
JA
454 }
455 | NUMBER '<' WORD
456 {
0001803f
CR
457 source.dest = $1;
458 redir.filename = $3;
459 $$ = make_redirection (source, r_input_direction, redir, 0);
460 }
461 | REDIR_WORD '>' WORD
462 {
463 source.filename = $1;
726f6388 464 redir.filename = $3;
0001803f
CR
465 $$ = make_redirection (source, r_output_direction, redir, REDIR_VARASSIGN);
466 }
467 | REDIR_WORD '<' WORD
468 {
469 source.filename = $1;
470 redir.filename = $3;
471 $$ = make_redirection (source, r_input_direction, redir, REDIR_VARASSIGN);
726f6388
JA
472 }
473 | GREATER_GREATER WORD
474 {
0001803f 475 source.dest = 1;
726f6388 476 redir.filename = $2;
0001803f 477 $$ = make_redirection (source, r_appending_to, redir, 0);
726f6388
JA
478 }
479 | NUMBER GREATER_GREATER WORD
480 {
0001803f
CR
481 source.dest = $1;
482 redir.filename = $3;
483 $$ = make_redirection (source, r_appending_to, redir, 0);
484 }
485 | REDIR_WORD GREATER_GREATER WORD
486 {
487 source.filename = $1;
488 redir.filename = $3;
489 $$ = make_redirection (source, r_appending_to, redir, REDIR_VARASSIGN);
490 }
491 | GREATER_BAR WORD
492 {
493 source.dest = 1;
494 redir.filename = $2;
495 $$ = make_redirection (source, r_output_force, redir, 0);
496 }
497 | NUMBER GREATER_BAR WORD
498 {
499 source.dest = $1;
500 redir.filename = $3;
501 $$ = make_redirection (source, r_output_force, redir, 0);
502 }
503 | REDIR_WORD GREATER_BAR WORD
504 {
505 source.filename = $1;
506 redir.filename = $3;
507 $$ = make_redirection (source, r_output_force, redir, REDIR_VARASSIGN);
508 }
509 | LESS_GREATER WORD
510 {
511 source.dest = 0;
512 redir.filename = $2;
513 $$ = make_redirection (source, r_input_output, redir, 0);
514 }
515 | NUMBER LESS_GREATER WORD
516 {
517 source.dest = $1;
726f6388 518 redir.filename = $3;
0001803f
CR
519 $$ = make_redirection (source, r_input_output, redir, 0);
520 }
521 | REDIR_WORD LESS_GREATER WORD
522 {
523 source.filename = $1;
524 redir.filename = $3;
525 $$ = make_redirection (source, r_input_output, redir, REDIR_VARASSIGN);
726f6388
JA
526 }
527 | LESS_LESS WORD
528 {
0001803f 529 source.dest = 0;
726f6388 530 redir.filename = $2;
0001803f 531 $$ = make_redirection (source, r_reading_until, redir, 0);
90a39f32 532 push_heredoc ($$);
726f6388
JA
533 }
534 | NUMBER LESS_LESS WORD
535 {
0001803f
CR
536 source.dest = $1;
537 redir.filename = $3;
538 $$ = make_redirection (source, r_reading_until, redir, 0);
90a39f32 539 push_heredoc ($$);
0001803f
CR
540 }
541 | REDIR_WORD LESS_LESS WORD
542 {
543 source.filename = $1;
726f6388 544 redir.filename = $3;
0001803f 545 $$ = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN);
90a39f32 546 push_heredoc ($$);
0001803f
CR
547 }
548 | LESS_LESS_MINUS WORD
549 {
550 source.dest = 0;
551 redir.filename = $2;
552 $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
90a39f32 553 push_heredoc ($$);
0001803f
CR
554 }
555 | NUMBER LESS_LESS_MINUS WORD
556 {
557 source.dest = $1;
558 redir.filename = $3;
559 $$ = make_redirection (source, r_deblank_reading_until, redir, 0);
90a39f32 560 push_heredoc ($$);
0001803f
CR
561 }
562 | REDIR_WORD LESS_LESS_MINUS WORD
563 {
564 source.filename = $1;
565 redir.filename = $3;
566 $$ = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN);
90a39f32 567 push_heredoc ($$);
726f6388 568 }
7117c2d2
JA
569 | LESS_LESS_LESS WORD
570 {
0001803f 571 source.dest = 0;
7117c2d2 572 redir.filename = $2;
0001803f 573 $$ = make_redirection (source, r_reading_string, redir, 0);
7117c2d2
JA
574 }
575 | NUMBER LESS_LESS_LESS WORD
576 {
0001803f 577 source.dest = $1;
7117c2d2 578 redir.filename = $3;
0001803f
CR
579 $$ = make_redirection (source, r_reading_string, redir, 0);
580 }
581 | REDIR_WORD LESS_LESS_LESS WORD
582 {
583 source.filename = $1;
584 redir.filename = $3;
585 $$ = make_redirection (source, r_reading_string, redir, REDIR_VARASSIGN);
7117c2d2 586 }
726f6388
JA
587 | LESS_AND NUMBER
588 {
0001803f 589 source.dest = 0;
726f6388 590 redir.dest = $2;
0001803f 591 $$ = make_redirection (source, r_duplicating_input, redir, 0);
726f6388
JA
592 }
593 | NUMBER LESS_AND NUMBER
594 {
0001803f
CR
595 source.dest = $1;
596 redir.dest = $3;
597 $$ = make_redirection (source, r_duplicating_input, redir, 0);
598 }
599 | REDIR_WORD LESS_AND NUMBER
600 {
601 source.filename = $1;
726f6388 602 redir.dest = $3;
0001803f 603 $$ = make_redirection (source, r_duplicating_input, redir, REDIR_VARASSIGN);
726f6388
JA
604 }
605 | GREATER_AND NUMBER
606 {
0001803f 607 source.dest = 1;
726f6388 608 redir.dest = $2;
0001803f 609 $$ = make_redirection (source, r_duplicating_output, redir, 0);
726f6388
JA
610 }
611 | NUMBER GREATER_AND NUMBER
612 {
0001803f 613 source.dest = $1;
726f6388 614 redir.dest = $3;
0001803f
CR
615 $$ = make_redirection (source, r_duplicating_output, redir, 0);
616 }
617 | REDIR_WORD GREATER_AND NUMBER
618 {
619 source.filename = $1;
620 redir.dest = $3;
621 $$ = make_redirection (source, r_duplicating_output, redir, REDIR_VARASSIGN);
726f6388
JA
622 }
623 | LESS_AND WORD
624 {
0001803f 625 source.dest = 0;
726f6388 626 redir.filename = $2;
0001803f 627 $$ = make_redirection (source, r_duplicating_input_word, redir, 0);
726f6388
JA
628 }
629 | NUMBER LESS_AND WORD
630 {
0001803f
CR
631 source.dest = $1;
632 redir.filename = $3;
633 $$ = make_redirection (source, r_duplicating_input_word, redir, 0);
634 }
635 | REDIR_WORD LESS_AND WORD
636 {
637 source.filename = $1;
726f6388 638 redir.filename = $3;
0001803f 639 $$ = make_redirection (source, r_duplicating_input_word, redir, REDIR_VARASSIGN);
726f6388
JA
640 }
641 | GREATER_AND WORD
642 {
0001803f 643 source.dest = 1;
726f6388 644 redir.filename = $2;
0001803f 645 $$ = make_redirection (source, r_duplicating_output_word, redir, 0);
726f6388
JA
646 }
647 | NUMBER GREATER_AND WORD
648 {
0001803f 649 source.dest = $1;
726f6388 650 redir.filename = $3;
0001803f 651 $$ = make_redirection (source, r_duplicating_output_word, redir, 0);
726f6388 652 }
0001803f 653 | REDIR_WORD GREATER_AND WORD
726f6388 654 {
0001803f 655 source.filename = $1;
726f6388 656 redir.filename = $3;
0001803f 657 $$ = make_redirection (source, r_duplicating_output_word, redir, REDIR_VARASSIGN);
726f6388
JA
658 }
659 | GREATER_AND '-'
660 {
0001803f 661 source.dest = 1;
f73dda09 662 redir.dest = 0;
0001803f 663 $$ = make_redirection (source, r_close_this, redir, 0);
726f6388
JA
664 }
665 | NUMBER GREATER_AND '-'
666 {
0001803f 667 source.dest = $1;
f73dda09 668 redir.dest = 0;
0001803f 669 $$ = make_redirection (source, r_close_this, redir, 0);
726f6388 670 }
0001803f 671 | REDIR_WORD GREATER_AND '-'
726f6388 672 {
0001803f 673 source.filename = $1;
f73dda09 674 redir.dest = 0;
0001803f 675 $$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
726f6388 676 }
0001803f 677 | LESS_AND '-'
726f6388 678 {
0001803f 679 source.dest = 0;
f73dda09 680 redir.dest = 0;
0001803f 681 $$ = make_redirection (source, r_close_this, redir, 0);
726f6388 682 }
0001803f 683 | NUMBER LESS_AND '-'
3185942a 684 {
0001803f
CR
685 source.dest = $1;
686 redir.dest = 0;
687 $$ = make_redirection (source, r_close_this, redir, 0);
3185942a 688 }
0001803f 689 | REDIR_WORD LESS_AND '-'
726f6388 690 {
0001803f
CR
691 source.filename = $1;
692 redir.dest = 0;
693 $$ = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN);
726f6388 694 }
0001803f 695 | AND_GREATER WORD
726f6388 696 {
0001803f 697 source.dest = 1;
726f6388 698 redir.filename = $2;
0001803f 699 $$ = make_redirection (source, r_err_and_out, redir, 0);
ccc6cda3 700 }
0001803f 701 | AND_GREATER_GREATER WORD
726f6388 702 {
0001803f 703 source.dest = 1;
726f6388 704 redir.filename = $2;
0001803f 705 $$ = make_redirection (source, r_append_err_and_out, redir, 0);
726f6388
JA
706 }
707 ;
708
709simple_command_element: WORD
710 { $$.word = $1; $$.redirect = 0; }
711 | ASSIGNMENT_WORD
712 { $$.word = $1; $$.redirect = 0; }
713 | redirection
714 { $$.redirect = $1; $$.word = 0; }
715 ;
716
ccc6cda3 717redirection_list: redirection
726f6388
JA
718 {
719 $$ = $1;
720 }
ccc6cda3
JA
721 | redirection_list redirection
722 {
723 register REDIRECT *t;
726f6388 724
ccc6cda3
JA
725 for (t = $1; t->next; t = t->next)
726 ;
727 t->next = $2;
726f6388
JA
728 $$ = $1;
729 }
730 ;
731
732simple_command: simple_command_element
733 { $$ = make_simple_command ($1, (COMMAND *)NULL); }
734 | simple_command simple_command_element
735 { $$ = make_simple_command ($2, $1); }
736 ;
737
738command: simple_command
739 { $$ = clean_simple_command ($1); }
740 | shell_command
741 { $$ = $1; }
ccc6cda3 742 | shell_command redirection_list
726f6388 743 {
ccc6cda3
JA
744 COMMAND *tc;
745
746 tc = $1;
ccc6cda3 747 if (tc->redirects)
726f6388
JA
748 {
749 register REDIRECT *t;
ccc6cda3 750 for (t = tc->redirects; t->next; t = t->next)
726f6388
JA
751 ;
752 t->next = $2;
753 }
754 else
ccc6cda3 755 tc->redirects = $2;
726f6388
JA
756 $$ = $1;
757 }
28ef6c31
JA
758 | function_def
759 { $$ = $1; }
3185942a
JA
760 | coproc
761 { $$ = $1; }
726f6388
JA
762 ;
763
ccc6cda3
JA
764shell_command: for_command
765 { $$ = $1; }
766 | case_command
767 { $$ = $1; }
768 | WHILE compound_list DO compound_list DONE
726f6388 769 { $$ = make_while_command ($2, $4); }
ccc6cda3 770 | UNTIL compound_list DO compound_list DONE
726f6388
JA
771 { $$ = make_until_command ($2, $4); }
772 | select_command
773 { $$ = $1; }
774 | if_command
775 { $$ = $1; }
776 | subshell
777 { $$ = $1; }
778 | group_command
779 { $$ = $1; }
cce855bc
JA
780 | arith_command
781 { $$ = $1; }
782 | cond_command
783 { $$ = $1; }
bb70624e
JA
784 | arith_for_command
785 { $$ = $1; }
726f6388
JA
786 ;
787
d166f048 788for_command: FOR WORD newline_list DO compound_list DONE
b80f6443
JA
789 {
790 $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
791 if (word_top > 0) word_top--;
792 }
d166f048 793 | FOR WORD newline_list '{' compound_list '}'
b80f6443
JA
794 {
795 $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
796 if (word_top > 0) word_top--;
797 }
d166f048 798 | FOR WORD ';' newline_list DO compound_list DONE
b80f6443
JA
799 {
800 $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
801 if (word_top > 0) word_top--;
802 }
d166f048 803 | FOR WORD ';' newline_list '{' compound_list '}'
b80f6443
JA
804 {
805 $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
806 if (word_top > 0) word_top--;
807 }
d166f048 808 | FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE
b80f6443
JA
809 {
810 $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
811 if (word_top > 0) word_top--;
812 }
d166f048 813 | FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'
b80f6443
JA
814 {
815 $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
816 if (word_top > 0) word_top--;
817 }
f73dda09 818 | FOR WORD newline_list IN list_terminator newline_list DO compound_list DONE
b80f6443
JA
819 {
820 $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
821 if (word_top > 0) word_top--;
822 }
f73dda09 823 | FOR WORD newline_list IN list_terminator newline_list '{' compound_list '}'
b80f6443
JA
824 {
825 $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
826 if (word_top > 0) word_top--;
827 }
ccc6cda3
JA
828 ;
829
bb70624e 830arith_for_command: FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE
b80f6443
JA
831 {
832 $$ = make_arith_for_command ($2, $6, arith_for_lineno);
833 if (word_top > 0) word_top--;
834 }
bb70624e 835 | FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}'
b80f6443
JA
836 {
837 $$ = make_arith_for_command ($2, $6, arith_for_lineno);
838 if (word_top > 0) word_top--;
839 }
28ef6c31 840 | FOR ARITH_FOR_EXPRS DO compound_list DONE
b80f6443
JA
841 {
842 $$ = make_arith_for_command ($2, $4, arith_for_lineno);
843 if (word_top > 0) word_top--;
844 }
28ef6c31 845 | FOR ARITH_FOR_EXPRS '{' compound_list '}'
b80f6443
JA
846 {
847 $$ = make_arith_for_command ($2, $4, arith_for_lineno);
848 if (word_top > 0) word_top--;
849 }
bb70624e 850 ;
28ef6c31 851
ccc6cda3 852select_command: SELECT WORD newline_list DO list DONE
726f6388 853 {
b80f6443
JA
854 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
855 if (word_top > 0) word_top--;
726f6388 856 }
ccc6cda3 857 | SELECT WORD newline_list '{' list '}'
726f6388 858 {
b80f6443
JA
859 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
860 if (word_top > 0) word_top--;
726f6388 861 }
ccc6cda3 862 | SELECT WORD ';' newline_list DO list DONE
726f6388 863 {
b80f6443
JA
864 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
865 if (word_top > 0) word_top--;
726f6388 866 }
ccc6cda3 867 | SELECT WORD ';' newline_list '{' list '}'
726f6388 868 {
b80f6443
JA
869 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
870 if (word_top > 0) word_top--;
726f6388 871 }
ccc6cda3 872 | SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE
726f6388 873 {
b80f6443
JA
874 $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
875 if (word_top > 0) word_top--;
726f6388 876 }
ccc6cda3 877 | SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}'
726f6388 878 {
b80f6443
JA
879 $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
880 if (word_top > 0) word_top--;
726f6388
JA
881 }
882 ;
883
ccc6cda3 884case_command: CASE WORD newline_list IN newline_list ESAC
b80f6443
JA
885 {
886 $$ = make_case_command ($2, (PATTERN_LIST *)NULL, word_lineno[word_top]);
887 if (word_top > 0) word_top--;
888 }
ccc6cda3 889 | CASE WORD newline_list IN case_clause_sequence newline_list ESAC
b80f6443
JA
890 {
891 $$ = make_case_command ($2, $5, word_lineno[word_top]);
892 if (word_top > 0) word_top--;
893 }
ccc6cda3 894 | CASE WORD newline_list IN case_clause ESAC
b80f6443
JA
895 {
896 $$ = make_case_command ($2, $5, word_lineno[word_top]);
897 if (word_top > 0) word_top--;
898 }
ccc6cda3 899 ;
726f6388 900
28ef6c31 901function_def: WORD '(' ')' newline_list function_body
ccc6cda3 902 { $$ = make_function_def ($1, $5, function_dstart, function_bstart); }
726f6388 903
28ef6c31 904 | FUNCTION WORD '(' ')' newline_list function_body
ccc6cda3 905 { $$ = make_function_def ($2, $6, function_dstart, function_bstart); }
726f6388 906
28ef6c31 907 | FUNCTION WORD newline_list function_body
ccc6cda3 908 { $$ = make_function_def ($2, $4, function_dstart, function_bstart); }
726f6388
JA
909 ;
910
28ef6c31
JA
911function_body: shell_command
912 { $$ = $1; }
913 | shell_command redirection_list
914 {
915 COMMAND *tc;
916
917 tc = $1;
918 /* According to Posix.2 3.9.5, redirections
919 specified after the body of a function should
920 be attached to the function and performed when
921 the function is executed, not as part of the
922 function definition command. */
923 /* XXX - I don't think it matters, but we might
924 want to change this in the future to avoid
925 problems differentiating between a function
926 definition with a redirection and a function
927 definition containing a single command with a
928 redirection. The two are semantically equivalent,
929 though -- the only difference is in how the
930 command printing code displays the redirections. */
931 if (tc->redirects)
932 {
933 register REDIRECT *t;
934 for (t = tc->redirects; t->next; t = t->next)
935 ;
936 t->next = $2;
937 }
938 else
939 tc->redirects = $2;
940 $$ = $1;
941 }
942 ;
943
ccc6cda3 944subshell: '(' compound_list ')'
bb70624e
JA
945 {
946 $$ = make_subshell_command ($2);
947 $$->flags |= CMD_WANT_SUBSHELL;
948 }
726f6388 949 ;
ccc6cda3 950
3185942a
JA
951coproc: COPROC shell_command
952 {
953 $$ = make_coproc_command ("COPROC", $2);
954 $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
955 }
956 | COPROC shell_command redirection_list
957 {
958 COMMAND *tc;
959
960 tc = $2;
961 if (tc->redirects)
962 {
963 register REDIRECT *t;
964 for (t = tc->redirects; t->next; t = t->next)
965 ;
966 t->next = $3;
967 }
968 else
969 tc->redirects = $3;
970 $$ = make_coproc_command ("COPROC", $2);
971 $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
972 }
973 | COPROC WORD shell_command
974 {
975 $$ = make_coproc_command ($2->word, $3);
976 $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
977 }
978 | COPROC WORD shell_command redirection_list
979 {
980 COMMAND *tc;
981
982 tc = $3;
983 if (tc->redirects)
984 {
985 register REDIRECT *t;
986 for (t = tc->redirects; t->next; t = t->next)
987 ;
988 t->next = $4;
989 }
990 else
991 tc->redirects = $4;
992 $$ = make_coproc_command ($2->word, $3);
993 $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
994 }
995 | COPROC simple_command
996 {
997 $$ = make_coproc_command ("COPROC", clean_simple_command ($2));
998 $$->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
999 }
1000 ;
1001
ccc6cda3 1002if_command: IF compound_list THEN compound_list FI
726f6388 1003 { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
ccc6cda3 1004 | IF compound_list THEN compound_list ELSE compound_list FI
726f6388 1005 { $$ = make_if_command ($2, $4, $6); }
ccc6cda3 1006 | IF compound_list THEN compound_list elif_clause FI
726f6388
JA
1007 { $$ = make_if_command ($2, $4, $5); }
1008 ;
1009
1010
28ef6c31 1011group_command: '{' compound_list '}'
726f6388
JA
1012 { $$ = make_group_command ($2); }
1013 ;
1014
cce855bc
JA
1015arith_command: ARITH_CMD
1016 { $$ = make_arith_command ($1); }
1017 ;
1018
1019cond_command: COND_START COND_CMD COND_END
1020 { $$ = $2; }
1021 ;
1022
ccc6cda3 1023elif_clause: ELIF compound_list THEN compound_list
726f6388 1024 { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
ccc6cda3 1025 | ELIF compound_list THEN compound_list ELSE compound_list
726f6388 1026 { $$ = make_if_command ($2, $4, $6); }
ccc6cda3 1027 | ELIF compound_list THEN compound_list elif_clause
726f6388
JA
1028 { $$ = make_if_command ($2, $4, $5); }
1029 ;
1030
ccc6cda3
JA
1031case_clause: pattern_list
1032 | case_clause_sequence pattern_list
726f6388
JA
1033 { $2->next = $1; $$ = $2; }
1034 ;
1035
ccc6cda3 1036pattern_list: newline_list pattern ')' compound_list
726f6388 1037 { $$ = make_pattern_list ($2, $4); }
ccc6cda3 1038 | newline_list pattern ')' newline_list
726f6388 1039 { $$ = make_pattern_list ($2, (COMMAND *)NULL); }
ccc6cda3 1040 | newline_list '(' pattern ')' compound_list
726f6388 1041 { $$ = make_pattern_list ($3, $5); }
ccc6cda3 1042 | newline_list '(' pattern ')' newline_list
726f6388
JA
1043 { $$ = make_pattern_list ($3, (COMMAND *)NULL); }
1044 ;
1045
ccc6cda3 1046case_clause_sequence: pattern_list SEMI_SEMI
3185942a 1047 { $$ = $1; }
ccc6cda3 1048 | case_clause_sequence pattern_list SEMI_SEMI
726f6388 1049 { $2->next = $1; $$ = $2; }
3185942a
JA
1050 | pattern_list SEMI_AND
1051 { $1->flags |= CASEPAT_FALLTHROUGH; $$ = $1; }
1052 | case_clause_sequence pattern_list SEMI_AND
1053 { $2->flags |= CASEPAT_FALLTHROUGH; $2->next = $1; $$ = $2; }
1054 | pattern_list SEMI_SEMI_AND
1055 { $1->flags |= CASEPAT_TESTNEXT; $$ = $1; }
1056 | case_clause_sequence pattern_list SEMI_SEMI_AND
1057 { $2->flags |= CASEPAT_TESTNEXT; $2->next = $1; $$ = $2; }
726f6388
JA
1058 ;
1059
726f6388
JA
1060pattern: WORD
1061 { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
1062 | pattern '|' WORD
1063 { $$ = make_word_list ($3, $1); }
1064 ;
1065
1066/* A list allows leading or trailing newlines and
1067 newlines as operators (equivalent to semicolons).
1068 It must end with a newline or semicolon.
1069 Lists are used within commands such as if, for, while. */
1070
ccc6cda3 1071list: newline_list list0
726f6388
JA
1072 {
1073 $$ = $2;
1074 if (need_here_doc)
1075 gather_here_documents ();
1076 }
1077 ;
1078
ccc6cda3
JA
1079compound_list: list
1080 | newline_list list1
1081 {
1082 $$ = $2;
1083 }
1084 ;
1085
1086list0: list1 '\n' newline_list
1087 | list1 '&' newline_list
726f6388
JA
1088 {
1089 if ($1->type == cm_connection)
1090 $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
1091 else
1092 $$ = command_connect ($1, (COMMAND *)NULL, '&');
1093 }
ccc6cda3 1094 | list1 ';' newline_list
726f6388
JA
1095
1096 ;
1097
ccc6cda3 1098list1: list1 AND_AND newline_list list1
726f6388 1099 { $$ = command_connect ($1, $4, AND_AND); }
ccc6cda3 1100 | list1 OR_OR newline_list list1
726f6388 1101 { $$ = command_connect ($1, $4, OR_OR); }
ccc6cda3 1102 | list1 '&' newline_list list1
726f6388
JA
1103 {
1104 if ($1->type == cm_connection)
1105 $$ = connect_async_list ($1, $4, '&');
1106 else
1107 $$ = command_connect ($1, $4, '&');
1108 }
ccc6cda3 1109 | list1 ';' newline_list list1
726f6388 1110 { $$ = command_connect ($1, $4, ';'); }
ccc6cda3 1111 | list1 '\n' newline_list list1
726f6388 1112 { $$ = command_connect ($1, $4, ';'); }
ccc6cda3 1113 | pipeline_command
726f6388 1114 { $$ = $1; }
726f6388
JA
1115 ;
1116
7117c2d2
JA
1117simple_list_terminator: '\n'
1118 | yacc_EOF
1119 ;
1120
726f6388 1121list_terminator:'\n'
b80f6443 1122 { $$ = '\n'; }
726f6388 1123 | ';'
b80f6443 1124 { $$ = ';'; }
726f6388 1125 | yacc_EOF
b80f6443 1126 { $$ = yacc_EOF; }
726f6388
JA
1127 ;
1128
ccc6cda3
JA
1129newline_list:
1130 | newline_list '\n'
726f6388
JA
1131 ;
1132
1133/* A simple_list is a list that contains no significant newlines
1134 and no leading or trailing newlines. Newlines are allowed
1135 only following operators, where they are not significant.
1136
1137 This is what an inputunit consists of. */
1138
1139simple_list: simple_list1
1140 {
1141 $$ = $1;
1142 if (need_here_doc)
1143 gather_here_documents ();
3185942a
JA
1144 if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1145 {
1146 global_command = $1;
1147 eof_encountered = 0;
1148 rewind_input_string ();
1149 YYACCEPT;
1150 }
726f6388
JA
1151 }
1152 | simple_list1 '&'
1153 {
1154 if ($1->type == cm_connection)
1155 $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
1156 else
1157 $$ = command_connect ($1, (COMMAND *)NULL, '&');
1158 if (need_here_doc)
1159 gather_here_documents ();
3185942a
JA
1160 if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1161 {
1162 global_command = $1;
1163 eof_encountered = 0;
1164 rewind_input_string ();
1165 YYACCEPT;
1166 }
726f6388
JA
1167 }
1168 | simple_list1 ';'
1169 {
1170 $$ = $1;
1171 if (need_here_doc)
1172 gather_here_documents ();
3185942a
JA
1173 if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token)
1174 {
1175 global_command = $1;
1176 eof_encountered = 0;
1177 rewind_input_string ();
1178 YYACCEPT;
1179 }
726f6388
JA
1180 }
1181 ;
1182
ccc6cda3 1183simple_list1: simple_list1 AND_AND newline_list simple_list1
726f6388 1184 { $$ = command_connect ($1, $4, AND_AND); }
ccc6cda3 1185 | simple_list1 OR_OR newline_list simple_list1
726f6388
JA
1186 { $$ = command_connect ($1, $4, OR_OR); }
1187 | simple_list1 '&' simple_list1
1188 {
1189 if ($1->type == cm_connection)
1190 $$ = connect_async_list ($1, $3, '&');
1191 else
1192 $$ = command_connect ($1, $3, '&');
1193 }
1194 | simple_list1 ';' simple_list1
1195 { $$ = command_connect ($1, $3, ';'); }
ccc6cda3
JA
1196
1197 | pipeline_command
1198 { $$ = $1; }
1199 ;
1200
1201pipeline_command: pipeline
495aee44
CR
1202 { $$ = $1; }
1203 | BANG pipeline_command
726f6388 1204 {
95732b49 1205 if ($2)
495aee44 1206 $2->flags ^= CMD_INVERT_RETURN; /* toggle */
726f6388
JA
1207 $$ = $2;
1208 }
495aee44 1209 | timespec pipeline_command
ccc6cda3 1210 {
95732b49
JA
1211 if ($2)
1212 $2->flags |= $1;
ccc6cda3
JA
1213 $$ = $2;
1214 }
b80f6443
JA
1215 | timespec list_terminator
1216 {
1217 ELEMENT x;
1218
1219 /* Boy, this is unclean. `time' by itself can
1220 time a null command. We cheat and push a
1221 newline back if the list_terminator was a newline
1222 to avoid the double-newline problem (one to
1223 terminate this, one to terminate the command) */
1224 x.word = 0;
1225 x.redirect = 0;
1226 $$ = make_simple_command (x, (COMMAND *)NULL);
1227 $$->flags |= $1;
1228 /* XXX - let's cheat and push a newline back */
1229 if ($2 == '\n')
1230 token_to_read = '\n';
a0c0a00f
CR
1231 else if ($2 == ';')
1232 token_to_read = ';';
b80f6443 1233 }
495aee44
CR
1234 | BANG list_terminator
1235 {
1236 ELEMENT x;
1237
1238 /* This is just as unclean. Posix says that `!'
1239 by itself should be equivalent to `false'.
1240 We cheat and push a
1241 newline back if the list_terminator was a newline
1242 to avoid the double-newline problem (one to
1243 terminate this, one to terminate the command) */
1244 x.word = 0;
1245 x.redirect = 0;
1246 $$ = make_simple_command (x, (COMMAND *)NULL);
1247 $$->flags |= CMD_INVERT_RETURN;
1248 /* XXX - let's cheat and push a newline back */
1249 if ($2 == '\n')
1250 token_to_read = '\n';
a0c0a00f
CR
1251 if ($2 == ';')
1252 token_to_read = ';';
495aee44 1253 }
726f6388
JA
1254 ;
1255
3185942a 1256pipeline: pipeline '|' newline_list pipeline
726f6388 1257 { $$ = command_connect ($1, $4, '|'); }
3185942a
JA
1258 | pipeline BAR_AND newline_list pipeline
1259 {
1260 /* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */
1261 COMMAND *tc;
0001803f 1262 REDIRECTEE rd, sd;
3185942a
JA
1263 REDIRECT *r;
1264
89a92869 1265 tc = $1->type == cm_simple ? (COMMAND *)$1->value.Simple : $1;
0001803f 1266 sd.dest = 2;
3185942a 1267 rd.dest = 1;
0001803f 1268 r = make_redirection (sd, r_duplicating_output, rd, 0);
3185942a
JA
1269 if (tc->redirects)
1270 {
1271 register REDIRECT *t;
1272 for (t = tc->redirects; t->next; t = t->next)
1273 ;
1274 t->next = r;
1275 }
1276 else
1277 tc->redirects = r;
1278
1279 $$ = command_connect ($1, $4, '|');
1280 }
726f6388
JA
1281 | command
1282 { $$ = $1; }
1283 ;
ccc6cda3
JA
1284
1285timespec: TIME
1286 { $$ = CMD_TIME_PIPELINE; }
1287 | TIME TIMEOPT
1288 { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
495aee44
CR
1289 | TIME TIMEOPT TIMEIGN
1290 { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
ccc6cda3 1291 ;
726f6388
JA
1292%%
1293
1294/* Initial size to allocate for tokens, and the
1295 amount to grow them by. */
d166f048 1296#define TOKEN_DEFAULT_INITIAL_SIZE 496
726f6388
JA
1297#define TOKEN_DEFAULT_GROW_SIZE 512
1298
b80f6443
JA
1299/* Should we call prompt_again? */
1300#define SHOULD_PROMPT() \
1301 (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
1302
1303#if defined (ALIAS)
1304# define expanding_alias() (pushed_string_list && pushed_string_list->expander)
1305#else
1306# define expanding_alias() 0
1307#endif
1308
726f6388
JA
1309/* Global var is non-zero when end of file has been reached. */
1310int EOF_Reached = 0;
1311
f73dda09
JA
1312#ifdef DEBUG
1313static void
ccc6cda3
JA
1314debug_parser (i)
1315 int i;
1316{
1317#if YYDEBUG != 0
1318 yydebug = i;
1319#endif
1320}
f73dda09 1321#endif
ccc6cda3 1322
726f6388
JA
1323/* yy_getc () returns the next available character from input or EOF.
1324 yy_ungetc (c) makes `c' the next character to read.
1325 init_yy_io (get, unget, type, location) makes the function GET the
1326 installed function for getting the next character, makes UNGET the
1327 installed function for un-getting a character, sets the type of stream
1328 (either string or file) from TYPE, and makes LOCATION point to where
1329 the input is coming from. */
1330
1331/* Unconditionally returns end-of-file. */
ccc6cda3 1332int
726f6388
JA
1333return_EOF ()
1334{
1335 return (EOF);
1336}
1337
1338/* Variable containing the current get and unget functions.
1339 See ./input.h for a clearer description. */
1340BASH_INPUT bash_input;
1341
ccc6cda3
JA
1342/* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
1343 is non-null, avoiding a memory leak. */
726f6388
JA
1344void
1345initialize_bash_input ()
1346{
ccc6cda3
JA
1347 bash_input.type = st_none;
1348 FREE (bash_input.name);
726f6388
JA
1349 bash_input.name = (char *)NULL;
1350 bash_input.location.file = (FILE *)NULL;
1351 bash_input.location.string = (char *)NULL;
f73dda09
JA
1352 bash_input.getter = (sh_cget_func_t *)NULL;
1353 bash_input.ungetter = (sh_cunget_func_t *)NULL;
726f6388
JA
1354}
1355
1356/* Set the contents of the current bash input stream from
1357 GET, UNGET, TYPE, NAME, and LOCATION. */
1358void
1359init_yy_io (get, unget, type, name, location)
f73dda09
JA
1360 sh_cget_func_t *get;
1361 sh_cunget_func_t *unget;
d166f048 1362 enum stream_type type;
f73dda09 1363 const char *name;
726f6388
JA
1364 INPUT_STREAM location;
1365{
1366 bash_input.type = type;
1367 FREE (bash_input.name);
ccc6cda3 1368 bash_input.name = name ? savestring (name) : (char *)NULL;
726f6388 1369
ccc6cda3 1370 /* XXX */
726f6388
JA
1371#if defined (CRAY)
1372 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
1373#else
1374 bash_input.location = location;
1375#endif
1376 bash_input.getter = get;
1377 bash_input.ungetter = unget;
1378}
1379
7117c2d2
JA
1380char *
1381yy_input_name ()
1382{
1383 return (bash_input.name ? bash_input.name : "stdin");
1384}
1385
726f6388 1386/* Call this to get the next character of input. */
f73dda09 1387static int
726f6388
JA
1388yy_getc ()
1389{
1390 return (*(bash_input.getter)) ();
1391}
1392
1393/* Call this to unget C. That is, to make C the next character
1394 to be read. */
f73dda09 1395static int
726f6388
JA
1396yy_ungetc (c)
1397 int c;
1398{
1399 return (*(bash_input.ungetter)) (c);
1400}
1401
1402#if defined (BUFFERED_INPUT)
f73dda09 1403#ifdef INCLUDE_UNUSED
726f6388
JA
1404int
1405input_file_descriptor ()
1406{
1407 switch (bash_input.type)
1408 {
1409 case st_stream:
1410 return (fileno (bash_input.location.file));
1411 case st_bstream:
1412 return (bash_input.location.buffered_fd);
ccc6cda3 1413 case st_stdin:
726f6388
JA
1414 default:
1415 return (fileno (stdin));
1416 }
1417}
f73dda09 1418#endif
726f6388
JA
1419#endif /* BUFFERED_INPUT */
1420
1421/* **************************************************************** */
1422/* */
1423/* Let input be read from readline (). */
1424/* */
1425/* **************************************************************** */
1426
1427#if defined (READLINE)
1428char *current_readline_prompt = (char *)NULL;
1429char *current_readline_line = (char *)NULL;
1430int current_readline_line_index = 0;
1431
1432static int
1433yy_readline_get ()
1434{
ccc6cda3 1435 SigHandler *old_sigint;
f73dda09
JA
1436 int line_len;
1437 unsigned char c;
ccc6cda3 1438
a0c0a00f 1439 if (current_readline_line == 0)
726f6388 1440 {
a0c0a00f 1441 if (bash_readline_initialized == 0)
726f6388
JA
1442 initialize_readline ();
1443
1444#if defined (JOB_CONTROL)
1445 if (job_control)
28ef6c31 1446 give_terminal_to (shell_pgrp, 0);
726f6388
JA
1447#endif /* JOB_CONTROL */
1448
a0c0a00f 1449 old_sigint = IMPOSSIBLE_TRAP_HANDLER;
726f6388
JA
1450 if (signal_is_ignored (SIGINT) == 0)
1451 {
ac50fbac 1452 /* interrupt_immediately++; */
495aee44 1453 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
726f6388
JA
1454 }
1455
ccc6cda3
JA
1456 current_readline_line = readline (current_readline_prompt ?
1457 current_readline_prompt : "");
726f6388 1458
ac50fbac 1459 CHECK_TERMSIG;
495aee44 1460 if (signal_is_ignored (SIGINT) == 0)
726f6388 1461 {
ac50fbac 1462 /* interrupt_immediately--; */
495aee44
CR
1463 if (old_sigint != IMPOSSIBLE_TRAP_HANDLER)
1464 set_signal_handler (SIGINT, old_sigint);
726f6388
JA
1465 }
1466
ccc6cda3
JA
1467#if 0
1468 /* Reset the prompt to the decoded value of prompt_string_pointer. */
726f6388 1469 reset_readline_prompt ();
ccc6cda3 1470#endif
726f6388 1471
ccc6cda3 1472 if (current_readline_line == 0)
726f6388
JA
1473 return (EOF);
1474
ccc6cda3 1475 current_readline_line_index = 0;
726f6388 1476 line_len = strlen (current_readline_line);
ccc6cda3 1477
f73dda09 1478 current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len);
726f6388
JA
1479 current_readline_line[line_len++] = '\n';
1480 current_readline_line[line_len] = '\0';
1481 }
1482
ccc6cda3 1483 if (current_readline_line[current_readline_line_index] == 0)
726f6388
JA
1484 {
1485 free (current_readline_line);
1486 current_readline_line = (char *)NULL;
1487 return (yy_readline_get ());
1488 }
1489 else
1490 {
f73dda09 1491 c = current_readline_line[current_readline_line_index++];
726f6388
JA
1492 return (c);
1493 }
1494}
1495
1496static int
1497yy_readline_unget (c)
ccc6cda3 1498 int c;
726f6388
JA
1499{
1500 if (current_readline_line_index && current_readline_line)
1501 current_readline_line[--current_readline_line_index] = c;
1502 return (c);
1503}
1504
ccc6cda3 1505void
726f6388
JA
1506with_input_from_stdin ()
1507{
1508 INPUT_STREAM location;
1509
1510 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
1511 {
1512 location.string = current_readline_line;
1513 init_yy_io (yy_readline_get, yy_readline_unget,
1514 st_stdin, "readline stdin", location);
1515 }
1516}
1517
1518#else /* !READLINE */
1519
1520void
1521with_input_from_stdin ()
1522{
1523 with_input_from_stream (stdin, "stdin");
1524}
1525#endif /* !READLINE */
1526
1527/* **************************************************************** */
1528/* */
1529/* Let input come from STRING. STRING is zero terminated. */
1530/* */
1531/* **************************************************************** */
1532
1533static int
1534yy_string_get ()
1535{
ccc6cda3 1536 register char *string;
f73dda09 1537 register unsigned char c;
726f6388
JA
1538
1539 string = bash_input.location.string;
726f6388
JA
1540
1541 /* If the string doesn't exist, or is empty, EOF found. */
1542 if (string && *string)
1543 {
f73dda09 1544 c = *string++;
726f6388 1545 bash_input.location.string = string;
f73dda09 1546 return (c);
726f6388 1547 }
f73dda09
JA
1548 else
1549 return (EOF);
726f6388
JA
1550}
1551
1552static int
1553yy_string_unget (c)
1554 int c;
1555{
1556 *(--bash_input.location.string) = c;
1557 return (c);
1558}
1559
1560void
1561with_input_from_string (string, name)
f73dda09
JA
1562 char *string;
1563 const char *name;
726f6388
JA
1564{
1565 INPUT_STREAM location;
1566
1567 location.string = string;
726f6388
JA
1568 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
1569}
1570
3185942a
JA
1571/* Count the number of characters we've consumed from bash_input.location.string
1572 and read into shell_input_line, but have not returned from shell_getc.
1573 That is the true input location. Rewind bash_input.location.string by
1574 that number of characters, so it points to the last character actually
1575 consumed by the parser. */
1576static void
1577rewind_input_string ()
1578{
1579 int xchars;
1580
1581 /* number of unconsumed characters in the input -- XXX need to take newlines
1582 into account, e.g., $(...\n) */
1583 xchars = shell_input_line_len - shell_input_line_index;
1584 if (bash_input.location.string[-1] == '\n')
1585 xchars++;
1586
1587 /* XXX - how to reflect bash_input.location.string back to string passed to
1588 parse_and_execute or xparse_dolparen? xparse_dolparen needs to know how
1589 far into the string we parsed. parse_and_execute knows where bash_input.
1590 location.string is, and how far from orig_string that is -- that's the
1591 number of characters the command consumed. */
1592
1593 /* bash_input.location.string - xchars should be where we parsed to */
1594 /* need to do more validation on xchars value for sanity -- test cases. */
1595 bash_input.location.string -= xchars;
1596}
1597
726f6388
JA
1598/* **************************************************************** */
1599/* */
1600/* Let input come from STREAM. */
1601/* */
1602/* **************************************************************** */
1603
bb70624e
JA
1604/* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
1605 define, and just use getc/ungetc if it was defined, but since bash
1606 installs its signal handlers without the SA_RESTART flag, some signals
1607 (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
1608 the read to be restarted. We need to restart it ourselves. */
1609
726f6388
JA
1610static int
1611yy_stream_get ()
1612{
bb70624e 1613 int result;
726f6388 1614
bb70624e 1615 result = EOF;
726f6388 1616 if (bash_input.location.file)
95732b49 1617 {
ac50fbac 1618#if 0
95732b49 1619 if (interactive)
ac50fbac
CR
1620 interrupt_immediately++;
1621#endif
1622
1623 /* XXX - don't need terminate_immediately; getc_with_restart checks
1624 for terminating signals itself if read returns < 0 */
95732b49 1625 result = getc_with_restart (bash_input.location.file);
ac50fbac
CR
1626
1627#if 0
95732b49 1628 if (interactive)
ac50fbac
CR
1629 interrupt_immediately--;
1630#endif
95732b49 1631 }
726f6388
JA
1632 return (result);
1633}
1634
1635static int
1636yy_stream_unget (c)
1637 int c;
1638{
726f6388 1639 return (ungetc_with_restart (c, bash_input.location.file));
726f6388
JA
1640}
1641
1642void
1643with_input_from_stream (stream, name)
1644 FILE *stream;
f73dda09 1645 const char *name;
726f6388
JA
1646{
1647 INPUT_STREAM location;
1648
1649 location.file = stream;
1650 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
1651}
1652
1653typedef struct stream_saver {
1654 struct stream_saver *next;
1655 BASH_INPUT bash_input;
1656 int line;
1657#if defined (BUFFERED_INPUT)
1658 BUFFERED_STREAM *bstream;
1659#endif /* BUFFERED_INPUT */
1660} STREAM_SAVER;
1661
1662/* The globally known line number. */
1663int line_number = 0;
1664
495aee44
CR
1665/* The line number offset set by assigning to LINENO. Not currently used. */
1666int line_number_base = 0;
1667
cce855bc
JA
1668#if defined (COND_COMMAND)
1669static int cond_lineno;
1670static int cond_token;
1671#endif
1672
726f6388
JA
1673STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
1674
ccc6cda3
JA
1675void
1676push_stream (reset_lineno)
1677 int reset_lineno;
726f6388
JA
1678{
1679 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1680
1681 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1682
1683#if defined (BUFFERED_INPUT)
1684 saver->bstream = (BUFFERED_STREAM *)NULL;
1685 /* If we have a buffered stream, clear out buffers[fd]. */
1686 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
cce855bc
JA
1687 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
1688 (BUFFERED_STREAM *)NULL);
726f6388
JA
1689#endif /* BUFFERED_INPUT */
1690
1691 saver->line = line_number;
1692 bash_input.name = (char *)NULL;
1693 saver->next = stream_list;
1694 stream_list = saver;
ccc6cda3
JA
1695 EOF_Reached = 0;
1696 if (reset_lineno)
1697 line_number = 0;
726f6388
JA
1698}
1699
ccc6cda3 1700void
726f6388
JA
1701pop_stream ()
1702{
726f6388
JA
1703 if (!stream_list)
1704 EOF_Reached = 1;
1705 else
1706 {
1707 STREAM_SAVER *saver = stream_list;
1708
1709 EOF_Reached = 0;
1710 stream_list = stream_list->next;
1711
1712 init_yy_io (saver->bash_input.getter,
1713 saver->bash_input.ungetter,
1714 saver->bash_input.type,
1715 saver->bash_input.name,
1716 saver->bash_input.location);
1717
1718#if defined (BUFFERED_INPUT)
1719 /* If we have a buffered stream, restore buffers[fd]. */
1720 /* If the input file descriptor was changed while this was on the
1721 save stack, update the buffered fd to the new file descriptor and
1722 re-establish the buffer <-> bash_input fd correspondence. */
1723 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
28ef6c31
JA
1724 {
1725 if (bash_input_fd_changed)
726f6388
JA
1726 {
1727 bash_input_fd_changed = 0;
1728 if (default_buffered_input >= 0)
1729 {
1730 bash_input.location.buffered_fd = default_buffered_input;
1731 saver->bstream->b_fd = default_buffered_input;
28ef6c31 1732 SET_CLOSE_ON_EXEC (default_buffered_input);
726f6388
JA
1733 }
1734 }
28ef6c31 1735 /* XXX could free buffered stream returned as result here. */
cce855bc 1736 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
28ef6c31 1737 }
726f6388
JA
1738#endif /* BUFFERED_INPUT */
1739
1740 line_number = saver->line;
1741
1742 FREE (saver->bash_input.name);
1743 free (saver);
1744 }
1745}
1746
1747/* Return 1 if a stream of type TYPE is saved on the stack. */
1748int
1749stream_on_stack (type)
ccc6cda3 1750 enum stream_type type;
726f6388
JA
1751{
1752 register STREAM_SAVER *s;
ccc6cda3 1753
726f6388
JA
1754 for (s = stream_list; s; s = s->next)
1755 if (s->bash_input.type == type)
1756 return 1;
1757 return 0;
1758}
1759
bb70624e
JA
1760/* Save the current token state and return it in a malloced array. */
1761int *
1762save_token_state ()
1763{
1764 int *ret;
1765
89a92869 1766 ret = (int *)xmalloc (4 * sizeof (int));
bb70624e
JA
1767 ret[0] = last_read_token;
1768 ret[1] = token_before_that;
1769 ret[2] = two_tokens_ago;
89a92869 1770 ret[3] = current_token;
bb70624e
JA
1771 return ret;
1772}
1773
1774void
1775restore_token_state (ts)
1776 int *ts;
1777{
1778 if (ts == 0)
1779 return;
1780 last_read_token = ts[0];
1781 token_before_that = ts[1];
1782 two_tokens_ago = ts[2];
89a92869 1783 current_token = ts[3];
bb70624e
JA
1784}
1785
726f6388
JA
1786/*
1787 * This is used to inhibit alias expansion and reserved word recognition
ccc6cda3
JA
1788 * inside case statement pattern lists. A `case statement pattern list' is:
1789 *
726f6388
JA
1790 * everything between the `in' in a `case word in' and the next ')'
1791 * or `esac'
1792 * everything between a `;;' and the next `)' or `esac'
1793 */
726f6388 1794
cce855bc
JA
1795#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1796
ccc6cda3
JA
1797#define END_OF_ALIAS 0
1798
726f6388
JA
1799/*
1800 * Pseudo-global variables used in implementing token-wise alias expansion.
1801 */
1802
726f6388 1803/*
ccc6cda3 1804 * Pushing and popping strings. This works together with shell_getc to
726f6388
JA
1805 * implement alias expansion on a per-token basis.
1806 */
1807
ac50fbac
CR
1808#define PSH_ALIAS 0x01
1809#define PSH_DPAREN 0x02
1810#define PSH_SOURCE 0x04
1811
726f6388
JA
1812typedef struct string_saver {
1813 struct string_saver *next;
1814 int expand_alias; /* Value to set expand_alias to when string is popped. */
1815 char *saved_line;
cce855bc 1816#if defined (ALIAS)
ccc6cda3 1817 alias_t *expander; /* alias that caused this line to be pushed. */
cce855bc 1818#endif
ac50fbac
CR
1819 size_t saved_line_size, saved_line_index;
1820 int saved_line_terminator;
1821 int flags;
726f6388
JA
1822} STRING_SAVER;
1823
1824STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1825
726f6388
JA
1826/*
1827 * Push the current shell_input_line onto a stack of such lines and make S
1828 * the current input. Used when expanding aliases. EXPAND is used to set
1829 * the value of expand_next_token when the string is popped, so that the
1830 * word after the alias in the original line is handled correctly when the
1831 * alias expands to multiple words. TOKEN is the token that was expanded
1832 * into S; it is saved and used to prevent infinite recursive expansion.
1833 */
1834static void
ccc6cda3 1835push_string (s, expand, ap)
726f6388
JA
1836 char *s;
1837 int expand;
ccc6cda3 1838 alias_t *ap;
726f6388 1839{
f73dda09 1840 STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER));
726f6388
JA
1841
1842 temp->expand_alias = expand;
1843 temp->saved_line = shell_input_line;
1844 temp->saved_line_size = shell_input_line_size;
1845 temp->saved_line_index = shell_input_line_index;
1846 temp->saved_line_terminator = shell_input_line_terminator;
ac50fbac 1847 temp->flags = 0;
cce855bc 1848#if defined (ALIAS)
ccc6cda3 1849 temp->expander = ap;
ac50fbac
CR
1850 if (ap)
1851 temp->flags = PSH_ALIAS;
cce855bc 1852#endif
726f6388
JA
1853 temp->next = pushed_string_list;
1854 pushed_string_list = temp;
1855
cce855bc 1856#if defined (ALIAS)
d166f048
JA
1857 if (ap)
1858 ap->flags |= AL_BEINGEXPANDED;
cce855bc 1859#endif
726f6388
JA
1860
1861 shell_input_line = s;
ac50fbac 1862 shell_input_line_size = STRLEN (s);
726f6388
JA
1863 shell_input_line_index = 0;
1864 shell_input_line_terminator = '\0';
b80f6443
JA
1865#if 0
1866 parser_state &= ~PST_ALEXPNEXT; /* XXX */
1867#endif
7117c2d2
JA
1868
1869 set_line_mbstate ();
726f6388
JA
1870}
1871
1872/*
1873 * Make the top of the pushed_string stack be the current shell input.
1874 * Only called when there is something on the stack. Called from shell_getc
1875 * when it thinks it has consumed the string generated by an alias expansion
1876 * and needs to return to the original input line.
1877 */
1878static void
1879pop_string ()
1880{
1881 STRING_SAVER *t;
1882
1883 FREE (shell_input_line);
1884 shell_input_line = pushed_string_list->saved_line;
1885 shell_input_line_index = pushed_string_list->saved_line_index;
1886 shell_input_line_size = pushed_string_list->saved_line_size;
1887 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
ccc6cda3
JA
1888
1889 if (pushed_string_list->expand_alias)
1890 parser_state |= PST_ALEXPNEXT;
1891 else
1892 parser_state &= ~PST_ALEXPNEXT;
726f6388
JA
1893
1894 t = pushed_string_list;
1895 pushed_string_list = pushed_string_list->next;
ccc6cda3 1896
cce855bc 1897#if defined (ALIAS)
d166f048
JA
1898 if (t->expander)
1899 t->expander->flags &= ~AL_BEINGEXPANDED;
cce855bc 1900#endif
ccc6cda3
JA
1901
1902 free ((char *)t);
7117c2d2
JA
1903
1904 set_line_mbstate ();
726f6388
JA
1905}
1906
1907static void
1908free_string_list ()
1909{
ccc6cda3 1910 register STRING_SAVER *t, *t1;
726f6388 1911
ccc6cda3 1912 for (t = pushed_string_list; t; )
726f6388
JA
1913 {
1914 t1 = t->next;
1915 FREE (t->saved_line);
cce855bc
JA
1916#if defined (ALIAS)
1917 if (t->expander)
1918 t->expander->flags &= ~AL_BEINGEXPANDED;
1919#endif
726f6388
JA
1920 free ((char *)t);
1921 t = t1;
1922 }
1923 pushed_string_list = (STRING_SAVER *)NULL;
1924}
1925
cce855bc 1926#endif /* ALIAS || DPAREN_ARITHMETIC */
ccc6cda3 1927
b80f6443
JA
1928void
1929free_pushed_string_input ()
1930{
1931#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1932 free_string_list ();
1933#endif
1934}
1935
ac50fbac
CR
1936int
1937parser_expanding_alias ()
1938{
1939 return (expanding_alias ());
1940}
1941
1942void
1943parser_save_alias ()
1944{
1945#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1946 push_string ((char *)NULL, 0, (alias_t *)NULL);
1947 pushed_string_list->flags = PSH_SOURCE; /* XXX - for now */
1948#else
1949 ;
1950#endif
1951}
1952
1953void
1954parser_restore_alias ()
1955{
1956#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1957 if (pushed_string_list)
1958 pop_string ();
1959#else
1960 ;
1961#endif
1962}
1963
a0c0a00f
CR
1964void
1965clear_shell_input_line ()
1966{
1967 if (shell_input_line)
1968 shell_input_line[shell_input_line_index = 0] = '\0';
1969}
1970
726f6388
JA
1971/* Return a line of text, taken from wherever yylex () reads input.
1972 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
1973 is non-zero, we remove unquoted \<newline> pairs. This is used by
1974 read_secondary_line to read here documents. */
1975static char *
1976read_a_line (remove_quoted_newline)
1977 int remove_quoted_newline;
1978{
1979 static char *line_buffer = (char *)NULL;
1980 static int buffer_size = 0;
0001803f 1981 int indx, c, peekc, pass_next;
726f6388 1982
ccc6cda3 1983#if defined (READLINE)
b80f6443 1984 if (no_line_editing && SHOULD_PROMPT ())
ccc6cda3 1985#else
b80f6443 1986 if (SHOULD_PROMPT ())
ccc6cda3
JA
1987#endif
1988 print_prompt ();
1989
0001803f 1990 pass_next = indx = 0;
726f6388
JA
1991 while (1)
1992 {
726f6388
JA
1993 /* Allow immediate exit if interrupted during input. */
1994 QUIT;
1995
95732b49
JA
1996 c = yy_getc ();
1997
28ef6c31 1998 /* Ignore null bytes in input. */
726f6388 1999 if (c == 0)
28ef6c31
JA
2000 {
2001#if 0
2002 internal_warning ("read_a_line: ignored null byte in input");
2003#endif
2004 continue;
2005 }
726f6388
JA
2006
2007 /* If there is no more input, then we return NULL. */
2008 if (c == EOF)
2009 {
ccc6cda3
JA
2010 if (interactive && bash_input.type == st_stream)
2011 clearerr (stdin);
726f6388
JA
2012 if (indx == 0)
2013 return ((char *)NULL);
2014 c = '\n';
2015 }
2016
2017 /* `+2' in case the final character in the buffer is a newline. */
ccc6cda3 2018 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
726f6388
JA
2019
2020 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
2021 here document with an unquoted delimiter. In this case,
2022 the line will be expanded as if it were in double quotes.
2023 We allow a backslash to escape the next character, but we
2024 need to treat the backslash specially only if a backslash
2025 quoting a backslash-newline pair appears in the line. */
2026 if (pass_next)
28ef6c31 2027 {
726f6388
JA
2028 line_buffer[indx++] = c;
2029 pass_next = 0;
28ef6c31 2030 }
726f6388
JA
2031 else if (c == '\\' && remove_quoted_newline)
2032 {
495aee44 2033 QUIT;
726f6388
JA
2034 peekc = yy_getc ();
2035 if (peekc == '\n')
b80f6443
JA
2036 {
2037 line_number++;
2038 continue; /* Make the unquoted \<newline> pair disappear. */
2039 }
726f6388
JA
2040 else
2041 {
2042 yy_ungetc (peekc);
2043 pass_next = 1;
2044 line_buffer[indx++] = c; /* Preserve the backslash. */
2045 }
2046 }
2047 else
2048 line_buffer[indx++] = c;
2049
2050 if (c == '\n')
2051 {
2052 line_buffer[indx] = '\0';
2053 return (line_buffer);
2054 }
2055 }
2056}
2057
2058/* Return a line as in read_a_line (), but insure that the prompt is
2059 the secondary prompt. This is used to read the lines of a here
2060 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
2061 newlines quoted with backslashes while reading the line. It is
2062 non-zero unless the delimiter of the here document was quoted. */
2063char *
2064read_secondary_line (remove_quoted_newline)
2065 int remove_quoted_newline;
2066{
3185942a
JA
2067 char *ret;
2068 int n, c;
2069
726f6388 2070 prompt_string_pointer = &ps2_prompt;
b80f6443
JA
2071 if (SHOULD_PROMPT())
2072 prompt_again ();
3185942a
JA
2073 ret = read_a_line (remove_quoted_newline);
2074#if defined (HISTORY)
89a92869 2075 if (ret && remember_on_history && (parser_state & PST_HEREDOC))
3185942a 2076 {
a0c0a00f
CR
2077 /* To make adding the here-document body right, we need to rely on
2078 history_delimiting_chars() returning \n for the first line of the
2079 here-document body and the null string for the second and subsequent
2080 lines, so we avoid double newlines.
3185942a
JA
2081 current_command_line_count == 2 for the first line of the body. */
2082
2083 current_command_line_count++;
2084 maybe_add_history (ret);
2085 }
2086#endif /* HISTORY */
2087 return ret;
726f6388
JA
2088}
2089
726f6388
JA
2090/* **************************************************************** */
2091/* */
2092/* YYLEX () */
2093/* */
2094/* **************************************************************** */
2095
2096/* Reserved words. These are only recognized as the first word of a
2097 command. */
2098STRING_INT_ALIST word_token_alist[] = {
2099 { "if", IF },
2100 { "then", THEN },
2101 { "else", ELSE },
2102 { "elif", ELIF },
2103 { "fi", FI },
2104 { "case", CASE },
2105 { "esac", ESAC },
2106 { "for", FOR },
2107#if defined (SELECT_COMMAND)
2108 { "select", SELECT },
2109#endif
2110 { "while", WHILE },
2111 { "until", UNTIL },
2112 { "do", DO },
2113 { "done", DONE },
2114 { "in", IN },
2115 { "function", FUNCTION },
ccc6cda3
JA
2116#if defined (COMMAND_TIMING)
2117 { "time", TIME },
2118#endif
726f6388
JA
2119 { "{", '{' },
2120 { "}", '}' },
2121 { "!", BANG },
cce855bc
JA
2122#if defined (COND_COMMAND)
2123 { "[[", COND_START },
2124 { "]]", COND_END },
3185942a
JA
2125#endif
2126#if defined (COPROCESS_SUPPORT)
2127 { "coproc", COPROC },
cce855bc 2128#endif
726f6388
JA
2129 { (char *)NULL, 0}
2130};
2131
7117c2d2
JA
2132/* other tokens that can be returned by read_token() */
2133STRING_INT_ALIST other_token_alist[] = {
2134 /* Multiple-character tokens with special values */
495aee44 2135 { "--", TIMEIGN },
7117c2d2
JA
2136 { "-p", TIMEOPT },
2137 { "&&", AND_AND },
2138 { "||", OR_OR },
2139 { ">>", GREATER_GREATER },
2140 { "<<", LESS_LESS },
2141 { "<&", LESS_AND },
2142 { ">&", GREATER_AND },
2143 { ";;", SEMI_SEMI },
3185942a
JA
2144 { ";&", SEMI_AND },
2145 { ";;&", SEMI_SEMI_AND },
7117c2d2
JA
2146 { "<<-", LESS_LESS_MINUS },
2147 { "<<<", LESS_LESS_LESS },
2148 { "&>", AND_GREATER },
3185942a 2149 { "&>>", AND_GREATER_GREATER },
7117c2d2
JA
2150 { "<>", LESS_GREATER },
2151 { ">|", GREATER_BAR },
3185942a 2152 { "|&", BAR_AND },
7117c2d2
JA
2153 { "EOF", yacc_EOF },
2154 /* Tokens whose value is the character itself */
2155 { ">", '>' },
2156 { "<", '<' },
2157 { "-", '-' },
2158 { "{", '{' },
2159 { "}", '}' },
2160 { ";", ';' },
2161 { "(", '(' },
2162 { ")", ')' },
2163 { "|", '|' },
2164 { "&", '&' },
2165 { "newline", '\n' },
2166 { (char *)NULL, 0}
2167};
2168
2169/* others not listed here:
2170 WORD look at yylval.word
2171 ASSIGNMENT_WORD look at yylval.word
2172 NUMBER look at yylval.number
2173 ARITH_CMD look at yylval.word_list
2174 ARITH_FOR_EXPRS look at yylval.word_list
2175 COND_CMD look at yylval.command
2176*/
b72432fd 2177
ccc6cda3
JA
2178/* These are used by read_token_word, but appear up here so that shell_getc
2179 can use them to decide when to add otherwise blank lines to the history. */
2180
2181/* The primary delimiter stack. */
2182struct dstack dstack = { (char *)NULL, 0, 0 };
2183
2184/* A temporary delimiter stack to be used when decoding prompt strings.
2185 This is needed because command substitutions in prompt strings (e.g., PS2)
2186 can screw up the parser's quoting state. */
2187static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
2188
2189/* Macro for accessing the top delimiter on the stack. Returns the
2190 delimiter or zero if none. */
2191#define current_delimiter(ds) \
2192 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
2193
2194#define push_delimiter(ds, character) \
2195 do \
2196 { \
2197 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
f73dda09 2198 ds.delimiters = (char *)xrealloc \
ccc6cda3
JA
2199 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
2200 ds.delimiters[ds.delimiter_depth] = character; \
2201 ds.delimiter_depth++; \
2202 } \
2203 while (0)
2204
2205#define pop_delimiter(ds) ds.delimiter_depth--
2206
726f6388
JA
2207/* Return the next shell input character. This always reads characters
2208 from shell_input_line; when that line is exhausted, it is time to
2209 read the next line. This is called by read_token when the shell is
2210 processing normal command input. */
ccc6cda3 2211
28ef6c31
JA
2212/* This implements one-character lookahead/lookbehind across physical input
2213 lines, to avoid something being lost because it's pushed back with
2214 shell_ungetc when we're at the start of a line. */
2215static int eol_ungetc_lookahead = 0;
2216
726f6388
JA
2217static int
2218shell_getc (remove_quoted_newline)
2219 int remove_quoted_newline;
2220{
ccc6cda3 2221 register int i;
a0c0a00f 2222 int c, truncating, last_was_backslash;
f73dda09 2223 unsigned char uc;
726f6388
JA
2224
2225 QUIT;
2226
a0c0a00f 2227 last_was_backslash = 0;
95732b49
JA
2228 if (sigwinch_received)
2229 {
2230 sigwinch_received = 0;
2231 get_new_window_size (0, (int *)0, (int *)0);
2232 }
2233
28ef6c31
JA
2234 if (eol_ungetc_lookahead)
2235 {
2236 c = eol_ungetc_lookahead;
2237 eol_ungetc_lookahead = 0;
2238 return (c);
2239 }
2240
cce855bc 2241#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
726f6388
JA
2242 /* If shell_input_line[shell_input_line_index] == 0, but there is
2243 something on the pushed list of strings, then we don't want to go
2244 off and get another line. We let the code down below handle it. */
2245
2246 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
2247 (pushed_string_list == (STRING_SAVER *)NULL)))
cce855bc 2248#else /* !ALIAS && !DPAREN_ARITHMETIC */
726f6388 2249 if (!shell_input_line || !shell_input_line[shell_input_line_index])
cce855bc 2250#endif /* !ALIAS && !DPAREN_ARITHMETIC */
726f6388 2251 {
726f6388
JA
2252 line_number++;
2253
ac50fbac
CR
2254 /* Let's not let one really really long line blow up memory allocation */
2255 if (shell_input_line && shell_input_line_size >= 32768)
2256 {
2257 free (shell_input_line);
2258 shell_input_line = 0;
2259 shell_input_line_size = 0;
2260 }
2261
726f6388
JA
2262 restart_read:
2263
2264 /* Allow immediate exit if interrupted during input. */
2265 QUIT;
2266
ac50fbac 2267 i = truncating = 0;
726f6388
JA
2268 shell_input_line_terminator = 0;
2269
b80f6443
JA
2270 /* If the shell is interatctive, but not currently printing a prompt
2271 (interactive_shell && interactive == 0), we don't want to print
2272 notifies or cleanup the jobs -- we want to defer it until we do
2273 print the next prompt. */
2274 if (interactive_shell == 0 || SHOULD_PROMPT())
2275 {
726f6388
JA
2276#if defined (JOB_CONTROL)
2277 /* This can cause a problem when reading a command as the result
2278 of a trap, when the trap is called from flush_child. This call
2279 had better not cause jobs to disappear from the job table in
2280 that case, or we will have big trouble. */
b80f6443 2281 notify_and_cleanup ();
726f6388 2282#else /* !JOB_CONTROL */
b80f6443 2283 cleanup_dead_jobs ();
726f6388 2284#endif /* !JOB_CONTROL */
b80f6443 2285 }
726f6388
JA
2286
2287#if defined (READLINE)
b80f6443 2288 if (no_line_editing && SHOULD_PROMPT())
726f6388 2289#else
b80f6443 2290 if (SHOULD_PROMPT())
726f6388
JA
2291#endif
2292 print_prompt ();
2293
2294 if (bash_input.type == st_stream)
2295 clearerr (stdin);
2296
28ef6c31 2297 while (1)
726f6388 2298 {
28ef6c31
JA
2299 c = yy_getc ();
2300
726f6388
JA
2301 /* Allow immediate exit if interrupted during input. */
2302 QUIT;
2303
28ef6c31
JA
2304 if (c == '\0')
2305 {
2306#if 0
2307 internal_warning ("shell_getc: ignored null byte in input");
2308#endif
2309 continue;
2310 }
2311
ac50fbac
CR
2312 /* Theoretical overflow */
2313 /* If we can't put 256 bytes more into the buffer, allocate
2314 everything we can and fill it as full as we can. */
2315 /* XXX - we ignore rest of line using `truncating' flag */
2316 if (shell_input_line_size > (SIZE_MAX - 256))
2317 {
2318 size_t n;
2319
2320 n = SIZE_MAX - i; /* how much more can we put into the buffer? */
2321 if (n <= 2) /* we have to save 1 for the newline added below */
2322 {
2323 if (truncating == 0)
a0c0a00f 2324 internal_warning(_("shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%lu): line truncated"), shell_input_line_size, (unsigned long)SIZE_MAX);
ac50fbac
CR
2325 shell_input_line[i] = '\0';
2326 truncating = 1;
2327 }
2328 if (shell_input_line_size < SIZE_MAX)
2329 {
2330 shell_input_line_size = SIZE_MAX;
2331 shell_input_line = xrealloc (shell_input_line, shell_input_line_size);
2332 }
2333 }
2334 else
2335 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
726f6388
JA
2336
2337 if (c == EOF)
2338 {
2339 if (bash_input.type == st_stream)
2340 clearerr (stdin);
2341
ccc6cda3 2342 if (i == 0)
726f6388
JA
2343 shell_input_line_terminator = EOF;
2344
2345 shell_input_line[i] = '\0';
2346 break;
2347 }
2348
ac50fbac
CR
2349 if (truncating == 0 || c == '\n')
2350 shell_input_line[i++] = c;
726f6388
JA
2351
2352 if (c == '\n')
2353 {
2354 shell_input_line[--i] = '\0';
2355 current_command_line_count++;
2356 break;
2357 }
a0c0a00f
CR
2358
2359 last_was_backslash = last_was_backslash == 0 && c == '\\';
726f6388 2360 }
28ef6c31 2361
726f6388
JA
2362 shell_input_line_index = 0;
2363 shell_input_line_len = i; /* == strlen (shell_input_line) */
2364
7117c2d2
JA
2365 set_line_mbstate ();
2366
726f6388 2367#if defined (HISTORY)
ccc6cda3 2368 if (remember_on_history && shell_input_line && shell_input_line[0])
726f6388
JA
2369 {
2370 char *expansions;
ccc6cda3
JA
2371# if defined (BANG_HISTORY)
2372 int old_hist;
2373
2374 /* If the current delimiter is a single quote, we should not be
2375 performing history expansion, even if we're on a different
2376 line from the original single quote. */
2377 old_hist = history_expansion_inhibited;
2378 if (current_delimiter (dstack) == '\'')
2379 history_expansion_inhibited = 1;
2380# endif
a0c0a00f
CR
2381 /* Calling with a third argument of 1 allows remember_on_history to
2382 determine whether or not the line is saved to the history list */
726f6388 2383 expansions = pre_process_line (shell_input_line, 1, 1);
ccc6cda3
JA
2384# if defined (BANG_HISTORY)
2385 history_expansion_inhibited = old_hist;
2386# endif
d166f048
JA
2387 if (expansions != shell_input_line)
2388 {
2389 free (shell_input_line);
2390 shell_input_line = expansions;
2391 shell_input_line_len = shell_input_line ?
2392 strlen (shell_input_line) : 0;
495aee44 2393 if (shell_input_line_len == 0)
d166f048
JA
2394 current_command_line_count--;
2395
2396 /* We have to force the xrealloc below because we don't know
28ef6c31 2397 the true allocated size of shell_input_line anymore. */
d166f048 2398 shell_input_line_size = shell_input_line_len;
7117c2d2
JA
2399
2400 set_line_mbstate ();
d166f048 2401 }
726f6388 2402 }
28ef6c31
JA
2403 /* Try to do something intelligent with blank lines encountered while
2404 entering multi-line commands. XXX - this is grotesque */
ccc6cda3
JA
2405 else if (remember_on_history && shell_input_line &&
2406 shell_input_line[0] == '\0' &&
28ef6c31 2407 current_command_line_count > 1)
ccc6cda3 2408 {
28ef6c31
JA
2409 if (current_delimiter (dstack))
2410 /* We know shell_input_line[0] == 0 and we're reading some sort of
2411 quoted string. This means we've got a line consisting of only
2412 a newline in a quoted string. We want to make sure this line
2413 gets added to the history. */
2414 maybe_add_history (shell_input_line);
2415 else
2416 {
2417 char *hdcs;
495aee44 2418 hdcs = history_delimiting_chars (shell_input_line);
28ef6c31
JA
2419 if (hdcs && hdcs[0] == ';')
2420 maybe_add_history (shell_input_line);
2421 }
ccc6cda3
JA
2422 }
2423
726f6388
JA
2424#endif /* HISTORY */
2425
2426 if (shell_input_line)
2427 {
2428 /* Lines that signify the end of the shell's input should not be
ac50fbac
CR
2429 echoed. We should not echo lines while parsing command
2430 substitutions with recursive calls into the parsing engine; those
2431 should only be echoed once when we read the word. That is the
2432 reason for the test against shell_eof_token, which is set to a
2433 right paren when parsing the contents of command substitutions. */
726f6388 2434 if (echo_input_at_read && (shell_input_line[0] ||
ac50fbac
CR
2435 shell_input_line_terminator != EOF) &&
2436 shell_eof_token == 0)
726f6388
JA
2437 fprintf (stderr, "%s\n", shell_input_line);
2438 }
2439 else
2440 {
2441 shell_input_line_size = 0;
2442 prompt_string_pointer = &current_prompt_string;
b80f6443
JA
2443 if (SHOULD_PROMPT ())
2444 prompt_again ();
726f6388
JA
2445 goto restart_read;
2446 }
2447
2448 /* Add the newline to the end of this string, iff the string does
2449 not already end in an EOF character. */
2450 if (shell_input_line_terminator != EOF)
2451 {
6ebbb24a 2452 if (shell_input_line_size < SIZE_MAX-3 && (shell_input_line_len+3 > shell_input_line_size))
f73dda09 2453 shell_input_line = (char *)xrealloc (shell_input_line,
726f6388
JA
2454 1 + (shell_input_line_size += 2));
2455
a0c0a00f
CR
2456 /* Don't add a newline to a string that ends with a backslash if we're
2457 going to be removing quoted newlines, since that will eat the
2458 backslash. Add another backslash instead (will be removed by
2459 word expansion). */
2460 if (bash_input.type == st_string && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline)
2461 shell_input_line[shell_input_line_len] = '\\';
2462 else
2463 shell_input_line[shell_input_line_len] = '\n';
ccc6cda3 2464 shell_input_line[shell_input_line_len + 1] = '\0';
7117c2d2
JA
2465
2466 set_line_mbstate ();
726f6388
JA
2467 }
2468 }
ccc6cda3 2469
495aee44 2470next_alias_char:
f73dda09 2471 uc = shell_input_line[shell_input_line_index];
726f6388 2472
f73dda09 2473 if (uc)
726f6388
JA
2474 shell_input_line_index++;
2475
cce855bc 2476#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
f73dda09 2477 /* If UC is NULL, we have reached the end of the current input string. If
726f6388
JA
2478 pushed_string_list is non-empty, it's time to pop to the previous string
2479 because we have fully consumed the result of the last alias expansion.
2480 Do it transparently; just return the next character of the string popped
2481 to. */
ac50fbac
CR
2482 /* If pushed_string_list != 0 but pushed_string_list->expander == 0 (not
2483 currently tested) and the flags value is not PSH_SOURCE, we are not
2484 parsing an alias, we have just saved one (push_string, when called by
2485 the parse_dparen code) In this case, just go on as well. The PSH_SOURCE
2486 case is handled below. */
0001803f 2487pop_alias:
ac50fbac 2488 if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE)
726f6388 2489 {
b80f6443
JA
2490 pop_string ();
2491 uc = shell_input_line[shell_input_line_index];
2492 if (uc)
2493 shell_input_line_index++;
726f6388 2494 }
cce855bc 2495#endif /* ALIAS || DPAREN_ARITHMETIC */
726f6388 2496
95732b49
JA
2497 if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
2498 {
2499 if (SHOULD_PROMPT ())
2500 prompt_again ();
2501 line_number++;
495aee44
CR
2502 /* What do we do here if we're expanding an alias whose definition
2503 includes an escaped newline? If that's the last character in the
2504 alias expansion, we just pop the pushed string list (recall that
2505 we inhibit the appending of a space in mk_alexpansion() if newline
2506 is the last character). If it's not the last character, we need
2507 to consume the quoted newline and move to the next character in
2508 the expansion. */
509a4430 2509#if defined (ALIAS)
0001803f
CR
2510 if (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0')
2511 {
2512 uc = 0;
2513 goto pop_alias;
2514 }
495aee44
CR
2515 else if (expanding_alias () && shell_input_line[shell_input_line_index+1] != '\0')
2516 {
2517 shell_input_line_index++; /* skip newline */
2518 goto next_alias_char; /* and get next character */
2519 }
509a4430
CR
2520 else
2521#endif
495aee44 2522 goto restart_read;
95732b49
JA
2523 }
2524
495aee44 2525 if (uc == 0 && shell_input_line_terminator == EOF)
ccc6cda3 2526 return ((shell_input_line_index != 0) ? '\n' : EOF);
726f6388 2527
ac50fbac
CR
2528#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
2529 /* We already know that we are not parsing an alias expansion because of the
2530 check for expanding_alias() above. This knows how parse_and_execute
2531 handles switching to st_string input while an alias is being expanded,
2532 hence the check for pushed_string_list without pushed_string_list->expander
2533 and the check for PSH_SOURCE as pushed_string_list->flags.
2534 parse_and_execute and parse_string both change the input type to st_string
2535 and place the string to be parsed and executed into location.string, so
2536 we should not stop reading that until the pointer is '\0'.
2537 The check for shell_input_line_terminator may be superfluous.
2538
2539 This solves the problem of `.' inside a multi-line alias with embedded
2540 newlines executing things out of order. */
2541 if (uc == 0 && bash_input.type == st_string && *bash_input.location.string &&
2542 pushed_string_list && pushed_string_list->flags == PSH_SOURCE &&
2543 shell_input_line_terminator == 0)
2544 {
2545 shell_input_line_index = 0;
2546 goto restart_read;
2547 }
2548#endif
2549
f73dda09 2550 return (uc);
726f6388
JA
2551}
2552
7117c2d2
JA
2553/* Put C back into the input for the shell. This might need changes for
2554 HANDLE_MULTIBYTE around EOLs. Since we (currently) never push back a
2555 character different than we read, shell_input_line_property doesn't need
2556 to change when manipulating shell_input_line. The define for
2557 last_shell_getc_is_singlebyte should take care of it, though. */
726f6388
JA
2558static void
2559shell_ungetc (c)
2560 int c;
2561{
2562 if (shell_input_line && shell_input_line_index)
2563 shell_input_line[--shell_input_line_index] = c;
28ef6c31
JA
2564 else
2565 eol_ungetc_lookahead = c;
726f6388
JA
2566}
2567
ca6a2ba4
CR
2568char *
2569parser_remaining_input ()
2570{
2571 if (shell_input_line == 0)
2572 return 0;
2573 if (shell_input_line_index < 0 || shell_input_line_index >= shell_input_line_len)
a0c0a00f 2574 return ""; /* XXX */
ca6a2ba4
CR
2575 return (shell_input_line + shell_input_line_index);
2576}
2577
f73dda09
JA
2578#ifdef INCLUDE_UNUSED
2579/* Back the input pointer up by one, effectively `ungetting' a character. */
ccc6cda3
JA
2580static void
2581shell_ungetchar ()
2582{
2583 if (shell_input_line && shell_input_line_index)
2584 shell_input_line_index--;
2585}
f73dda09 2586#endif
ccc6cda3
JA
2587
2588/* Discard input until CHARACTER is seen, then push that character back
2589 onto the input stream. */
726f6388
JA
2590static void
2591discard_until (character)
2592 int character;
2593{
2594 int c;
2595
2596 while ((c = shell_getc (0)) != EOF && c != character)
2597 ;
2598
2599 if (c != EOF)
2600 shell_ungetc (c);
2601}
726f6388
JA
2602
2603void
0628567a
JA
2604execute_variable_command (command, vname)
2605 char *command, *vname;
726f6388 2606{
726f6388 2607 char *last_lastarg;
b80f6443 2608 sh_parser_state_t ps;
726f6388 2609
b80f6443 2610 save_parser_state (&ps);
726f6388
JA
2611 last_lastarg = get_string_value ("_");
2612 if (last_lastarg)
2613 last_lastarg = savestring (last_lastarg);
2614
0628567a 2615 parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
726f6388 2616
b80f6443 2617 restore_parser_state (&ps);
95732b49 2618 bind_variable ("_", last_lastarg, 0);
726f6388
JA
2619 FREE (last_lastarg);
2620
ccc6cda3 2621 if (token_to_read == '\n') /* reset_parser was called */
726f6388
JA
2622 token_to_read = 0;
2623}
2624
a0c0a00f
CR
2625void
2626push_token (x)
2627 int x;
2628{
2629 two_tokens_ago = token_before_that;
2630 token_before_that = last_read_token;
2631 last_read_token = current_token;
2632
2633 current_token = x;
2634}
2635
ccc6cda3
JA
2636/* Place to remember the token. We try to keep the buffer
2637 at a reasonable size, but it can grow. */
2638static char *token = (char *)NULL;
2639
2640/* Current size of the token buffer. */
2641static int token_buffer_size;
2642
726f6388
JA
2643/* Command to read_token () explaining what we want it to do. */
2644#define READ 0
2645#define RESET 1
2646#define prompt_is_ps1 \
2647 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2648
2649/* Function for yyparse to call. yylex keeps track of
2650 the last two tokens read, and calls read_token. */
ccc6cda3 2651static int
726f6388
JA
2652yylex ()
2653{
ccc6cda3 2654 if (interactive && (current_token == 0 || current_token == '\n'))
726f6388
JA
2655 {
2656 /* Before we print a prompt, we might have to check mailboxes.
2657 We do this only if it is time to do so. Notice that only here
2658 is the mail alarm reset; nothing takes place in check_mail ()
2659 except the checking of mail. Please don't change this. */
b4a8651a 2660 if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ())
726f6388
JA
2661 {
2662 check_mail ();
2663 reset_mail_timer ();
2664 }
2665
2666 /* Avoid printing a prompt if we're not going to read anything, e.g.
2667 after resetting the parser with read_token (RESET). */
b80f6443 2668 if (token_to_read == 0 && SHOULD_PROMPT ())
726f6388
JA
2669 prompt_again ();
2670 }
2671
ccc6cda3 2672 two_tokens_ago = token_before_that;
726f6388
JA
2673 token_before_that = last_read_token;
2674 last_read_token = current_token;
2675 current_token = read_token (READ);
3185942a
JA
2676
2677 if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token)
2678 {
2679 current_token = yacc_EOF;
2680 if (bash_input.type == st_string)
2681 rewind_input_string ();
2682 }
2683 parser_state &= ~PST_EOFTOKEN;
2684
726f6388
JA
2685 return (current_token);
2686}
2687
726f6388
JA
2688/* When non-zero, we have read the required tokens
2689 which allow ESAC to be the next one read. */
ccc6cda3 2690static int esacs_needed_count;
726f6388 2691
90a39f32
CR
2692static void
2693push_heredoc (r)
2694 REDIRECT *r;
2695{
2696 if (need_here_doc >= HEREDOC_MAX)
2697 {
2698 last_command_exit_value = EX_BADUSAGE;
2699 need_here_doc = 0;
2700 report_syntax_error (_("maximum here-document count exceeded"));
2701 reset_parser ();
2702 exit_shell (last_command_exit_value);
2703 }
2704 redir_stack[need_here_doc++] = r;
2705}
2706
726f6388
JA
2707void
2708gather_here_documents ()
2709{
3185942a
JA
2710 int r;
2711
2712 r = 0;
a0c0a00f 2713 here_doc_first_line = 1;
daefb2c5 2714 while (need_here_doc > 0)
726f6388 2715 {
3185942a
JA
2716 parser_state |= PST_HEREDOC;
2717 make_here_document (redir_stack[r++], line_number);
2718 parser_state &= ~PST_HEREDOC;
726f6388 2719 need_here_doc--;
a0c0a00f 2720 redir_stack[r - 1] = 0; /* XXX */
726f6388 2721 }
a0c0a00f 2722 here_doc_first_line = 0; /* just in case */
726f6388
JA
2723}
2724
726f6388
JA
2725/* When non-zero, an open-brace used to create a group is awaiting a close
2726 brace partner. */
ccc6cda3 2727static int open_brace_count;
726f6388 2728
a0c0a00f
CR
2729/* In the following three macros, `token' is always last_read_token */
2730
2731/* Are we in the middle of parsing a redirection where we are about to read
2732 a word? This is used to make sure alias expansion doesn't happen in the
2733 middle of a redirection, even though we're parsing a simple command. */
2734#define parsing_redirection(token) \
2735 (token == '<' || token == '>' || \
2736 token == GREATER_GREATER || token == GREATER_BAR || \
2737 token == LESS_GREATER || token == LESS_LESS_MINUS || \
2738 token == LESS_LESS || token == LESS_LESS_LESS || \
2739 token == LESS_AND || token == GREATER_AND || token == AND_GREATER)
2740
2741/* Is `token' one that will allow a WORD to be read in a command position?
2742 We can read a simple command name on which we should attempt alias expansion
2743 or we can read an assignment statement. */
726f6388 2744#define command_token_position(token) \
a0c0a00f
CR
2745 (((token) == ASSIGNMENT_WORD) || \
2746 ((parser_state&PST_REDIRLIST) && parsing_redirection(token) == 0) || \
3185942a 2747 ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token)))
726f6388 2748
a0c0a00f 2749/* Are we in a position where we can read an assignment statement? */
b80f6443
JA
2750#define assignment_acceptable(token) \
2751 (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
726f6388
JA
2752
2753/* Check to see if TOKEN is a reserved word and return the token
2754 value if it is. */
2755#define CHECK_FOR_RESERVED_WORD(tok) \
2756 do { \
2757 if (!dollar_present && !quoted && \
2758 reserved_word_acceptable (last_read_token)) \
2759 { \
2760 int i; \
2761 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2762 if (STREQ (tok, word_token_alist[i].word)) \
2763 { \
ccc6cda3 2764 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
726f6388 2765 break; \
b80f6443 2766 if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
cce855bc 2767 break; \
a0c0a00f
CR
2768 if ((parser_state & PST_CASEPAT) && last_read_token == '|' && word_token_alist[i].token == ESAC) \
2769 break; /* Posix grammar rule 4 */ \
726f6388 2770 if (word_token_alist[i].token == ESAC) \
ccc6cda3
JA
2771 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2772 else if (word_token_alist[i].token == CASE) \
2773 parser_state |= PST_CASESTMT; \
cce855bc
JA
2774 else if (word_token_alist[i].token == COND_END) \
2775 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
2776 else if (word_token_alist[i].token == COND_START) \
2777 parser_state |= PST_CONDCMD; \
ccc6cda3
JA
2778 else if (word_token_alist[i].token == '{') \
2779 open_brace_count++; \
2780 else if (word_token_alist[i].token == '}' && open_brace_count) \
2781 open_brace_count--; \
726f6388
JA
2782 return (word_token_alist[i].token); \
2783 } \
2784 } \
2785 } while (0)
2786
ccc6cda3
JA
2787#if defined (ALIAS)
2788
2789 /* OK, we have a token. Let's try to alias expand it, if (and only if)
2790 it's eligible.
2791
7117c2d2 2792 It is eligible for expansion if EXPAND_ALIASES is set, and
ccc6cda3
JA
2793 the token is unquoted and the last token read was a command
2794 separator (or expand_next_token is set), and we are currently
2795 processing an alias (pushed_string_list is non-empty) and this
2796 token is not the same as the current or any previously
2797 processed alias.
2798
2799 Special cases that disqualify:
2800 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
b80f6443
JA
2801
2802static char *
2803mk_alexpansion (s)
2804 char *s;
2805{
2806 int l;
2807 char *r;
2808
2809 l = strlen (s);
2810 r = xmalloc (l + 2);
2811 strcpy (r, s);
495aee44
CR
2812 /* If the last character in the alias is a newline, don't add a trailing
2813 space to the expansion. Works with shell_getc above. */
a0c0a00f 2814 if (r[l - 1] != ' ' && r[l - 1] != '\n' && shellmeta(r[l - 1]) == 0)
b80f6443
JA
2815 r[l++] = ' ';
2816 r[l] = '\0';
2817 return r;
2818}
2819
ccc6cda3 2820static int
f73dda09
JA
2821alias_expand_token (tokstr)
2822 char *tokstr;
726f6388 2823{
ccc6cda3
JA
2824 char *expanded;
2825 alias_t *ap;
726f6388 2826
ccc6cda3
JA
2827 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
2828 (parser_state & PST_CASEPAT) == 0)
726f6388 2829 {
f73dda09 2830 ap = find_alias (tokstr);
ccc6cda3
JA
2831
2832 /* Currently expanding this token. */
2833 if (ap && (ap->flags & AL_BEINGEXPANDED))
2834 return (NO_EXPANSION);
2835
b80f6443
JA
2836 /* mk_alexpansion puts an extra space on the end of the alias expansion,
2837 so the lookahead by the parser works right. If this gets changed,
2838 make sure the code in shell_getc that deals with reaching the end of
2839 an expanded alias is changed with it. */
2840 expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
2841
ccc6cda3
JA
2842 if (expanded)
2843 {
2844 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
2845 return (RE_READ_TOKEN);
2846 }
2847 else
2848 /* This is an eligible token that does not have an expansion. */
2849 return (NO_EXPANSION);
726f6388 2850 }
ccc6cda3
JA
2851 return (NO_EXPANSION);
2852}
2853#endif /* ALIAS */
726f6388 2854
cce855bc
JA
2855static int
2856time_command_acceptable ()
2857{
2858#if defined (COMMAND_TIMING)
495aee44
CR
2859 int i;
2860
2861 if (posixly_correct && shell_compatibility_level > 41)
2862 {
2863 /* Quick check of the rest of the line to find the next token. If it
2864 begins with a `-', Posix says to not return `time' as the token.
2865 This was interp 267. */
2866 i = shell_input_line_index;
2867 while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t'))
2868 i++;
2869 if (shell_input_line[i] == '-')
2870 return 0;
2871 }
2872
cce855bc
JA
2873 switch (last_read_token)
2874 {
2875 case 0:
2876 case ';':
2877 case '\n':
a0c0a00f
CR
2878 if (token_before_that == '|')
2879 return (0);
2880 /* FALLTHROUGH */
cce855bc
JA
2881 case AND_AND:
2882 case OR_OR:
2883 case '&':
af61c549 2884 case WHILE:
b72432fd 2885 case DO:
af61c549
CR
2886 case UNTIL:
2887 case IF:
b72432fd 2888 case THEN:
af61c549 2889 case ELIF:
b72432fd 2890 case ELSE:
28ef6c31 2891 case '{': /* } */
af61c549
CR
2892 case '(': /* )( */
2893 case ')': /* only valid in case statement */
495aee44
CR
2894 case BANG: /* ! time pipeline */
2895 case TIME: /* time time pipeline */
2896 case TIMEOPT: /* time -p time pipeline */
2897 case TIMEIGN: /* time -p -- ... */
cce855bc
JA
2898 return 1;
2899 default:
2900 return 0;
2901 }
2902#else
2903 return 0;
2904#endif /* COMMAND_TIMING */
2905}
2906
ccc6cda3
JA
2907/* Handle special cases of token recognition:
2908 IN is recognized if the last token was WORD and the token
2909 before that was FOR or CASE or SELECT.
2910
2911 DO is recognized if the last token was WORD and the token
2912 before that was FOR or SELECT.
2913
2914 ESAC is recognized if the last token caused `esacs_needed_count'
2915 to be set
2916
2917 `{' is recognized if the last token as WORD and the token
28ef6c31
JA
2918 before that was FUNCTION, or if we just parsed an arithmetic
2919 `for' command.
ccc6cda3 2920
28ef6c31 2921 `}' is recognized if there is an unclosed `{' present.
cce855bc
JA
2922
2923 `-p' is returned as TIMEOPT if the last read token was TIME.
495aee44 2924 `--' is returned as TIMEIGN if the last read token was TIMEOPT.
cce855bc
JA
2925
2926 ']]' is returned as COND_END if the parser is currently parsing
2927 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
2928
2929 `time' is returned as TIME if and only if it is immediately
2930 preceded by one of `;', `\n', `||', `&&', or `&'.
ccc6cda3
JA
2931*/
2932
2933static int
f73dda09
JA
2934special_case_tokens (tokstr)
2935 char *tokstr;
ccc6cda3
JA
2936{
2937 if ((last_read_token == WORD) &&
2938#if defined (SELECT_COMMAND)
2939 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
2940#else
2941 ((token_before_that == FOR) || (token_before_that == CASE)) &&
2942#endif
f73dda09 2943 (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
726f6388 2944 {
ccc6cda3
JA
2945 if (token_before_that == CASE)
2946 {
2947 parser_state |= PST_CASEPAT;
2948 esacs_needed_count++;
2949 }
2950 return (IN);
2951 }
726f6388 2952
ccc6cda3
JA
2953 if (last_read_token == WORD &&
2954#if defined (SELECT_COMMAND)
2955 (token_before_that == FOR || token_before_that == SELECT) &&
2956#else
2957 (token_before_that == FOR) &&
2958#endif
f73dda09 2959 (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
ccc6cda3
JA
2960 return (DO);
2961
2962 /* Ditto for ESAC in the CASE case.
2963 Specifically, this handles "case word in esac", which is a legal
2964 construct, certainly because someone will pass an empty arg to the
2965 case construct, and we don't want it to barf. Of course, we should
2966 insist that the case construct has at least one pattern in it, but
2967 the designers disagree. */
2968 if (esacs_needed_count)
2969 {
2970 esacs_needed_count--;
f73dda09 2971 if (STREQ (tokstr, "esac"))
726f6388 2972 {
ccc6cda3
JA
2973 parser_state &= ~PST_CASEPAT;
2974 return (ESAC);
726f6388 2975 }
ccc6cda3 2976 }
726f6388 2977
ccc6cda3
JA
2978 /* The start of a shell function definition. */
2979 if (parser_state & PST_ALLOWOPNBRC)
2980 {
2981 parser_state &= ~PST_ALLOWOPNBRC;
f73dda09 2982 if (tokstr[0] == '{' && tokstr[1] == '\0') /* } */
726f6388 2983 {
ccc6cda3
JA
2984 open_brace_count++;
2985 function_bstart = line_number;
2986 return ('{'); /* } */
726f6388 2987 }
ccc6cda3
JA
2988 }
2989
28ef6c31
JA
2990 /* We allow a `do' after a for ((...)) without an intervening
2991 list_terminator */
f73dda09 2992 if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
28ef6c31 2993 return (DO);
f73dda09 2994 if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0') /* } */
28ef6c31
JA
2995 {
2996 open_brace_count++;
2997 return ('{'); /* } */
2998 }
2999
f73dda09 3000 if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
ccc6cda3
JA
3001 {
3002 open_brace_count--; /* { */
3003 return ('}');
3004 }
3005
cce855bc 3006#if defined (COMMAND_TIMING)
ccc6cda3 3007 /* Handle -p after `time'. */
f73dda09 3008 if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
ccc6cda3 3009 return (TIMEOPT);
495aee44
CR
3010 /* Handle -- after `time -p'. */
3011 if (last_read_token == TIMEOPT && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2])
3012 return (TIMEIGN);
b80f6443 3013#endif
cce855bc
JA
3014
3015#if defined (COND_COMMAND) /* [[ */
f73dda09 3016 if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
cce855bc
JA
3017 return (COND_END);
3018#endif
726f6388 3019
ccc6cda3
JA
3020 return (-1);
3021}
3022
3023/* Called from shell.c when Control-C is typed at top level. Or
3024 by the error rule at top level. */
3025void
3026reset_parser ()
3027{
3028 dstack.delimiter_depth = 0; /* No delimiters found so far. */
3029 open_brace_count = 0;
3030
0001803f
CR
3031#if defined (EXTENDED_GLOB)
3032 /* Reset to global value of extended glob */
3033 if (parser_state & PST_EXTPAT)
3034 extended_glob = global_extglob;
3035#endif
3036
ccc6cda3 3037 parser_state = 0;
a0c0a00f 3038 here_doc_first_line = 0;
ccc6cda3 3039
cce855bc 3040#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
ccc6cda3 3041 if (pushed_string_list)
cce855bc
JA
3042 free_string_list ();
3043#endif /* ALIAS || DPAREN_ARITHMETIC */
726f6388 3044
a0c0a00f 3045 /* This is where we resynchronize to the next newline on error/reset */
ccc6cda3
JA
3046 if (shell_input_line)
3047 {
3048 free (shell_input_line);
3049 shell_input_line = (char *)NULL;
3050 shell_input_line_size = shell_input_line_index = 0;
3051 }
3052
3053 FREE (word_desc_to_read);
3054 word_desc_to_read = (WORD_DESC *)NULL;
3055
836a17be
CR
3056 eol_ungetc_lookahead = 0;
3057
89a92869 3058 current_token = '\n'; /* XXX */
ccc6cda3
JA
3059 last_read_token = '\n';
3060 token_to_read = '\n';
3061}
3062
3063/* Read the next token. Command can be READ (normal operation) or
3064 RESET (to normalize state). */
3065static int
3066read_token (command)
3067 int command;
3068{
3069 int character; /* Current character. */
3070 int peek_char; /* Temporary look-ahead character. */
3071 int result; /* The thing to return. */
3072
3073 if (command == RESET)
3074 {
3075 reset_parser ();
726f6388
JA
3076 return ('\n');
3077 }
3078
3079 if (token_to_read)
3080 {
ccc6cda3
JA
3081 result = token_to_read;
3082 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
d166f048
JA
3083 {
3084 yylval.word = word_desc_to_read;
3085 word_desc_to_read = (WORD_DESC *)NULL;
3086 }
726f6388 3087 token_to_read = 0;
ccc6cda3 3088 return (result);
726f6388
JA
3089 }
3090
cce855bc
JA
3091#if defined (COND_COMMAND)
3092 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
3093 {
3094 cond_lineno = line_number;
3095 parser_state |= PST_CONDEXPR;
3096 yylval.command = parse_cond_command ();
3097 if (cond_token != COND_END)
3098 {
7117c2d2 3099 cond_error ();
cce855bc
JA
3100 return (-1);
3101 }
3102 token_to_read = COND_END;
3103 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
3104 return (COND_CMD);
3105 }
3106#endif
3107
726f6388 3108#if defined (ALIAS)
726f6388
JA
3109 /* This is a place to jump back to once we have successfully expanded a
3110 token with an alias and pushed the string with push_string () */
3111 re_read_token:
726f6388
JA
3112#endif /* ALIAS */
3113
3114 /* Read a single word from input. Start by skipping blanks. */
0628567a 3115 while ((character = shell_getc (1)) != EOF && shellblank (character))
ccc6cda3 3116 ;
726f6388
JA
3117
3118 if (character == EOF)
3119 {
3120 EOF_Reached = 1;
3121 return (yacc_EOF);
3122 }
3123
7117c2d2 3124 if MBTEST(character == '#' && (!interactive || interactive_comments))
726f6388
JA
3125 {
3126 /* A comment. Discard until EOL or EOF, and then return a newline. */
3127 discard_until ('\n');
3128 shell_getc (0);
ccc6cda3 3129 character = '\n'; /* this will take the next if statement and return. */
726f6388
JA
3130 }
3131
3132 if (character == '\n')
3133 {
3134 /* If we're about to return an unquoted newline, we can go and collect
3135 the text of any pending here document. */
3136 if (need_here_doc)
3137 gather_here_documents ();
3138
3139#if defined (ALIAS)
ccc6cda3 3140 parser_state &= ~PST_ALEXPNEXT;
726f6388
JA
3141#endif /* ALIAS */
3142
95732b49
JA
3143 parser_state &= ~PST_ASSIGNOK;
3144
726f6388
JA
3145 return (character);
3146 }
3147
f1be666c
JA
3148 if (parser_state & PST_REGEXP)
3149 goto tokword;
3150
ccc6cda3 3151 /* Shell meta-characters. */
7117c2d2 3152 if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
726f6388
JA
3153 {
3154#if defined (ALIAS)
3155 /* Turn off alias tokenization iff this character sequence would
3156 not leave us ready to read a command. */
3157 if (character == '<' || character == '>')
ccc6cda3 3158 parser_state &= ~PST_ALEXPNEXT;
726f6388
JA
3159#endif /* ALIAS */
3160
95732b49
JA
3161 parser_state &= ~PST_ASSIGNOK;
3162
a0c0a00f
CR
3163 /* If we are parsing a command substitution and we have read a character
3164 that marks the end of it, don't bother to skip over quoted newlines
3165 when we read the next token. We're just interested in a character
3166 that will turn this into a two-character token, so we let the higher
3167 layers deal with quoted newlines following the command substitution. */
3168 if ((parser_state & PST_CMDSUBST) && character == shell_eof_token)
3169 peek_char = shell_getc (0);
3170 else
3171 peek_char = shell_getc (1);
3172
ccc6cda3 3173 if (character == peek_char)
726f6388
JA
3174 {
3175 switch (character)
3176 {
ccc6cda3 3177 case '<':
726f6388
JA
3178 /* If '<' then we could be at "<<" or at "<<-". We have to
3179 look ahead one more character. */
726f6388 3180 peek_char = shell_getc (1);
3185942a 3181 if MBTEST(peek_char == '-')
726f6388 3182 return (LESS_LESS_MINUS);
3185942a 3183 else if MBTEST(peek_char == '<')
7117c2d2 3184 return (LESS_LESS_LESS);
726f6388
JA
3185 else
3186 {
3187 shell_ungetc (peek_char);
3188 return (LESS_LESS);
3189 }
3190
3191 case '>':
3192 return (GREATER_GREATER);
3193
3194 case ';':
ccc6cda3 3195 parser_state |= PST_CASEPAT;
726f6388 3196#if defined (ALIAS)
ccc6cda3 3197 parser_state &= ~PST_ALEXPNEXT;
726f6388 3198#endif /* ALIAS */
95732b49 3199
3185942a
JA
3200 peek_char = shell_getc (1);
3201 if MBTEST(peek_char == '&')
3202 return (SEMI_SEMI_AND);
3203 else
3204 {
3205 shell_ungetc (peek_char);
3206 return (SEMI_SEMI);
3207 }
726f6388
JA
3208
3209 case '&':
3210 return (AND_AND);
3211
3212 case '|':
3213 return (OR_OR);
ccc6cda3 3214
bb70624e 3215#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
ccc6cda3 3216 case '(': /* ) */
7117c2d2
JA
3217 result = parse_dparen (character);
3218 if (result == -2)
3219 break;
3220 else
3221 return result;
ccc6cda3 3222#endif
726f6388 3223 }
726f6388 3224 }
7117c2d2 3225 else if MBTEST(character == '<' && peek_char == '&')
ccc6cda3 3226 return (LESS_AND);
7117c2d2 3227 else if MBTEST(character == '>' && peek_char == '&')
ccc6cda3 3228 return (GREATER_AND);
7117c2d2 3229 else if MBTEST(character == '<' && peek_char == '>')
ccc6cda3 3230 return (LESS_GREATER);
7117c2d2 3231 else if MBTEST(character == '>' && peek_char == '|')
ccc6cda3 3232 return (GREATER_BAR);
3185942a
JA
3233 else if MBTEST(character == '&' && peek_char == '>')
3234 {
3235 peek_char = shell_getc (1);
3236 if MBTEST(peek_char == '>')
3237 return (AND_GREATER_GREATER);
3238 else
3239 {
3240 shell_ungetc (peek_char);
3241 return (AND_GREATER);
3242 }
3243 }
3244 else if MBTEST(character == '|' && peek_char == '&')
3245 return (BAR_AND);
3246 else if MBTEST(character == ';' && peek_char == '&')
3247 {
3248 parser_state |= PST_CASEPAT;
3249#if defined (ALIAS)
3250 parser_state &= ~PST_ALEXPNEXT;
3251#endif /* ALIAS */
3252 return (SEMI_AND);
3253 }
ccc6cda3 3254
726f6388
JA
3255 shell_ungetc (peek_char);
3256
3257 /* If we look like we are reading the start of a function
3258 definition, then let the reader know about it so that
3259 we will do the right thing with `{'. */
7117c2d2 3260 if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
726f6388 3261 {
ccc6cda3 3262 parser_state |= PST_ALLOWOPNBRC;
726f6388 3263#if defined (ALIAS)
ccc6cda3 3264 parser_state &= ~PST_ALEXPNEXT;
726f6388 3265#endif /* ALIAS */
ccc6cda3 3266 function_dstart = line_number;
726f6388
JA
3267 }
3268
ccc6cda3
JA
3269 /* case pattern lists may be preceded by an optional left paren. If
3270 we're not trying to parse a case pattern list, the left paren
3271 indicates a subshell. */
7117c2d2 3272 if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
ccc6cda3
JA
3273 parser_state |= PST_SUBSHELL;
3274 /*(*/
7117c2d2 3275 else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
28ef6c31 3276 parser_state &= ~PST_CASEPAT;
ccc6cda3 3277 /*(*/
7117c2d2 3278 else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
ccc6cda3 3279 parser_state &= ~PST_SUBSHELL;
726f6388
JA
3280
3281#if defined (PROCESS_SUBSTITUTION)
3282 /* Check for the constructs which introduce process substitution.
3283 Shells running in `posix mode' don't do process substitution. */
7117c2d2 3284 if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
726f6388
JA
3285#endif /* PROCESS_SUBSTITUTION */
3286 return (character);
3287 }
3288
7117c2d2
JA
3289 /* Hack <&- (close stdin) case. Also <&N- (dup and close). */
3290 if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
ccc6cda3
JA
3291 return (character);
3292
f1be666c 3293tokword:
726f6388
JA
3294 /* Okay, if we got this far, we have to read a word. Read one,
3295 and then check it against the known ones. */
ccc6cda3
JA
3296 result = read_token_word (character);
3297#if defined (ALIAS)
3298 if (result == RE_READ_TOKEN)
3299 goto re_read_token;
3300#endif
3301 return result;
3302}
726f6388 3303
7117c2d2
JA
3304/*
3305 * Match a $(...) or other grouping construct. This has to handle embedded
3306 * quoted strings ('', ``, "") and nested constructs. It also must handle
95732b49
JA
3307 * reprompting the user, if necessary, after reading a newline, and returning
3308 * correct error values if it reads EOF.
7117c2d2 3309 */
495aee44
CR
3310#define P_FIRSTCLOSE 0x0001
3311#define P_ALLOWESC 0x0002
3312#define P_DQUOTE 0x0004
3313#define P_COMMAND 0x0008 /* parsing a command, so look for comments */
3314#define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */
3315#define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */
3316#define P_DOLBRACE 0x0040 /* parsing a ${...} construct */
b72432fd 3317
3185942a
JA
3318/* Lexical state while parsing a grouping construct or $(...). */
3319#define LEX_WASDOL 0x001
3320#define LEX_CKCOMMENT 0x002
3321#define LEX_INCOMMENT 0x004
3322#define LEX_PASSNEXT 0x008
3323#define LEX_RESWDOK 0x010
3324#define LEX_CKCASE 0x020
3325#define LEX_INCASE 0x040
3326#define LEX_INHEREDOC 0x080
3327#define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
3328#define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
a0c0a00f
CR
3329#define LEX_QUOTEDDOC 0x400 /* here doc with quoted delim */
3330#define LEX_INWORD 0x800
3185942a
JA
3331
3332#define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
3333
3334#define CHECK_NESTRET_ERROR() \
3335 do { \
3336 if (nestret == &matched_pair_error) \
3337 { \
3338 free (ret); \
3339 return &matched_pair_error; \
3340 } \
3341 } while (0)
3342
3343#define APPEND_NESTRET() \
3344 do { \
3345 if (nestlen) \
3346 { \
3347 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \
3348 strcpy (ret + retind, nestret); \
3349 retind += nestlen; \
3350 } \
3351 } while (0)
3352
ccc6cda3 3353static char matched_pair_error;
3185942a 3354
ccc6cda3
JA
3355static char *
3356parse_matched_pair (qc, open, close, lenp, flags)
3357 int qc; /* `"' if this construct is within double quotes */
3358 int open, close;
3359 int *lenp, flags;
3360{
3185942a
JA
3361 int count, ch, tflags;
3362 int nestlen, ttranslen, start_lineno;
28ef6c31 3363 char *ret, *nestret, *ttrans;
b80f6443 3364 int retind, retsize, rflags;
495aee44
CR
3365 int dolbrace_state;
3366
3367 dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0;
726f6388 3368
0001803f 3369/*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/
ccc6cda3 3370 count = 1;
3185942a
JA
3371 tflags = 0;
3372
3373 if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3374 tflags |= LEX_CKCOMMENT;
726f6388 3375
b80f6443
JA
3376 /* RFLAGS is the set of flags we want to pass to recursive calls. */
3377 rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
3378
f73dda09 3379 ret = (char *)xmalloc (retsize = 64);
ccc6cda3 3380 retind = 0;
726f6388 3381
ccc6cda3
JA
3382 start_lineno = line_number;
3383 while (count)
3384 {
495aee44 3385 ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
0628567a 3386
ccc6cda3
JA
3387 if (ch == EOF)
3388 {
3389 free (ret);
b80f6443 3390 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
ccc6cda3
JA
3391 EOF_Reached = 1; /* XXX */
3392 return (&matched_pair_error);
3393 }
726f6388 3394
ccc6cda3 3395 /* Possible reprompting. */
b80f6443 3396 if (ch == '\n' && SHOULD_PROMPT ())
ccc6cda3 3397 prompt_again ();
726f6388 3398
3185942a
JA
3399 /* Don't bother counting parens or doing anything else if in a comment
3400 or part of a case statement */
3401 if (tflags & LEX_INCOMMENT)
95732b49
JA
3402 {
3403 /* Add this character. */
3404 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3405 ret[retind++] = ch;
3406
3407 if (ch == '\n')
3185942a 3408 tflags &= ~LEX_INCOMMENT;
95732b49
JA
3409
3410 continue;
3411 }
3185942a 3412
0628567a
JA
3413 /* Not exactly right yet, should handle shell metacharacters, too. If
3414 any changes are made to this test, make analogous changes to subst.c:
3415 extract_delimited_string(). */
3185942a
JA
3416 else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
3417 tflags |= LEX_INCOMMENT;
0628567a 3418
3185942a 3419 if (tflags & LEX_PASSNEXT) /* last char was backslash */
ccc6cda3 3420 {
3185942a 3421 tflags &= ~LEX_PASSNEXT;
ccc6cda3
JA
3422 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3423 {
3185942a
JA
3424 if (retind > 0)
3425 retind--; /* swallow previously-added backslash */
ccc6cda3
JA
3426 continue;
3427 }
726f6388 3428
ccc6cda3 3429 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
ac50fbac 3430 if MBTEST(ch == CTLESC)
ccc6cda3
JA
3431 ret[retind++] = CTLESC;
3432 ret[retind++] = ch;
3433 continue;
3434 }
3185942a
JA
3435 /* If we're reparsing the input (e.g., from parse_string_to_word_list),
3436 we've already prepended CTLESC to single-quoted results of $'...'.
3437 We may want to do this for other CTLESC-quoted characters in
3438 reparse, too. */
3439 else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL))
3440 {
3441 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3442 ret[retind++] = ch;
3443 continue;
3444 }
7117c2d2 3445 else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
ccc6cda3
JA
3446 {
3447 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
3448 ret[retind++] = CTLESC;
3449 ret[retind++] = ch;
3450 continue;
3451 }
7117c2d2 3452 else if MBTEST(ch == close) /* ending delimiter */
ccc6cda3 3453 count--;
bb70624e 3454 /* handle nested ${...} specially. */
3185942a 3455 else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */
28ef6c31 3456 count++;
7117c2d2 3457 else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
ccc6cda3 3458 count++;
726f6388 3459
ccc6cda3
JA
3460 /* Add this character. */
3461 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3462 ret[retind++] = ch;
726f6388 3463
3185942a
JA
3464 /* If we just read the ending character, don't bother continuing. */
3465 if (count == 0)
3466 break;
3467
ccc6cda3 3468 if (open == '\'') /* '' inside grouping construct */
bb70624e 3469 {
7117c2d2 3470 if MBTEST((flags & P_ALLOWESC) && ch == '\\')
3185942a 3471 tflags |= LEX_PASSNEXT;
bb70624e
JA
3472 continue;
3473 }
726f6388 3474
7117c2d2 3475 if MBTEST(ch == '\\') /* backslashes */
3185942a
JA
3476 tflags |= LEX_PASSNEXT;
3477
495aee44
CR
3478 /* Based on which dolstate is currently in (param, op, or word),
3479 decide what the op is. We're really only concerned if it's % or
3480 #, so we can turn on a flag that says whether or not we should
3481 treat single quotes as special when inside a double-quoted
3482 ${...}. This logic must agree with subst.c:extract_dollar_brace_string
3483 since they share the same defines. */
ac50fbac 3484 /* FLAG POSIX INTERP 221 */
495aee44
CR
3485 if (flags & P_DOLBRACE)
3486 {
3487 /* ${param%[%]word} */
3488 if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1)
3489 dolbrace_state = DOLBRACE_QUOTE;
3490 /* ${param#[#]word} */
3491 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1)
3492 dolbrace_state = DOLBRACE_QUOTE;
3493 /* ${param/[/]pat/rep} */
3494 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '/' && retind > 1)
ac50fbac 3495 dolbrace_state = DOLBRACE_QUOTE2; /* XXX */
495aee44
CR
3496 /* ${param^[^]pat} */
3497 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '^' && retind > 1)
3498 dolbrace_state = DOLBRACE_QUOTE;
3499 /* ${param,[,]pat} */
3500 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1)
3501 dolbrace_state = DOLBRACE_QUOTE;
3502 else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0)
3503 dolbrace_state = DOLBRACE_OP;
3504 else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0)
3505 dolbrace_state = DOLBRACE_WORD;
3506 }
3507
3185942a 3508 /* The big hammer. Single quotes aren't special in double quotes. The
495aee44 3509 problem is that Posix used to say the single quotes are semi-special:
3185942a
JA
3510 within a double-quoted ${...} construct "an even number of
3511 unescaped double-quotes or single-quotes, if any, shall occur." */
495aee44 3512 /* This was changed in Austin Group Interp 221 */
bc63a081 3513 if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2 && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'')
3185942a 3514 continue;
726f6388 3515
3185942a
JA
3516 /* Could also check open == '`' if we want to parse grouping constructs
3517 inside old-style command substitution. */
ccc6cda3
JA
3518 if (open != close) /* a grouping construct */
3519 {
7117c2d2 3520 if MBTEST(shellquote (ch))
ccc6cda3
JA
3521 {
3522 /* '', ``, or "" inside $(...) or other grouping construct. */
3523 push_delimiter (dstack, ch);
3185942a 3524 if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */
b80f6443 3525 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
28ef6c31 3526 else
b80f6443 3527 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
ccc6cda3 3528 pop_delimiter (dstack);
3185942a
JA
3529 CHECK_NESTRET_ERROR ();
3530
3531 if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
28ef6c31
JA
3532 {
3533 /* Translate $'...' here. */
3534 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
f73dda09 3535 xfree (nestret);
95732b49 3536
ac50fbac
CR
3537 /* If we're parsing a double-quoted brace expansion and we are
3538 not in a place where single quotes are treated specially,
3539 make sure we single-quote the results of the ansi
3540 expansion because quote removal should remove them later */
3541 /* FLAG POSIX INTERP 221 */
3542 if ((shell_compatibility_level > 42) && (rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2) && (flags & P_DOLBRACE))
3543 {
3544 nestret = sh_single_quote (ttrans);
3545 free (ttrans);
3546 nestlen = strlen (nestret);
3547 }
3548 else if ((rflags & P_DQUOTE) == 0)
95732b49
JA
3549 {
3550 nestret = sh_single_quote (ttrans);
3551 free (ttrans);
3552 nestlen = strlen (nestret);
3553 }
3554 else
3555 {
3556 nestret = ttrans;
3557 nestlen = ttranslen;
3558 }
28ef6c31
JA
3559 retind -= 2; /* back up before the $' */
3560 }
3185942a 3561 else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
28ef6c31
JA
3562 {
3563 /* Locale expand $"..." here. */
3564 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
f73dda09 3565 xfree (nestret);
95732b49
JA
3566
3567 nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
28ef6c31 3568 free (ttrans);
95732b49 3569 nestlen = ttranslen + 2;
28ef6c31
JA
3570 retind -= 2; /* back up before the $" */
3571 }
7117c2d2 3572
3185942a 3573 APPEND_NESTRET ();
ccc6cda3
JA
3574 FREE (nestret);
3575 }
a0c0a00f 3576 else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
89a92869 3577 goto parse_dollar_word;
ccc6cda3
JA
3578 }
3579 /* Parse an old-style command substitution within double quotes as a
3580 single word. */
3581 /* XXX - sh and ksh93 don't do this - XXX */
7117c2d2 3582 else if MBTEST(open == '"' && ch == '`')
ccc6cda3 3583 {
b80f6443 3584 nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
3185942a
JA
3585
3586 CHECK_NESTRET_ERROR ();
3587 APPEND_NESTRET ();
3588
3589 FREE (nestret);
3590 }
3591 else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
3592 /* check for $(), $[], or ${} inside quoted string. */
3593 {
89a92869 3594parse_dollar_word:
3185942a
JA
3595 if (open == ch) /* undo previous increment */
3596 count--;
3597 if (ch == '(') /* ) */
3598 nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
3599 else if (ch == '{') /* } */
495aee44 3600 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
3185942a
JA
3601 else if (ch == '[') /* ] */
3602 nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
3603
3604 CHECK_NESTRET_ERROR ();
3605 APPEND_NESTRET ();
3606
3607 FREE (nestret);
3608 }
3609 if MBTEST(ch == '$')
3610 tflags |= LEX_WASDOL;
3611 else
3612 tflags &= ~LEX_WASDOL;
3613 }
3614
3615 ret[retind] = '\0';
3616 if (lenp)
3617 *lenp = retind;
0001803f 3618/*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/
3185942a
JA
3619 return ret;
3620}
3621
a0c0a00f
CR
3622#if defined (DEBUG)
3623static void
3624dump_tflags (flags)
3625 int flags;
3626{
3627 int f;
3628
3629 f = flags;
3630 fprintf (stderr, "%d -> ", f);
3631 if (f & LEX_WASDOL)
3632 {
3633 f &= ~LEX_WASDOL;
3634 fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
3635 }
3636 if (f & LEX_CKCOMMENT)
3637 {
3638 f &= ~LEX_CKCOMMENT;
3639 fprintf (stderr, "LEX_CKCOMMENT%s", f ? "|" : "");
3640 }
3641 if (f & LEX_INCOMMENT)
3642 {
3643 f &= ~LEX_INCOMMENT;
3644 fprintf (stderr, "LEX_INCOMMENT%s", f ? "|" : "");
3645 }
3646 if (f & LEX_PASSNEXT)
3647 {
3648 f &= ~LEX_PASSNEXT;
3649 fprintf (stderr, "LEX_PASSNEXT%s", f ? "|" : "");
3650 }
3651 if (f & LEX_RESWDOK)
3652 {
3653 f &= ~LEX_RESWDOK;
3654 fprintf (stderr, "LEX_RESWDOK%s", f ? "|" : "");
3655 }
3656 if (f & LEX_CKCASE)
3657 {
3658 f &= ~LEX_CKCASE;
3659 fprintf (stderr, "LEX_CKCASE%s", f ? "|" : "");
3660 }
3661 if (f & LEX_INCASE)
3662 {
3663 f &= ~LEX_INCASE;
3664 fprintf (stderr, "LEX_INCASE%s", f ? "|" : "");
3665 }
3666 if (f & LEX_INHEREDOC)
3667 {
3668 f &= ~LEX_INHEREDOC;
3669 fprintf (stderr, "LEX_INHEREDOC%s", f ? "|" : "");
3670 }
3671 if (f & LEX_HEREDELIM)
3672 {
3673 f &= ~LEX_HEREDELIM;
3674 fprintf (stderr, "LEX_HEREDELIM%s", f ? "|" : "");
3675 }
3676 if (f & LEX_STRIPDOC)
3677 {
3678 f &= ~LEX_STRIPDOC;
3679 fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
3680 }
3681 if (f & LEX_QUOTEDDOC)
3682 {
3683 f &= ~LEX_QUOTEDDOC;
3684 fprintf (stderr, "LEX_QUOTEDDOC%s", f ? "|" : "");
3685 }
3686 if (f & LEX_INWORD)
3687 {
3688 f &= ~LEX_INWORD;
3689 fprintf (stderr, "LEX_INWORD%s", f ? "|" : "");
3690 }
3691
3692 fprintf (stderr, "\n");
3693 fflush (stderr);
3694}
3695#endif
3696
3185942a
JA
3697/* Parse a $(...) command substitution. This is messier than I'd like, and
3698 reproduces a lot more of the token-reading code than I'd like. */
3699static char *
3700parse_comsub (qc, open, close, lenp, flags)
3701 int qc; /* `"' if this construct is within double quotes */
3702 int open, close;
3703 int *lenp, flags;
3704{
89a92869 3705 int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
3185942a
JA
3706 int nestlen, ttranslen, start_lineno;
3707 char *ret, *nestret, *ttrans, *heredelim;
3708 int retind, retsize, rflags, hdlen;
3709
495aee44
CR
3710 /* Posix interp 217 says arithmetic expressions have precedence, so
3711 assume $(( introduces arithmetic expansion and parse accordingly. */
3712 peekc = shell_getc (0);
3713 shell_ungetc (peekc);
3714 if (peekc == '(')
3715 return (parse_matched_pair (qc, open, close, lenp, 0));
3716
3185942a
JA
3717/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
3718 count = 1;
3719 tflags = LEX_RESWDOK;
3720
3721 if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
3722 tflags |= LEX_CKCASE;
3723 if ((tflags & LEX_CKCASE) && (interactive == 0 || interactive_comments))
3724 tflags |= LEX_CKCOMMENT;
3725
3726 /* RFLAGS is the set of flags we want to pass to recursive calls. */
3727 rflags = (flags & P_DQUOTE);
3728
3729 ret = (char *)xmalloc (retsize = 64);
3730 retind = 0;
3731
3732 start_lineno = line_number;
89a92869 3733 lex_rwlen = lex_wlen = 0;
3185942a
JA
3734
3735 heredelim = 0;
3736 lex_firstind = -1;
3737
3738 while (count)
3739 {
3740comsub_readchar:
495aee44 3741 ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT)) == 0);
3185942a
JA
3742
3743 if (ch == EOF)
3744 {
3745eof_error:
3746 free (ret);
3747 FREE (heredelim);
3748 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
3749 EOF_Reached = 1; /* XXX */
3750 return (&matched_pair_error);
3751 }
3752
3753 /* If we hit the end of a line and are reading the contents of a here
3754 document, and it's not the same line that the document starts on,
3755 check for this line being the here doc delimiter. Otherwise, if
3756 we're in a here document, mark the next character as the beginning
3757 of a line. */
3758 if (ch == '\n')
3759 {
3760 if ((tflags & LEX_HEREDELIM) && heredelim)
ccc6cda3 3761 {
3185942a
JA
3762 tflags &= ~LEX_HEREDELIM;
3763 tflags |= LEX_INHEREDOC;
3764 lex_firstind = retind + 1;
ccc6cda3 3765 }
3185942a 3766 else if (tflags & LEX_INHEREDOC)
ccc6cda3 3767 {
3185942a
JA
3768 int tind;
3769 tind = lex_firstind;
3770 while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
3771 tind++;
3772 if (STREQN (ret + tind, heredelim, hdlen))
3773 {
a0c0a00f 3774 tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
3185942a 3775/*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
0001803f
CR
3776 free (heredelim);
3777 heredelim = 0;
3185942a
JA
3778 lex_firstind = -1;
3779 }
3780 else
3781 lex_firstind = retind + 1;
ccc6cda3 3782 }
ccc6cda3 3783 }
3185942a
JA
3784
3785 /* Possible reprompting. */
3786 if (ch == '\n' && SHOULD_PROMPT ())
3787 prompt_again ();
3788
0001803f
CR
3789 /* XXX -- possibly allow here doc to be delimited by ending right
3790 paren. */
3791 if ((tflags & LEX_INHEREDOC) && ch == close && count == 1)
3792 {
3793 int tind;
a0c0a00f 3794/*itrace("parse_comsub:%d: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", line_number, retind-lex_firstind, hdlen, retind);*/
0001803f
CR
3795 tind = lex_firstind;
3796 while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
3797 tind++;
3798 if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
3799 {
a0c0a00f
CR
3800 tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
3801/*itrace("parse_comsub:%d: found here doc end `%*s'", line_number, hdlen, ret + tind);*/
0001803f
CR
3802 free (heredelim);
3803 heredelim = 0;
3804 lex_firstind = -1;
3805 }
3806 }
3807
a0c0a00f
CR
3808 /* Don't bother counting parens or doing anything else if in a comment or
3809 here document (not exactly right for here-docs -- if we want to allow
3810 recursive calls to parse_comsub to have their own here documents,
3811 change the LEX_INHEREDOC to LEX_QUOTEDDOC here and uncomment the next
3812 clause below. Note that to make this work completely, we need to make
3813 additional changes to allow xparse_dolparen to work right when the
3814 command substitution is parsed, because read_secondary_line doesn't know
3815 to recursively parse through command substitutions embedded in here-
3816 documents */
3185942a
JA
3817 if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC))
3818 {
3819 /* Add this character. */
3820 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3821 ret[retind++] = ch;
3822
3823 if ((tflags & LEX_INCOMMENT) && ch == '\n')
ac50fbac 3824 {
0001803f 3825/*itrace("parse_comsub:%d: lex_incomment -> 0 ch = `%c'", line_number, ch);*/
ac50fbac
CR
3826 tflags &= ~LEX_INCOMMENT;
3827 }
3185942a
JA
3828
3829 continue;
3830 }
a0c0a00f
CR
3831#if 0
3832 /* If we're going to recursively parse a command substitution inside a
3833 here-document, make sure we call parse_comsub recursively below. See
3834 above for additional caveats. */
3835 if ((tflags & LEX_INHEREDOC) && ((tflags & LEX_WASDOL) == 0 || ch != '(')) /*)*/
3836 {
3837 /* Add this character. */
3838 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3839 ret[retind++] = ch;
3840 if MBTEST(ch == '$')
3841 tflags |= LEX_WASDOL;
3842 else
3843 tflags &= ~LEX_WASDOL;
3844 }
3845#endif
3185942a 3846
89a92869
CR
3847 if (tflags & LEX_PASSNEXT) /* last char was backslash */
3848 {
3849/*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3850 tflags &= ~LEX_PASSNEXT;
3851 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
3852 {
3853 if (retind > 0)
3854 retind--; /* swallow previously-added backslash */
3855 continue;
3856 }
3857
3858 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
ac50fbac 3859 if MBTEST(ch == CTLESC)
89a92869
CR
3860 ret[retind++] = CTLESC;
3861 ret[retind++] = ch;
3862 continue;
3863 }
3864
3865 /* If this is a shell break character, we are not in a word. If not,
3866 we either start or continue a word. */
3867 if MBTEST(shellbreak (ch))
3868 {
3869 tflags &= ~LEX_INWORD;
3870/*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3871 }
3872 else
3873 {
3874 if (tflags & LEX_INWORD)
3875 {
3876 lex_wlen++;
3877/*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
3878 }
3879 else
3880 {
3881/*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
3882 tflags |= LEX_INWORD;
3883 lex_wlen = 0;
ae339e9c
CR
3884 if (tflags & LEX_RESWDOK)
3885 lex_rwlen = 0;
89a92869
CR
3886 }
3887 }
3888
3185942a 3889 /* Skip whitespace */
495aee44 3890 if MBTEST(shellblank (ch) && (tflags & LEX_HEREDELIM) == 0 && lex_rwlen == 0)
3185942a
JA
3891 {
3892 /* Add this character. */
3893 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3894 ret[retind++] = ch;
3895 continue;
3896 }
3897
3898 /* Either we are looking for the start of the here-doc delimiter
3899 (lex_firstind == -1) or we are reading one (lex_firstind >= 0).
3900 If this character is a shell break character and we are reading
3901 the delimiter, save it and note that we are now reading a here
3902 document. If we've found the start of the delimiter, note it by
3903 setting lex_firstind. Backslashes can quote shell metacharacters
3904 in here-doc delimiters. */
3905 if (tflags & LEX_HEREDELIM)
3906 {
3907 if (lex_firstind == -1 && shellbreak (ch) == 0)
3908 lex_firstind = retind;
0001803f
CR
3909#if 0
3910 else if (heredelim && (tflags & LEX_PASSNEXT) == 0 && ch == '\n')
3911 {
3912 tflags |= LEX_INHEREDOC;
3913 tflags &= ~LEX_HEREDELIM;
3914 lex_firstind = retind + 1;
3915 }
3916#endif
3185942a
JA
3917 else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch))
3918 {
0001803f
CR
3919 if (heredelim == 0)
3920 {
3921 nestret = substring (ret, lex_firstind, retind);
3922 heredelim = string_quote_removal (nestret, 0);
0001803f 3923 hdlen = STRLEN(heredelim);
3185942a 3924/*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/
a0c0a00f
CR
3925 if (STREQ (heredelim, nestret) == 0)
3926 tflags |= LEX_QUOTEDDOC;
3927 free (nestret);
0001803f 3928 }
3185942a
JA
3929 if (ch == '\n')
3930 {
3931 tflags |= LEX_INHEREDOC;
3932 tflags &= ~LEX_HEREDELIM;
3933 lex_firstind = retind + 1;
3934 }
3935 else
3936 lex_firstind = -1;
3937 }
3938 }
3939
3940 /* Meta-characters that can introduce a reserved word. Not perfect yet. */
89a92869 3941 if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n'))
95732b49 3942 {
3185942a
JA
3943 /* Add this character. */
3944 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3945 ret[retind++] = ch;
3946 peekc = shell_getc (1);
3947 if (ch == peekc && (ch == '&' || ch == '|' || ch == ';')) /* two-character tokens */
3948 {
3949 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3950 ret[retind++] = peekc;
0001803f 3951/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
3185942a
JA
3952 tflags |= LEX_RESWDOK;
3953 lex_rwlen = 0;
3954 continue;
3955 }
3956 else if (ch == '\n' || COMSUB_META(ch))
3957 {
3958 shell_ungetc (peekc);
3185942a 3959/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
0001803f 3960 tflags |= LEX_RESWDOK;
3185942a
JA
3961 lex_rwlen = 0;
3962 continue;
3963 }
3964 else if (ch == EOF)
3965 goto eof_error;
3966 else
3967 {
3968 /* `unget' the character we just added and fall through */
3969 retind--;
3970 shell_ungetc (peekc);
3971 }
95732b49 3972 }
3185942a
JA
3973
3974 /* If we can read a reserved word, try to read one. */
3975 if (tflags & LEX_RESWDOK)
3976 {
a0c0a00f 3977 if MBTEST(islower ((unsigned char)ch))
3185942a
JA
3978 {
3979 /* Add this character. */
3980 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
3981 ret[retind++] = ch;
3982 lex_rwlen++;
3983 continue;
3984 }
3985 else if MBTEST(lex_rwlen == 4 && shellbreak (ch))
3986 {
3987 if (STREQN (ret + retind - 4, "case", 4))
ac50fbac
CR
3988 {
3989 tflags |= LEX_INCASE;
a0c0a00f 3990 tflags &= ~LEX_RESWDOK;
0001803f 3991/*itrace("parse_comsub:%d: found `case', lex_incase -> 1 lex_reswdok -> 0", line_number);*/
ac50fbac 3992 }
3185942a 3993 else if (STREQN (ret + retind - 4, "esac", 4))
ac50fbac
CR
3994 {
3995 tflags &= ~LEX_INCASE;
a0c0a00f
CR
3996/*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 1", line_number);*/
3997 tflags |= LEX_RESWDOK;
3998 lex_rwlen = 0;
3999 }
4000 else if (STREQN (ret + retind - 4, "done", 4) ||
4001 STREQN (ret + retind - 4, "then", 4) ||
4002 STREQN (ret + retind - 4, "else", 4) ||
4003 STREQN (ret + retind - 4, "elif", 4) ||
4004 STREQN (ret + retind - 4, "time", 4))
4005 {
4006 /* these are four-character reserved words that can be
4007 followed by a reserved word; anything else turns off
4008 the reserved-word-ok flag */
4009/*itrace("parse_comsub:%d: found `%.4s', lex_reswdok -> 1", line_number, ret+retind-4);*/
4010 tflags |= LEX_RESWDOK;
4011 lex_rwlen = 0;
4012 }
4013 else
4014 {
4015 tflags &= ~LEX_RESWDOK;
4016/*itrace("parse_comsub:%d: found `%.4s', lex_reswdok -> 0", line_number, ret+retind-4);*/
ac50fbac 4017 }
3185942a 4018 }
89a92869
CR
4019 else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
4020 ; /* don't modify LEX_RESWDOK if we're starting a comment */
ac50fbac
CR
4021 /* Allow `do' followed by space, tab, or newline to preserve the
4022 RESWDOK flag, but reset the reserved word length counter so we
4023 can read another one. */
4024 else if MBTEST(((tflags & LEX_INCASE) == 0) &&
a0c0a00f 4025 (isblank((unsigned char)ch) || ch == '\n') &&
ac50fbac
CR
4026 lex_rwlen == 2 &&
4027 STREQN (ret + retind - 2, "do", 2))
4028 {
a0c0a00f 4029/*itrace("parse_comsub:%d: lex_incase == 0 found `%c', found \"do\"", line_number, ch);*/
ac50fbac
CR
4030 lex_rwlen = 0;
4031 }
89a92869
CR
4032 else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
4033 /* If we can read a reserved word and we're in case, we're at the
4034 point where we can read a new pattern list or an esac. We
4035 handle the esac case above. If we read a newline, we want to
4036 leave LEX_RESWDOK alone. If we read anything else, we want to
4037 turn off LEX_RESWDOK, since we're going to read a pattern list. */
ac50fbac
CR
4038 {
4039 tflags &= ~LEX_RESWDOK;
89a92869 4040/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/
ac50fbac 4041 }
89a92869 4042 else if MBTEST(shellbreak (ch) == 0)
ac50fbac
CR
4043 {
4044 tflags &= ~LEX_RESWDOK;
3185942a 4045/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
ac50fbac
CR
4046 }
4047#if 0
4048 /* If we find a space or tab but have read something and it's not
4049 `do', turn off the reserved-word-ok flag */
a0c0a00f 4050 else if MBTEST(isblank ((unsigned char)ch) && lex_rwlen > 0)
ac50fbac
CR
4051 {
4052 tflags &= ~LEX_RESWDOK;
4053/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
4054 }
4055#endif
3185942a
JA
4056 }
4057
0001803f 4058 /* Might be the start of a here-doc delimiter */
3185942a
JA
4059 if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
4060 {
4061 /* Add this character. */
4062 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4063 ret[retind++] = ch;
4064 peekc = shell_getc (1);
4065 if (peekc == EOF)
4066 goto eof_error;
4067 if (peekc == ch)
4068 {
4069 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4070 ret[retind++] = peekc;
4071 peekc = shell_getc (1);
4072 if (peekc == EOF)
4073 goto eof_error;
4074 if (peekc == '-')
4075 {
4076 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4077 ret[retind++] = peekc;
4078 tflags |= LEX_STRIPDOC;
4079 }
4080 else
4081 shell_ungetc (peekc);
89a92869
CR
4082 if (peekc != '<')
4083 {
4084 tflags |= LEX_HEREDELIM;
4085 lex_firstind = -1;
4086 }
3185942a
JA
4087 continue;
4088 }
4089 else
89a92869 4090 ch = peekc; /* fall through and continue XXX */
3185942a 4091 }
89a92869 4092 else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
ac50fbac 4093 {
89a92869 4094/*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
ac50fbac
CR
4095 tflags |= LEX_INCOMMENT;
4096 }
3185942a 4097
89a92869 4098 if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
3185942a
JA
4099 {
4100 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
4101 ret[retind++] = CTLESC;
4102 ret[retind++] = ch;
4103 continue;
4104 }
4105#if 0
4106 else if MBTEST((tflags & LEX_INCASE) && ch == close && close == ')')
4107 tflags &= ~LEX_INCASE; /* XXX */
0628567a 4108#endif
3185942a 4109 else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0) /* ending delimiter */
ac50fbac
CR
4110 {
4111 count--;
3185942a 4112/*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/
ac50fbac 4113 }
3185942a 4114 else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open) /* nested begin */
ac50fbac
CR
4115 {
4116 count++;
0001803f 4117/*itrace("parse_comsub:%d: found open: count = %d", line_number, count);*/
ac50fbac 4118 }
3185942a
JA
4119
4120 /* Add this character. */
4121 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
4122 ret[retind++] = ch;
4123
4124 /* If we just read the ending character, don't bother continuing. */
4125 if (count == 0)
4126 break;
4127
4128 if MBTEST(ch == '\\') /* backslashes */
4129 tflags |= LEX_PASSNEXT;
4130
4131 if MBTEST(shellquote (ch))
4132 {
4133 /* '', ``, or "" inside $(...). */
4134 push_delimiter (dstack, ch);
4135 if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */
4136 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
4137 else
4138 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
4139 pop_delimiter (dstack);
4140 CHECK_NESTRET_ERROR ();
4141
4142 if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
4143 {
4144 /* Translate $'...' here. */
4145 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
4146 xfree (nestret);
4147
4148 if ((rflags & P_DQUOTE) == 0)
4149 {
4150 nestret = sh_single_quote (ttrans);
4151 free (ttrans);
4152 nestlen = strlen (nestret);
4153 }
4154 else
4155 {
4156 nestret = ttrans;
4157 nestlen = ttranslen;
4158 }
4159 retind -= 2; /* back up before the $' */
4160 }
4161 else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
4162 {
4163 /* Locale expand $"..." here. */
4164 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
4165 xfree (nestret);
4166
4167 nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
4168 free (ttrans);
4169 nestlen = ttranslen + 2;
4170 retind -= 2; /* back up before the $" */
4171 }
4172
4173 APPEND_NESTRET ();
4174 FREE (nestret);
4175 }
4176 else if MBTEST((tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
4177 /* check for $(), $[], or ${} inside command substitution. */
ccc6cda3 4178 {
3185942a 4179 if ((tflags & LEX_INCASE) == 0 && open == ch) /* undo previous increment */
ccc6cda3
JA
4180 count--;
4181 if (ch == '(') /* ) */
3185942a 4182 nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE);
ccc6cda3 4183 else if (ch == '{') /* } */
495aee44 4184 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags);
ccc6cda3 4185 else if (ch == '[') /* ] */
b80f6443 4186 nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
95732b49 4187
3185942a
JA
4188 CHECK_NESTRET_ERROR ();
4189 APPEND_NESTRET ();
4190
4191 FREE (nestret);
ccc6cda3 4192 }
3185942a
JA
4193 if MBTEST(ch == '$')
4194 tflags |= LEX_WASDOL;
4195 else
4196 tflags &= ~LEX_WASDOL;
ccc6cda3 4197 }
726f6388 4198
3185942a 4199 FREE (heredelim);
ccc6cda3
JA
4200 ret[retind] = '\0';
4201 if (lenp)
4202 *lenp = retind;
3185942a
JA
4203/*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/
4204 return ret;
4205}
4206
495aee44 4207/* Recursively call the parser to parse a $(...) command substitution. */
3185942a
JA
4208char *
4209xparse_dolparen (base, string, indp, flags)
4210 char *base;
4211 char *string;
4212 int *indp;
4213 int flags;
4214{
4215 sh_parser_state_t ps;
b4839c27 4216 sh_input_line_state_t ls;
ac50fbac 4217 int orig_ind, nc, sflags, orig_eof_token;
3185942a
JA
4218 char *ret, *s, *ep, *ostring;
4219
4220 /*yydebug = 1;*/
4221 orig_ind = *indp;
4222 ostring = string;
4223
b4839c27 4224/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/
3185942a
JA
4225 sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE;
4226 if (flags & SX_NOLONGJMP)
4227 sflags |= SEVAL_NOLONGJMP;
4228 save_parser_state (&ps);
b4839c27 4229 save_input_line_state (&ls);
ac50fbac 4230 orig_eof_token = shell_eof_token;
3185942a
JA
4231
4232 /*(*/
4233 parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/
4234 shell_eof_token = ')';
a0c0a00f
CR
4235
4236 nc = parse_string (string, "command substitution", sflags, &ep);
3185942a 4237
ac50fbac 4238 shell_eof_token = orig_eof_token;
3185942a
JA
4239 restore_parser_state (&ps);
4240 reset_parser ();
b4839c27
CR
4241 /* reset_parser clears shell_input_line and associated variables */
4242 restore_input_line_state (&ls);
ca6a2ba4
CR
4243
4244 token_to_read = 0;
3185942a 4245
a0c0a00f
CR
4246 /* If parse_string returns < 0, we need to jump to top level with the
4247 negative of the return value */
4248 if (nc < 0)
4249 jump_to_top_level (-nc); /* XXX */
4250
3185942a
JA
4251 /* Need to find how many characters parse_and_execute consumed, update
4252 *indp, if flags != 0, copy the portion of the string parsed into RET
4253 and return it. If flags & 1 (EX_NOALLOC) we can return NULL. */
4254
4255 /*(*/
4256 if (ep[-1] != ')')
4257 {
4258#if DEBUG
4259 if (ep[-1] != '\n')
4260 itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep);
4261#endif
4262 while (ep > ostring && ep[-1] == '\n') ep--;
4263 }
4264
4265 nc = ep - ostring;
4266 *indp = ep - base - 1;
4267
4268 /*(*/
4269#if DEBUG
4270 if (base[*indp] != ')')
4271 itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base);
4272#endif
4273
4274 if (flags & SX_NOALLOC)
4275 return (char *)NULL;
4276
4277 if (nc == 0)
4278 {
4279 ret = xmalloc (1);
4280 ret[0] = '\0';
4281 }
4282 else
4283 ret = substring (ostring, 0, nc - 1);
4284
ccc6cda3
JA
4285 return ret;
4286}
726f6388 4287
bb70624e 4288#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
7117c2d2
JA
4289/* Parse a double-paren construct. It can be either an arithmetic
4290 command, an arithmetic `for' command, or a nested subshell. Returns
4291 the parsed token, -1 on error, or -2 if we didn't do anything and
4292 should just go on. */
4293static int
4294parse_dparen (c)
4295 int c;
4296{
0628567a
JA
4297 int cmdtyp, sline;
4298 char *wval;
7117c2d2
JA
4299 WORD_DESC *wd;
4300
4301#if defined (ARITH_FOR_COMMAND)
4302 if (last_read_token == FOR)
4303 {
4304 arith_for_lineno = line_number;
b80f6443 4305 cmdtyp = parse_arith_cmd (&wval, 0);
7117c2d2
JA
4306 if (cmdtyp == 1)
4307 {
95732b49
JA
4308 wd = alloc_word_desc ();
4309 wd->word = wval;
7117c2d2 4310 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
7117c2d2
JA
4311 return (ARITH_FOR_EXPRS);
4312 }
4313 else
4314 return -1; /* ERROR */
4315 }
4316#endif
4317
4318#if defined (DPAREN_ARITHMETIC)
4319 if (reserved_word_acceptable (last_read_token))
4320 {
4321 sline = line_number;
95732b49 4322
b80f6443 4323 cmdtyp = parse_arith_cmd (&wval, 0);
7117c2d2
JA
4324 if (cmdtyp == 1) /* arithmetic command */
4325 {
95732b49
JA
4326 wd = alloc_word_desc ();
4327 wd->word = wval;
4328 wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
7117c2d2 4329 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
7117c2d2
JA
4330 return (ARITH_CMD);
4331 }
4332 else if (cmdtyp == 0) /* nested subshell */
4333 {
4334 push_string (wval, 0, (alias_t *)NULL);
ac50fbac 4335 pushed_string_list->flags = PSH_DPAREN;
7117c2d2
JA
4336 if ((parser_state & PST_CASEPAT) == 0)
4337 parser_state |= PST_SUBSHELL;
4338 return (c);
4339 }
4340 else /* ERROR */
4341 return -1;
4342 }
4343#endif
4344
4345 return -2; /* XXX */
4346}
4347
d166f048
JA
4348/* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
4349 If not, assume it's a nested subshell for backwards compatibility and
4350 return 0. In any case, put the characters we've consumed into a locally-
4351 allocated buffer and make *ep point to that buffer. Return -1 on an
4352 error, for example EOF. */
4353static int
b80f6443 4354parse_arith_cmd (ep, adddq)
d166f048 4355 char **ep;
b80f6443 4356 int adddq;
d166f048
JA
4357{
4358 int exp_lineno, rval, c;
f73dda09 4359 char *ttok, *tokstr;
d166f048
JA
4360 int ttoklen;
4361
4362 exp_lineno = line_number;
4363 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
4364 rval = 1;
4365 if (ttok == &matched_pair_error)
4366 return -1;
4367 /* Check that the next character is the closing right paren. If
4368 not, this is a syntax error. ( */
7117c2d2
JA
4369 c = shell_getc (0);
4370 if MBTEST(c != ')')
d166f048
JA
4371 rval = 0;
4372
f73dda09 4373 tokstr = (char *)xmalloc (ttoklen + 4);
d166f048 4374
b80f6443
JA
4375 /* if ADDDQ != 0 then (( ... )) -> "..." */
4376 if (rval == 1 && adddq) /* arith cmd, add double quotes */
d166f048 4377 {
b80f6443
JA
4378 tokstr[0] = '"';
4379 strncpy (tokstr + 1, ttok, ttoklen - 1);
f73dda09
JA
4380 tokstr[ttoklen] = '"';
4381 tokstr[ttoklen+1] = '\0';
d166f048 4382 }
b80f6443 4383 else if (rval == 1) /* arith cmd, don't add double quotes */
d166f048 4384 {
b80f6443
JA
4385 strncpy (tokstr, ttok, ttoklen - 1);
4386 tokstr[ttoklen-1] = '\0';
4387 }
4388 else /* nested subshell */
4389 {
4390 tokstr[0] = '(';
4391 strncpy (tokstr + 1, ttok, ttoklen - 1);
f73dda09
JA
4392 tokstr[ttoklen] = ')';
4393 tokstr[ttoklen+1] = c;
4394 tokstr[ttoklen+2] = '\0';
d166f048 4395 }
b80f6443 4396
f73dda09 4397 *ep = tokstr;
d166f048
JA
4398 FREE (ttok);
4399 return rval;
4400}
bb70624e 4401#endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
d166f048 4402
cce855bc 4403#if defined (COND_COMMAND)
7117c2d2
JA
4404static void
4405cond_error ()
4406{
4407 char *etext;
4408
4409 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
b80f6443 4410 parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
7117c2d2
JA
4411 else if (cond_token != COND_ERROR)
4412 {
4413 if (etext = error_token_from_token (cond_token))
4414 {
b80f6443 4415 parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
7117c2d2
JA
4416 free (etext);
4417 }
4418 else
b80f6443 4419 parser_error (cond_lineno, _("syntax error in conditional expression"));
7117c2d2
JA
4420 }
4421}
4422
cce855bc
JA
4423static COND_COM *
4424cond_expr ()
4425{
4426 return (cond_or ());
4427}
4428
4429static COND_COM *
4430cond_or ()
4431{
4432 COND_COM *l, *r;
4433
4434 l = cond_and ();
4435 if (cond_token == OR_OR)
4436 {
4437 r = cond_or ();
4438 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
4439 }
4440 return l;
4441}
4442
4443static COND_COM *
4444cond_and ()
4445{
4446 COND_COM *l, *r;
4447
4448 l = cond_term ();
4449 if (cond_token == AND_AND)
4450 {
4451 r = cond_and ();
4452 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
4453 }
4454 return l;
4455}
4456
4457static int
4458cond_skip_newlines ()
4459{
4460 while ((cond_token = read_token (READ)) == '\n')
4461 {
b80f6443 4462 if (SHOULD_PROMPT ())
cce855bc
JA
4463 prompt_again ();
4464 }
4465 return (cond_token);
4466}
4467
4468#define COND_RETURN_ERROR() \
4469 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
4470
4471static COND_COM *
4472cond_term ()
4473{
4474 WORD_DESC *op;
4475 COND_COM *term, *tleft, *tright;
4476 int tok, lineno;
7117c2d2 4477 char *etext;
cce855bc
JA
4478
4479 /* Read a token. It can be a left paren, a `!', a unary operator, or a
4480 word that should be the first argument of a binary operator. Start by
4481 skipping newlines, since this is a compound command. */
4482 tok = cond_skip_newlines ();
4483 lineno = line_number;
4484 if (tok == COND_END)
4485 {
4486 COND_RETURN_ERROR ();
4487 }
4488 else if (tok == '(')
4489 {
4490 term = cond_expr ();
4491 if (cond_token != ')')
4492 {
4493 if (term)
4494 dispose_cond_node (term); /* ( */
7117c2d2
JA
4495 if (etext = error_token_from_token (cond_token))
4496 {
b80f6443 4497 parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
7117c2d2
JA
4498 free (etext);
4499 }
4500 else
b80f6443 4501 parser_error (lineno, _("expected `)'"));
cce855bc
JA
4502 COND_RETURN_ERROR ();
4503 }
4504 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
4505 (void)cond_skip_newlines ();
4506 }
4507 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
4508 {
4509 if (tok == WORD)
4510 dispose_word (yylval.word); /* not needed */
4511 term = cond_term ();
4512 if (term)
4513 term->flags |= CMD_INVERT_RETURN;
4514 }
3185942a 4515 else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[2] == 0 && test_unop (yylval.word->word))
cce855bc
JA
4516 {
4517 op = yylval.word;
4518 tok = read_token (READ);
4519 if (tok == WORD)
4520 {
4521 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4522 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4523 }
4524 else
4525 {
4526 dispose_word (op);
7117c2d2
JA
4527 if (etext = error_token_from_token (tok))
4528 {
b80f6443 4529 parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
7117c2d2
JA
4530 free (etext);
4531 }
4532 else
b80f6443 4533 parser_error (line_number, _("unexpected argument to conditional unary operator"));
cce855bc
JA
4534 COND_RETURN_ERROR ();
4535 }
4536
4537 (void)cond_skip_newlines ();
4538 }
bb70624e 4539 else if (tok == WORD) /* left argument to binary operator */
cce855bc
JA
4540 {
4541 /* lhs */
4542 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4543
4544 /* binop */
4545 tok = read_token (READ);
4546 if (tok == WORD && test_binop (yylval.word->word))
0001803f
CR
4547 {
4548 op = yylval.word;
4549 if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0')))
4550 parser_state |= PST_EXTPAT;
4551 else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0')
4552 parser_state |= PST_EXTPAT;
4553 }
b80f6443 4554#if defined (COND_REGEXP)
f1be666c
JA
4555 else if (tok == WORD && STREQ (yylval.word->word, "=~"))
4556 {
4557 op = yylval.word;
4558 parser_state |= PST_REGEXP;
4559 }
b80f6443 4560#endif
cce855bc 4561 else if (tok == '<' || tok == '>')
28ef6c31
JA
4562 op = make_word_from_token (tok); /* ( */
4563 /* There should be a check before blindly accepting the `)' that we have
4564 seen the opening `('. */
4565 else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
cce855bc
JA
4566 {
4567 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
4568 the test command. Similarly for [[ x && expr ]] or
28ef6c31 4569 [[ x || expr ]] or [[ (x) ]]. */
cce855bc
JA
4570 op = make_word ("-n");
4571 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
4572 cond_token = tok;
4573 return (term);
4574 }
4575 else
4576 {
7117c2d2
JA
4577 if (etext = error_token_from_token (tok))
4578 {
b80f6443 4579 parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
7117c2d2
JA
4580 free (etext);
4581 }
4582 else
b80f6443 4583 parser_error (line_number, _("conditional binary operator expected"));
cce855bc
JA
4584 dispose_cond_node (tleft);
4585 COND_RETURN_ERROR ();
4586 }
4587
4588 /* rhs */
0001803f
CR
4589 if (parser_state & PST_EXTPAT)
4590 extended_glob = 1;
cce855bc 4591 tok = read_token (READ);
0001803f
CR
4592 if (parser_state & PST_EXTPAT)
4593 extended_glob = global_extglob;
4594 parser_state &= ~(PST_REGEXP|PST_EXTPAT);
4595
cce855bc
JA
4596 if (tok == WORD)
4597 {
4598 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
4599 term = make_cond_node (COND_BINARY, op, tleft, tright);
4600 }
4601 else
4602 {
7117c2d2
JA
4603 if (etext = error_token_from_token (tok))
4604 {
b80f6443 4605 parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
7117c2d2
JA
4606 free (etext);
4607 }
4608 else
b80f6443 4609 parser_error (line_number, _("unexpected argument to conditional binary operator"));
cce855bc
JA
4610 dispose_cond_node (tleft);
4611 dispose_word (op);
4612 COND_RETURN_ERROR ();
4613 }
4614
4615 (void)cond_skip_newlines ();
4616 }
bb70624e
JA
4617 else
4618 {
4619 if (tok < 256)
b80f6443 4620 parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
7117c2d2
JA
4621 else if (etext = error_token_from_token (tok))
4622 {
b80f6443 4623 parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
7117c2d2
JA
4624 free (etext);
4625 }
bb70624e 4626 else
b80f6443 4627 parser_error (line_number, _("unexpected token %d in conditional command"), tok);
bb70624e
JA
4628 COND_RETURN_ERROR ();
4629 }
cce855bc
JA
4630 return (term);
4631}
4632
4633/* This is kind of bogus -- we slip a mini recursive-descent parser in
4634 here to handle the conditional statement syntax. */
4635static COMMAND *
4636parse_cond_command ()
4637{
4638 COND_COM *cexp;
4639
0001803f 4640 global_extglob = extended_glob;
cce855bc
JA
4641 cexp = cond_expr ();
4642 return (make_cond_command (cexp));
4643}
4644#endif
4645
7117c2d2
JA
4646#if defined (ARRAY_VARS)
4647/* When this is called, it's guaranteed that we don't care about anything
4648 in t beyond i. We do save and restore the chars, though. */
4649static int
4650token_is_assignment (t, i)
4651 char *t;
4652 int i;
4653{
4654 unsigned char c, c1;
4655 int r;
4656
4657 c = t[i]; c1 = t[i+1];
4658 t[i] = '='; t[i+1] = '\0';
b80f6443 4659 r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
7117c2d2
JA
4660 t[i] = c; t[i+1] = c1;
4661 return r;
4662}
4663
95732b49 4664/* XXX - possible changes here for `+=' */
7117c2d2
JA
4665static int
4666token_is_ident (t, i)
4667 char *t;
4668 int i;
4669{
4670 unsigned char c;
4671 int r;
4672
4673 c = t[i];
4674 t[i] = '\0';
4675 r = legal_identifier (t);
4676 t[i] = c;
4677 return r;
4678}
4679#endif
4680
ccc6cda3
JA
4681static int
4682read_token_word (character)
4683 int character;
4684{
4685 /* The value for YYLVAL when a WORD is read. */
4686 WORD_DESC *the_word;
726f6388 4687
ccc6cda3
JA
4688 /* Index into the token that we are building. */
4689 int token_index;
726f6388 4690
ccc6cda3 4691 /* ALL_DIGITS becomes zero when we see a non-digit. */
f73dda09 4692 int all_digit_token;
726f6388 4693
ccc6cda3
JA
4694 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
4695 int dollar_present;
726f6388 4696
95732b49
JA
4697 /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
4698 assignment. */
4699 int compound_assignment;
4700
ccc6cda3
JA
4701 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
4702 int quoted;
726f6388 4703
ccc6cda3
JA
4704 /* Non-zero means to ignore the value of the next character, and just
4705 to add it no matter what. */
a0c0a00f 4706 int pass_next_character;
726f6388 4707
ccc6cda3
JA
4708 /* The current delimiting character. */
4709 int cd;
4710 int result, peek_char;
4711 char *ttok, *ttrans;
4712 int ttoklen, ttranslen;
7117c2d2 4713 intmax_t lvalue;
726f6388 4714
d166f048 4715 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
f73dda09 4716 token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
726f6388 4717
ccc6cda3 4718 token_index = 0;
f73dda09 4719 all_digit_token = DIGIT (character);
95732b49 4720 dollar_present = quoted = pass_next_character = compound_assignment = 0;
726f6388 4721
ccc6cda3
JA
4722 for (;;)
4723 {
4724 if (character == EOF)
4725 goto got_token;
726f6388 4726
ccc6cda3
JA
4727 if (pass_next_character)
4728 {
4729 pass_next_character = 0;
f1be666c 4730 goto got_escaped_character;
ccc6cda3 4731 }
726f6388 4732
ccc6cda3 4733 cd = current_delimiter (dstack);
726f6388 4734
ccc6cda3
JA
4735 /* Handle backslashes. Quote lots of things when not inside of
4736 double-quotes, quote some things inside of double-quotes. */
7117c2d2 4737 if MBTEST(character == '\\')
ccc6cda3
JA
4738 {
4739 peek_char = shell_getc (0);
726f6388 4740
ccc6cda3
JA
4741 /* Backslash-newline is ignored in all cases except
4742 when quoted with single quotes. */
4743 if (peek_char == '\n')
4744 {
4745 character = '\n';
4746 goto next_character;
4747 }
4748 else
4749 {
4750 shell_ungetc (peek_char);
726f6388 4751
ccc6cda3
JA
4752 /* If the next character is to be quoted, note it now. */
4753 if (cd == 0 || cd == '`' ||
f73dda09 4754 (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
ccc6cda3 4755 pass_next_character++;
726f6388 4756
ccc6cda3
JA
4757 quoted = 1;
4758 goto got_character;
4759 }
4760 }
726f6388 4761
ccc6cda3 4762 /* Parse a matched pair of quote characters. */
7117c2d2 4763 if MBTEST(shellquote (character))
ccc6cda3
JA
4764 {
4765 push_delimiter (dstack, character);
95732b49 4766 ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
ccc6cda3
JA
4767 pop_delimiter (dstack);
4768 if (ttok == &matched_pair_error)
4769 return -1; /* Bail immediately. */
4770 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4771 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4772 token[token_index++] = character;
4773 strcpy (token + token_index, ttok);
4774 token_index += ttoklen;
f73dda09 4775 all_digit_token = 0;
ccc6cda3
JA
4776 quoted = 1;
4777 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
4778 FREE (ttok);
4779 goto next_character;
4780 }
726f6388 4781
f1be666c
JA
4782#ifdef COND_REGEXP
4783 /* When parsing a regexp as a single word inside a conditional command,
4784 we need to special-case characters special to both the shell and
4785 regular expressions. Right now, that is only '(' and '|'. */ /*)*/
4786 if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/
3185942a
JA
4787 {
4788 if (character == '|')
4789 goto got_character;
f1be666c
JA
4790
4791 push_delimiter (dstack, character);
4792 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4793 pop_delimiter (dstack);
4794 if (ttok == &matched_pair_error)
4795 return -1; /* Bail immediately. */
4796 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4797 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
4798 token[token_index++] = character;
4799 strcpy (token + token_index, ttok);
4800 token_index += ttoklen;
4801 FREE (ttok);
4802 dollar_present = all_digit_token = 0;
4803 goto next_character;
3185942a 4804 }
f1be666c
JA
4805#endif /* COND_REGEXP */
4806
cce855bc
JA
4807#ifdef EXTENDED_GLOB
4808 /* Parse a ksh-style extended pattern matching specification. */
f1be666c 4809 if MBTEST(extended_glob && PATTERN_CHAR (character))
cce855bc
JA
4810 {
4811 peek_char = shell_getc (1);
7117c2d2 4812 if MBTEST(peek_char == '(') /* ) */
cce855bc
JA
4813 {
4814 push_delimiter (dstack, peek_char);
4815 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
4816 pop_delimiter (dstack);
4817 if (ttok == &matched_pair_error)
4818 return -1; /* Bail immediately. */
ac50fbac 4819 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
cce855bc
JA
4820 token_buffer_size,
4821 TOKEN_DEFAULT_GROW_SIZE);
4822 token[token_index++] = character;
4823 token[token_index++] = peek_char;
4824 strcpy (token + token_index, ttok);
4825 token_index += ttoklen;
4826 FREE (ttok);
f73dda09 4827 dollar_present = all_digit_token = 0;
cce855bc
JA
4828 goto next_character;
4829 }
4830 else
4831 shell_ungetc (peek_char);
4832 }
4833#endif /* EXTENDED_GLOB */
4834
ccc6cda3
JA
4835 /* If the delimiter character is not single quote, parse some of
4836 the shell expansions that must be read as a single word. */
28ef6c31 4837 if (shellexp (character))
ccc6cda3
JA
4838 {
4839 peek_char = shell_getc (1);
4840 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
ac50fbac 4841 if MBTEST(peek_char == '(' ||
ccc6cda3
JA
4842 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
4843 {
4844 if (peek_char == '{') /* } */
495aee44 4845 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE);
ccc6cda3 4846 else if (peek_char == '(') /* ) */
d166f048
JA
4847 {
4848 /* XXX - push and pop the `(' as a delimiter for use by
4849 the command-oriented-history code. This way newlines
4850 appearing in the $(...) string get added to the
4851 history literally rather than causing a possibly-
bb70624e 4852 incorrect `;' to be added. ) */
d166f048 4853 push_delimiter (dstack, peek_char);
3185942a 4854 ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND);
d166f048
JA
4855 pop_delimiter (dstack);
4856 }
ccc6cda3
JA
4857 else
4858 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
4859 if (ttok == &matched_pair_error)
4860 return -1; /* Bail immediately. */
ac50fbac 4861 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3,
ccc6cda3
JA
4862 token_buffer_size,
4863 TOKEN_DEFAULT_GROW_SIZE);
4864 token[token_index++] = character;
4865 token[token_index++] = peek_char;
4866 strcpy (token + token_index, ttok);
4867 token_index += ttoklen;
4868 FREE (ttok);
4869 dollar_present = 1;
f73dda09 4870 all_digit_token = 0;
ccc6cda3
JA
4871 goto next_character;
4872 }
4873 /* This handles $'...' and $"..." new-style quoted strings. */
7117c2d2 4874 else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
ccc6cda3 4875 {
cce855bc
JA
4876 int first_line;
4877
4878 first_line = line_number;
bb70624e
JA
4879 push_delimiter (dstack, peek_char);
4880 ttok = parse_matched_pair (peek_char, peek_char, peek_char,
4881 &ttoklen,
4882 (peek_char == '\'') ? P_ALLOWESC : 0);
4883 pop_delimiter (dstack);
ccc6cda3
JA
4884 if (ttok == &matched_pair_error)
4885 return -1;
4886 if (peek_char == '\'')
bb70624e
JA
4887 {
4888 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
4889 free (ttok);
95732b49 4890
bb70624e
JA
4891 /* Insert the single quotes and correctly quote any
4892 embedded single quotes (allowed because P_ALLOWESC was
4893 passed to parse_matched_pair). */
28ef6c31 4894 ttok = sh_single_quote (ttrans);
bb70624e 4895 free (ttrans);
95732b49 4896 ttranslen = strlen (ttok);
bb70624e 4897 ttrans = ttok;
bb70624e 4898 }
ccc6cda3 4899 else
bb70624e 4900 {
0628567a 4901 /* Try to locale-expand the converted string. */
bb70624e
JA
4902 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
4903 free (ttok);
4904
4905 /* Add the double quotes back */
95732b49 4906 ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
bb70624e 4907 free (ttrans);
95732b49 4908 ttranslen += 2;
bb70624e
JA
4909 ttrans = ttok;
4910 }
4911
ac50fbac 4912 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 1,
ccc6cda3
JA
4913 token_buffer_size,
4914 TOKEN_DEFAULT_GROW_SIZE);
ccc6cda3
JA
4915 strcpy (token + token_index, ttrans);
4916 token_index += ttranslen;
ccc6cda3
JA
4917 FREE (ttrans);
4918 quoted = 1;
f73dda09 4919 all_digit_token = 0;
ccc6cda3
JA
4920 goto next_character;
4921 }
b72432fd
JA
4922 /* This could eventually be extended to recognize all of the
4923 shell's single-character parameter expansions, and set flags.*/
7117c2d2 4924 else if MBTEST(character == '$' && peek_char == '$')
b72432fd 4925 {
b72432fd
JA
4926 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
4927 token_buffer_size,
4928 TOKEN_DEFAULT_GROW_SIZE);
ac50fbac
CR
4929 token[token_index++] = '$';
4930 token[token_index++] = peek_char;
b72432fd 4931 dollar_present = 1;
f73dda09 4932 all_digit_token = 0;
b72432fd
JA
4933 goto next_character;
4934 }
ccc6cda3
JA
4935 else
4936 shell_ungetc (peek_char);
4937 }
726f6388 4938
ccc6cda3 4939#if defined (ARRAY_VARS)
3185942a
JA
4940 /* Identify possible array subscript assignment; match [...]. If
4941 parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating
4942 `sub' as if it were enclosed in double quotes. */
4943 else if MBTEST(character == '[' && /* ] */
4944 ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
4945 (token_index == 0 && (parser_state&PST_COMPASSIGN))))
7117c2d2 4946 {
89a92869 4947 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
7117c2d2
JA
4948 if (ttok == &matched_pair_error)
4949 return -1; /* Bail immediately. */
4950 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
4951 token_buffer_size,
4952 TOKEN_DEFAULT_GROW_SIZE);
4953 token[token_index++] = character;
4954 strcpy (token + token_index, ttok);
4955 token_index += ttoklen;
4956 FREE (ttok);
4957 all_digit_token = 0;
4958 goto next_character;
4959 }
ccc6cda3 4960 /* Identify possible compound array variable assignment. */
95732b49 4961 else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
ccc6cda3
JA
4962 {
4963 peek_char = shell_getc (1);
7117c2d2 4964 if MBTEST(peek_char == '(') /* ) */
ccc6cda3 4965 {
7117c2d2
JA
4966 ttok = parse_compound_assignment (&ttoklen);
4967
4968 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
ccc6cda3
JA
4969 token_buffer_size,
4970 TOKEN_DEFAULT_GROW_SIZE);
7117c2d2
JA
4971
4972 token[token_index++] = '=';
4973 token[token_index++] = '(';
4974 if (ttok)
4975 {
4976 strcpy (token + token_index, ttok);
4977 token_index += ttoklen;
4978 }
4979 token[token_index++] = ')';
ccc6cda3 4980 FREE (ttok);
f73dda09 4981 all_digit_token = 0;
95732b49 4982 compound_assignment = 1;
0628567a 4983#if 1
ccc6cda3 4984 goto next_character;
95732b49
JA
4985#else
4986 goto got_token; /* ksh93 seems to do this */
4987#endif
ccc6cda3
JA
4988 }
4989 else
4990 shell_ungetc (peek_char);
4991 }
4992#endif
726f6388 4993
ccc6cda3
JA
4994 /* When not parsing a multi-character word construct, shell meta-
4995 characters break words. */
7117c2d2 4996 if MBTEST(shellbreak (character))
ccc6cda3
JA
4997 {
4998 shell_ungetc (character);
4999 goto got_token;
5000 }
726f6388 5001
ac50fbac 5002got_character:
ccc6cda3 5003 if (character == CTLESC || character == CTLNUL)
ac50fbac
CR
5004 {
5005 RESIZE_MALLOCED_BUFFER (token, token_index, 2, token_buffer_size,
5006 TOKEN_DEFAULT_GROW_SIZE);
5007 token[token_index++] = CTLESC;
5008 }
5009 else
5010got_escaped_character:
5011 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
5012 TOKEN_DEFAULT_GROW_SIZE);
726f6388 5013
ac50fbac 5014 token[token_index++] = character;
f1be666c
JA
5015
5016 all_digit_token &= DIGIT (character);
5017 dollar_present |= character == '$';
5018
ccc6cda3 5019 next_character:
b80f6443 5020 if (character == '\n' && SHOULD_PROMPT ())
ccc6cda3 5021 prompt_again ();
726f6388 5022
ccc6cda3
JA
5023 /* We want to remove quoted newlines (that is, a \<newline> pair)
5024 unless we are within single quotes or pass_next_character is
5025 set (the shell equivalent of literal-next). */
5026 cd = current_delimiter (dstack);
5027 character = shell_getc (cd != '\'' && pass_next_character == 0);
5028 } /* end for (;;) */
726f6388 5029
ccc6cda3 5030got_token:
726f6388 5031
ac50fbac 5032 /* Calls to RESIZE_MALLOCED_BUFFER ensure there is sufficient room. */
ccc6cda3 5033 token[token_index] = '\0';
726f6388 5034
ccc6cda3
JA
5035 /* Check to see what thing we should return. If the last_read_token
5036 is a `<', or a `&', or the character which ended this token is
5037 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
5038 Otherwise, it is just a word, and should be returned as such. */
ac50fbac
CR
5039 if MBTEST(all_digit_token && (character == '<' || character == '>' ||
5040 last_read_token == LESS_AND ||
ccc6cda3 5041 last_read_token == GREATER_AND))
726f6388 5042 {
f73dda09 5043 if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
ac50fbac
CR
5044 {
5045 yylval.number = lvalue;
5046 return (NUMBER);
5047 }
726f6388
JA
5048 }
5049
ccc6cda3 5050 /* Check for special case tokens. */
7117c2d2 5051 result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
ccc6cda3
JA
5052 if (result >= 0)
5053 return result;
726f6388
JA
5054
5055#if defined (ALIAS)
ccc6cda3
JA
5056 /* Posix.2 does not allow reserved words to be aliased, so check for all
5057 of them, including special cases, before expanding the current token
5058 as an alias. */
7117c2d2 5059 if MBTEST(posixly_correct)
ccc6cda3
JA
5060 CHECK_FOR_RESERVED_WORD (token);
5061
5062 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
5063 inhibits alias expansion. */
5064 if (expand_aliases && quoted == 0)
5065 {
5066 result = alias_expand_token (token);
5067 if (result == RE_READ_TOKEN)
5068 return (RE_READ_TOKEN);
5069 else if (result == NO_EXPANSION)
5070 parser_state &= ~PST_ALEXPNEXT;
5071 }
726f6388 5072
ccc6cda3
JA
5073 /* If not in Posix.2 mode, check for reserved words after alias
5074 expansion. */
7117c2d2 5075 if MBTEST(posixly_correct == 0)
ccc6cda3
JA
5076#endif
5077 CHECK_FOR_RESERVED_WORD (token);
5078
a0c0a00f 5079 the_word = alloc_word_desc ();
f73dda09 5080 the_word->word = (char *)xmalloc (1 + token_index);
ccc6cda3
JA
5081 the_word->flags = 0;
5082 strcpy (the_word->word, token);
5083 if (dollar_present)
5084 the_word->flags |= W_HASDOLLAR;
5085 if (quoted)
0628567a
JA
5086 the_word->flags |= W_QUOTED; /*(*/
5087 if (compound_assignment && token[token_index-1] == ')')
95732b49 5088 the_word->flags |= W_COMPASSIGN;
ccc6cda3
JA
5089 /* A word is an assignment if it appears at the beginning of a
5090 simple command, or after another assignment word. This is
5091 context-dependent, so it cannot be handled in the grammar. */
b80f6443 5092 if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
ccc6cda3
JA
5093 {
5094 the_word->flags |= W_ASSIGNMENT;
5095 /* Don't perform word splitting on assignment statements. */
b80f6443 5096 if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
ac50fbac
CR
5097 {
5098 the_word->flags |= W_NOSPLIT;
5099 if (parser_state & PST_COMPASSIGN)
5100 the_word->flags |= W_NOGLOB; /* XXX - W_NOBRACE? */
5101 }
ccc6cda3 5102 }
726f6388 5103
95732b49
JA
5104 if (command_token_position (last_read_token))
5105 {
5106 struct builtin *b;
5107 b = builtin_address_internal (token, 0);
5108 if (b && (b->flags & ASSIGNMENT_BUILTIN))
0628567a
JA
5109 parser_state |= PST_ASSIGNOK;
5110 else if (STREQ (token, "eval") || STREQ (token, "let"))
5111 parser_state |= PST_ASSIGNOK;
95732b49
JA
5112 }
5113
ccc6cda3 5114 yylval.word = the_word;
726f6388 5115
0001803f
CR
5116 if (token[0] == '{' && token[token_index-1] == '}' &&
5117 (character == '<' || character == '>'))
5118 {
5119 /* can use token; already copied to the_word */
5120 token[token_index-1] = '\0';
ac50fbac 5121#if defined (ARRAY_VARS)
a0c0a00f 5122 if (legal_identifier (token+1) || valid_array_reference (token+1, 0))
ac50fbac 5123#else
0001803f 5124 if (legal_identifier (token+1))
ac50fbac 5125#endif
0001803f
CR
5126 {
5127 strcpy (the_word->word, token+1);
5128/*itrace("read_token_word: returning REDIR_WORD for %s", the_word->word);*/
5129 return (REDIR_WORD);
5130 }
5131 }
5132
ccc6cda3
JA
5133 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
5134 ? ASSIGNMENT_WORD : WORD;
726f6388 5135
b80f6443 5136 switch (last_read_token)
ccc6cda3 5137 {
b80f6443 5138 case FUNCTION:
ccc6cda3
JA
5139 parser_state |= PST_ALLOWOPNBRC;
5140 function_dstart = line_number;
b80f6443
JA
5141 break;
5142 case CASE:
5143 case SELECT:
5144 case FOR:
5145 if (word_top < MAX_CASE_NEST)
5146 word_top++;
5147 word_lineno[word_top] = line_number;
5148 break;
ccc6cda3 5149 }
726f6388 5150
ccc6cda3
JA
5151 return (result);
5152}
726f6388 5153
f73dda09 5154/* Return 1 if TOKSYM is a token that after being read would allow
726f6388
JA
5155 a reserved word to be seen, else 0. */
5156static int
f73dda09
JA
5157reserved_word_acceptable (toksym)
5158 int toksym;
726f6388 5159{
7117c2d2
JA
5160 switch (toksym)
5161 {
5162 case '\n':
5163 case ';':
5164 case '(':
5165 case ')':
5166 case '|':
5167 case '&':
5168 case '{':
5169 case '}': /* XXX */
5170 case AND_AND:
5171 case BANG:
89a92869 5172 case BAR_AND:
7117c2d2
JA
5173 case DO:
5174 case DONE:
5175 case ELIF:
5176 case ELSE:
5177 case ESAC:
5178 case FI:
5179 case IF:
5180 case OR_OR:
5181 case SEMI_SEMI:
3185942a
JA
5182 case SEMI_AND:
5183 case SEMI_SEMI_AND:
7117c2d2
JA
5184 case THEN:
5185 case TIME:
5186 case TIMEOPT:
495aee44 5187 case TIMEIGN:
3185942a 5188 case COPROC:
7117c2d2
JA
5189 case UNTIL:
5190 case WHILE:
5191 case 0:
5192 return 1;
5193 default:
3185942a
JA
5194#if defined (COPROCESS_SUPPORT)
5195 if (last_read_token == WORD && token_before_that == COPROC)
5196 return 1;
5197#endif
495aee44
CR
5198 if (last_read_token == WORD && token_before_that == FUNCTION)
5199 return 1;
7117c2d2
JA
5200 return 0;
5201 }
726f6388 5202}
7117c2d2 5203
726f6388
JA
5204/* Return the index of TOKEN in the alist of reserved words, or -1 if
5205 TOKEN is not a shell reserved word. */
5206int
f73dda09
JA
5207find_reserved_word (tokstr)
5208 char *tokstr;
726f6388
JA
5209{
5210 int i;
ccc6cda3 5211 for (i = 0; word_token_alist[i].word; i++)
f73dda09 5212 if (STREQ (tokstr, word_token_alist[i].word))
726f6388
JA
5213 return i;
5214 return -1;
5215}
5216
ac50fbac
CR
5217/* An interface to let the rest of the shell (primarily the completion
5218 system) know what the parser is expecting. */
5219int
5220parser_in_command_position ()
5221{
5222 return (command_token_position (last_read_token));
5223}
5224
ccc6cda3 5225#if 0
726f6388
JA
5226#if defined (READLINE)
5227/* Called after each time readline is called. This insures that whatever
5228 the new prompt string is gets propagated to readline's local prompt
5229 variable. */
5230static void
5231reset_readline_prompt ()
5232{
ccc6cda3
JA
5233 char *temp_prompt;
5234
726f6388
JA
5235 if (prompt_string_pointer)
5236 {
ccc6cda3 5237 temp_prompt = (*prompt_string_pointer)
726f6388
JA
5238 ? decode_prompt_string (*prompt_string_pointer)
5239 : (char *)NULL;
5240
5241 if (temp_prompt == 0)
5242 {
f73dda09 5243 temp_prompt = (char *)xmalloc (1);
726f6388
JA
5244 temp_prompt[0] = '\0';
5245 }
5246
5247 FREE (current_readline_prompt);
726f6388
JA
5248 current_readline_prompt = temp_prompt;
5249 }
5250}
5251#endif /* READLINE */
ccc6cda3 5252#endif /* 0 */
726f6388
JA
5253
5254#if defined (HISTORY)
5255/* A list of tokens which can be followed by newlines, but not by
5256 semi-colons. When concatenating multiple lines of history, the
5257 newline separator for such tokens is replaced with a space. */
3185942a 5258static const int no_semi_successors[] = {
726f6388 5259 '\n', '{', '(', ')', ';', '&', '|',
3185942a
JA
5260 CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL,
5261 WHILE, AND_AND, OR_OR, IN,
726f6388
JA
5262 0
5263};
5264
5265/* If we are not within a delimited expression, try to be smart
5266 about which separators can be semi-colons and which must be
ccc6cda3 5267 newlines. Returns the string that should be added into the
495aee44
CR
5268 history entry. LINE is the line we're about to add; it helps
5269 make some more intelligent decisions in certain cases. */
726f6388 5270char *
495aee44
CR
5271history_delimiting_chars (line)
5272 const char *line;
726f6388 5273{
495aee44 5274 static int last_was_heredoc = 0; /* was the last entry the start of a here document? */
ccc6cda3
JA
5275 register int i;
5276
495aee44
CR
5277 if ((parser_state & PST_HEREDOC) == 0)
5278 last_was_heredoc = 0;
5279
ccc6cda3
JA
5280 if (dstack.delimiter_depth != 0)
5281 return ("\n");
3185942a
JA
5282
5283 /* We look for current_command_line_count == 2 because we are looking to
5284 add the first line of the body of the here document (the second line
495aee44
CR
5285 of the command). We also keep LAST_WAS_HEREDOC as a private sentinel
5286 variable to note when we think we added the first line of a here doc
5287 (the one with a "<<" somewhere in it) */
3185942a 5288 if (parser_state & PST_HEREDOC)
495aee44
CR
5289 {
5290 if (last_was_heredoc)
5291 {
5292 last_was_heredoc = 0;
5293 return "\n";
5294 }
a0c0a00f 5295 return (here_doc_first_line ? "\n" : "");
495aee44 5296 }
3185942a 5297
801b47cb
CR
5298 if (parser_state & PST_COMPASSIGN)
5299 return (" ");
5300
ccc6cda3
JA
5301 /* First, handle some special cases. */
5302 /*(*/
5303 /* If we just read `()', assume it's a function definition, and don't
5304 add a semicolon. If the token before the `)' was not `(', and we're
5305 not in the midst of parsing a case statement, assume it's a
5306 parenthesized command and add the semicolon. */
5307 /*)(*/
5308 if (token_before_that == ')')
726f6388 5309 {
ccc6cda3
JA
5310 if (two_tokens_ago == '(') /*)*/ /* function def */
5311 return " ";
5312 /* This does not work for subshells inside case statement
5313 command lists. It's a suboptimal solution. */
5314 else if (parser_state & PST_CASESTMT) /* case statement pattern */
28ef6c31 5315 return " ";
a0c0a00f 5316 else
28ef6c31 5317 return "; "; /* (...) subshell */
ccc6cda3 5318 }
cce855bc
JA
5319 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
5320 return " "; /* function def using `function name' without `()' */
726f6388 5321
495aee44
CR
5322 /* If we're not in a here document, but we think we're about to parse one,
5323 and we would otherwise return a `;', return a newline to delimit the
5324 line with the here-doc delimiter */
5325 else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<"))
5326 {
5327 last_was_heredoc = 1;
5328 return "\n";
5329 }
a0c0a00f
CR
5330 else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && need_here_doc > 0)
5331 return "\n";
bb70624e
JA
5332 else if (token_before_that == WORD && two_tokens_ago == FOR)
5333 {
5334 /* Tricky. `for i\nin ...' should not have a semicolon, but
5335 `for i\ndo ...' should. We do what we can. */
3185942a 5336 for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++)
28ef6c31 5337 ;
bb70624e
JA
5338 if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
5339 return " ";
5340 return ";";
5341 }
95732b49
JA
5342 else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
5343 return " ";
bb70624e 5344
ccc6cda3
JA
5345 for (i = 0; no_semi_successors[i]; i++)
5346 {
5347 if (token_before_that == no_semi_successors[i])
5348 return (" ");
726f6388 5349 }
ccc6cda3
JA
5350
5351 return ("; ");
726f6388
JA
5352}
5353#endif /* HISTORY */
5354
5355/* Issue a prompt, or prepare to issue a prompt when the next character
5356 is read. */
5357static void
5358prompt_again ()
5359{
5360 char *temp_prompt;
5361
0001803f 5362 if (interactive == 0 || expanding_alias ()) /* XXX */
726f6388
JA
5363 return;
5364
5365 ps1_prompt = get_string_value ("PS1");
5366 ps2_prompt = get_string_value ("PS2");
5367
a0c0a00f
CR
5368 ps0_prompt = get_string_value ("PS0");
5369
726f6388
JA
5370 if (!prompt_string_pointer)
5371 prompt_string_pointer = &ps1_prompt;
5372
ccc6cda3 5373 temp_prompt = *prompt_string_pointer
726f6388
JA
5374 ? decode_prompt_string (*prompt_string_pointer)
5375 : (char *)NULL;
5376
5377 if (temp_prompt == 0)
5378 {
f73dda09 5379 temp_prompt = (char *)xmalloc (1);
726f6388
JA
5380 temp_prompt[0] = '\0';
5381 }
5382
5383 current_prompt_string = *prompt_string_pointer;
5384 prompt_string_pointer = &ps2_prompt;
5385
5386#if defined (READLINE)
5387 if (!no_line_editing)
5388 {
5389 FREE (current_readline_prompt);
5390 current_readline_prompt = temp_prompt;
5391 }
5392 else
5393#endif /* READLINE */
5394 {
5395 FREE (current_decoded_prompt);
5396 current_decoded_prompt = temp_prompt;
5397 }
5398}
5399
bb70624e
JA
5400int
5401get_current_prompt_level ()
5402{
5403 return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
5404}
5405
5406void
5407set_current_prompt_level (x)
5408 int x;
5409{
5410 prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
5411 current_prompt_string = *prompt_string_pointer;
5412}
5413
726f6388
JA
5414static void
5415print_prompt ()
5416{
5417 fprintf (stderr, "%s", current_decoded_prompt);
5418 fflush (stderr);
5419}
5420
5421/* Return a string which will be printed as a prompt. The string
5422 may contain special characters which are decoded as follows:
ccc6cda3
JA
5423
5424 \a bell (ascii 07)
ccc6cda3 5425 \d the date in Day Mon Date format
7117c2d2 5426 \e escape (ascii 033)
ccc6cda3
JA
5427 \h the hostname up to the first `.'
5428 \H the hostname
bb70624e
JA
5429 \j the number of active jobs
5430 \l the basename of the shell's tty device name
726f6388 5431 \n CRLF
7117c2d2 5432 \r CR
726f6388 5433 \s the name of the shell
ccc6cda3
JA
5434 \t the time in 24-hour hh:mm:ss format
5435 \T the time in 12-hour hh:mm:ss format
7117c2d2
JA
5436 \@ the time in 12-hour hh:mm am/pm format
5437 \A the time in 24-hour hh:mm format
5438 \D{fmt} the result of passing FMT to strftime(3)
5439 \u your username
ccc6cda3
JA
5440 \v the version of bash (e.g., 2.00)
5441 \V the release of bash, version + patchlevel (e.g., 2.00.0)
726f6388 5442 \w the current working directory
ccc6cda3 5443 \W the last element of $PWD
726f6388 5444 \! the history number of this command
7117c2d2 5445 \# the command number of this command
726f6388 5446 \$ a $ or a # if you are root
ccc6cda3 5447 \nnn character code nnn in octal
726f6388 5448 \\ a backslash
ccc6cda3
JA
5449 \[ begin a sequence of non-printing chars
5450 \] end a sequence of non-printing chars
726f6388 5451*/
d166f048 5452#define PROMPT_GROWTH 48
726f6388
JA
5453char *
5454decode_prompt_string (string)
5455 char *string;
5456{
726f6388 5457 WORD_LIST *list;
ccc6cda3
JA
5458 char *result, *t;
5459 struct dstack save_dstack;
0001803f 5460 int last_exit_value, last_comsub_pid;
726f6388 5461#if defined (PROMPT_STRING_DECODE)
a0c0a00f
CR
5462 size_t result_size;
5463 int result_index;
0628567a 5464 int c, n, i;
a0c0a00f 5465 char *temp, *t_host, octal_string[4];
7117c2d2 5466 struct tm *tm;
ccc6cda3 5467 time_t the_time;
7117c2d2
JA
5468 char timebuf[128];
5469 char *timefmt;
726f6388 5470
f73dda09 5471 result = (char *)xmalloc (result_size = PROMPT_GROWTH);
ccc6cda3
JA
5472 result[result_index = 0] = 0;
5473 temp = (char *)NULL;
726f6388
JA
5474
5475 while (c = *string++)
5476 {
5477 if (posixly_correct && c == '!')
5478 {
5479 if (*string == '!')
5480 {
5481 temp = savestring ("!");
5482 goto add_string;
5483 }
5484 else
5485 {
5486#if !defined (HISTORY)
5487 temp = savestring ("1");
5488#else /* HISTORY */
5489 temp = itos (history_number ());
5490#endif /* HISTORY */
5491 string--; /* add_string increments string again. */
5492 goto add_string;
5493 }
ccc6cda3 5494 }
726f6388
JA
5495 if (c == '\\')
5496 {
5497 c = *string;
5498
5499 switch (c)
5500 {
5501 case '0':
5502 case '1':
5503 case '2':
5504 case '3':
5505 case '4':
5506 case '5':
5507 case '6':
5508 case '7':
ccc6cda3
JA
5509 strncpy (octal_string, string, 3);
5510 octal_string[3] = '\0';
726f6388 5511
ccc6cda3 5512 n = read_octal (octal_string);
f73dda09 5513 temp = (char *)xmalloc (3);
726f6388 5514
ccc6cda3
JA
5515 if (n == CTLESC || n == CTLNUL)
5516 {
ccc6cda3
JA
5517 temp[0] = CTLESC;
5518 temp[1] = n;
5519 temp[2] = '\0';
5520 }
5521 else if (n == -1)
5522 {
5523 temp[0] = '\\';
5524 temp[1] = '\0';
5525 }
5526 else
5527 {
ccc6cda3
JA
5528 temp[0] = n;
5529 temp[1] = '\0';
5530 }
726f6388 5531
28ef6c31
JA
5532 for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
5533 string++;
5534
7117c2d2 5535 c = 0; /* tested at add_string: */
ccc6cda3 5536 goto add_string;
726f6388 5537
726f6388 5538 case 'd':
7117c2d2 5539 case 't':
ccc6cda3
JA
5540 case 'T':
5541 case '@':
f73dda09 5542 case 'A':
726f6388 5543 /* Make the current time/date into a string. */
7117c2d2 5544 (void) time (&the_time);
2bbe8058
CR
5545#if defined (HAVE_TZSET)
5546 sv_tz ("TZ"); /* XXX -- just make sure */
5547#endif
7117c2d2
JA
5548 tm = localtime (&the_time);
5549
5550 if (c == 'd')
5551 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
5552 else if (c == 't')
5553 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
5554 else if (c == 'T')
5555 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
5556 else if (c == '@')
5557 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
5558 else if (c == 'A')
5559 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
5560
b80f6443
JA
5561 if (n == 0)
5562 timebuf[0] = '\0';
5563 else
5564 timebuf[sizeof(timebuf) - 1] = '\0';
5565
7117c2d2
JA
5566 temp = savestring (timebuf);
5567 goto add_string;
726f6388 5568
7117c2d2
JA
5569 case 'D': /* strftime format */
5570 if (string[1] != '{') /* } */
5571 goto not_escape;
726f6388 5572
7117c2d2
JA
5573 (void) time (&the_time);
5574 tm = localtime (&the_time);
5575 string += 2; /* skip { */
5576 timefmt = xmalloc (strlen (string) + 3);
5577 for (t = timefmt; *string && *string != '}'; )
5578 *t++ = *string++;
5579 *t = '\0';
5580 c = *string; /* tested at add_string */
5581 if (timefmt[0] == '\0')
ccc6cda3 5582 {
7117c2d2
JA
5583 timefmt[0] = '%';
5584 timefmt[1] = 'X'; /* locale-specific current time */
5585 timefmt[2] = '\0';
ccc6cda3 5586 }
7117c2d2
JA
5587 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
5588 free (timefmt);
5589
b80f6443
JA
5590 if (n == 0)
5591 timebuf[0] = '\0';
5592 else
5593 timebuf[sizeof(timebuf) - 1] = '\0';
5594
7117c2d2
JA
5595 if (promptvars || posixly_correct)
5596 /* Make sure that expand_prompt_string is called with a
5597 second argument of Q_DOUBLE_QUOTES if we use this
5598 function here. */
5599 temp = sh_backslash_quote_for_double_quotes (timebuf);
5600 else
5601 temp = savestring (timebuf);
ccc6cda3 5602 goto add_string;
7117c2d2 5603
726f6388 5604 case 'n':
f73dda09 5605 temp = (char *)xmalloc (3);
ccc6cda3
JA
5606 temp[0] = no_line_editing ? '\n' : '\r';
5607 temp[1] = no_line_editing ? '\0' : '\n';
5608 temp[2] = '\0';
726f6388
JA
5609 goto add_string;
5610
5611 case 's':
ccc6cda3 5612 temp = base_pathname (shell_name);
a0c0a00f
CR
5613 /* Try to quote anything the user can set in the file system */
5614 if (promptvars || posixly_correct)
5615 temp = sh_backslash_quote_for_double_quotes (temp);
5616 else
5617 temp = savestring (temp);
ccc6cda3
JA
5618 goto add_string;
5619
5620 case 'v':
5621 case 'V':
7117c2d2 5622 temp = (char *)xmalloc (16);
ccc6cda3
JA
5623 if (c == 'v')
5624 strcpy (temp, dist_version);
5625 else
5626 sprintf (temp, "%s.%d", dist_version, patch_level);
5627 goto add_string;
5628
726f6388
JA
5629 case 'w':
5630 case 'W':
5631 {
ccc6cda3 5632 /* Use the value of PWD because it is much more efficient. */
0628567a 5633 char t_string[PATH_MAX];
e8ce775d 5634 int tlen;
726f6388
JA
5635
5636 temp = get_string_value ("PWD");
5637
ccc6cda3
JA
5638 if (temp == 0)
5639 {
5640 if (getcwd (t_string, sizeof(t_string)) == 0)
5641 {
28ef6c31 5642 t_string[0] = '.';
e8ce775d 5643 tlen = 1;
ccc6cda3 5644 }
e8ce775d
JA
5645 else
5646 tlen = strlen (t_string);
ccc6cda3 5647 }
726f6388 5648 else
e8ce775d
JA
5649 {
5650 tlen = sizeof (t_string) - 1;
5651 strncpy (t_string, temp, tlen);
5652 }
5653 t_string[tlen] = '\0';
726f6388 5654
0001803f
CR
5655#if defined (MACOSX)
5656 /* Convert from "fs" format to "input" format */
5657 temp = fnx_fromfs (t_string, strlen (t_string));
5658 if (temp != t_string)
5659 strcpy (t_string, temp);
5660#endif
5661
28ef6c31
JA
5662#define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
5663#define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
b80f6443 5664 /* Abbreviate \W as ~ if $PWD == $HOME */
95732b49 5665 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
726f6388 5666 {
28ef6c31
JA
5667 if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
5668 {
5669 t = strrchr (t_string, '/');
5670 if (t)
495aee44 5671 memmove (t_string, t + 1, strlen (t)); /* strlen(t) to copy NULL */
28ef6c31 5672 }
726f6388 5673 }
28ef6c31
JA
5674#undef ROOT_PATH
5675#undef DOUBLE_SLASH_ROOT
726f6388 5676 else
ac50fbac
CR
5677 {
5678 /* polite_directory_format is guaranteed to return a string
5679 no longer than PATH_MAX - 1 characters. */
5680 temp = polite_directory_format (t_string);
5681 if (temp != t_string)
5682 strcpy (t_string, temp);
5683 }
ccc6cda3 5684
3185942a 5685 temp = trim_pathname (t_string, PATH_MAX - 1);
ccc6cda3
JA
5686 /* If we're going to be expanding the prompt string later,
5687 quote the directory name. */
5688 if (promptvars || posixly_correct)
bb70624e 5689 /* Make sure that expand_prompt_string is called with a
7117c2d2 5690 second argument of Q_DOUBLE_QUOTES if we use this
bb70624e 5691 function here. */
28ef6c31 5692 temp = sh_backslash_quote_for_double_quotes (t_string);
ccc6cda3
JA
5693 else
5694 temp = savestring (t_string);
5695
726f6388
JA
5696 goto add_string;
5697 }
ccc6cda3 5698
726f6388 5699 case 'u':
bb70624e
JA
5700 if (current_user.user_name == 0)
5701 get_current_user_info ();
ccc6cda3
JA
5702 temp = savestring (current_user.user_name);
5703 goto add_string;
726f6388
JA
5704
5705 case 'h':
ccc6cda3 5706 case 'H':
a0c0a00f
CR
5707 t_host = savestring (current_host_name);
5708 if (c == 'h' && (t = (char *)strchr (t_host, '.')))
ccc6cda3 5709 *t = '\0';
a0c0a00f
CR
5710 if (promptvars || posixly_correct)
5711 /* Make sure that expand_prompt_string is called with a
5712 second argument of Q_DOUBLE_QUOTES if we use this
5713 function here. */
5714 temp = sh_backslash_quote_for_double_quotes (t_host);
5715 else
5716 temp = savestring (t_host);
5717 free (t_host);
ccc6cda3 5718 goto add_string;
726f6388
JA
5719
5720 case '#':
ccc6cda3
JA
5721 temp = itos (current_command_number);
5722 goto add_string;
726f6388
JA
5723
5724 case '!':
726f6388 5725#if !defined (HISTORY)
ccc6cda3 5726 temp = savestring ("1");
726f6388 5727#else /* HISTORY */
ccc6cda3 5728 temp = itos (history_number ());
726f6388 5729#endif /* HISTORY */
ccc6cda3 5730 goto add_string;
726f6388
JA
5731
5732 case '$':
f73dda09 5733 t = temp = (char *)xmalloc (3);
b72432fd
JA
5734 if ((promptvars || posixly_correct) && (current_user.euid != 0))
5735 *t++ = '\\';
5736 *t++ = current_user.euid == 0 ? '#' : '$';
5737 *t = '\0';
726f6388
JA
5738 goto add_string;
5739
bb70624e
JA
5740 case 'j':
5741 temp = itos (count_all_jobs ());
5742 goto add_string;
5743
5744 case 'l':
5745#if defined (HAVE_TTYNAME)
5746 temp = (char *)ttyname (fileno (stdin));
5747 t = temp ? base_pathname (temp) : "tty";
5748 temp = savestring (t);
5749#else
5750 temp = savestring ("tty");
5751#endif /* !HAVE_TTYNAME */
5752 goto add_string;
5753
726f6388
JA
5754#if defined (READLINE)
5755 case '[':
5756 case ']':
b80f6443
JA
5757 if (no_line_editing)
5758 {
5759 string++;
5760 break;
5761 }
f73dda09 5762 temp = (char *)xmalloc (3);
0628567a
JA
5763 n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
5764 i = 0;
5765 if (n == CTLESC || n == CTLNUL)
5766 temp[i++] = CTLESC;
5767 temp[i++] = n;
5768 temp[i] = '\0';
726f6388 5769 goto add_string;
ccc6cda3 5770#endif /* READLINE */
726f6388
JA
5771
5772 case '\\':
ccc6cda3
JA
5773 case 'a':
5774 case 'e':
7117c2d2 5775 case 'r':
f73dda09 5776 temp = (char *)xmalloc (2);
7117c2d2
JA
5777 if (c == 'a')
5778 temp[0] = '\07';
5779 else if (c == 'e')
5780 temp[0] = '\033';
5781 else if (c == 'r')
5782 temp[0] = '\r';
5783 else /* (c == '\\') */
5784 temp[0] = c;
ccc6cda3 5785 temp[1] = '\0';
726f6388
JA
5786 goto add_string;
5787
5788 default:
7117c2d2 5789not_escape:
f73dda09 5790 temp = (char *)xmalloc (3);
ccc6cda3 5791 temp[0] = '\\';
726f6388 5792 temp[1] = c;
ccc6cda3 5793 temp[2] = '\0';
726f6388
JA
5794
5795 add_string:
5796 if (c)
5797 string++;
5798 result =
5799 sub_append_string (temp, result, &result_index, &result_size);
ccc6cda3 5800 temp = (char *)NULL; /* Freed in sub_append_string (). */
726f6388
JA
5801 result[result_index] = '\0';
5802 break;
5803 }
5804 }
5805 else
5806 {
ccc6cda3 5807 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
a0c0a00f
CR
5808 /* dequote_string should take care of removing this if we are not
5809 performing the rest of the word expansions. */
5810 if (c == CTLESC || c == CTLNUL)
5811 result[result_index++] = CTLESC;
726f6388
JA
5812 result[result_index++] = c;
5813 result[result_index] = '\0';
5814 }
5815 }
5816#else /* !PROMPT_STRING_DECODE */
5817 result = savestring (string);
5818#endif /* !PROMPT_STRING_DECODE */
5819
ccc6cda3
JA
5820 /* Save the delimiter stack and point `dstack' to temp space so any
5821 command substitutions in the prompt string won't result in screwing
5822 up the parser's quoting state. */
5823 save_dstack = dstack;
5824 dstack = temp_dstack;
5825 dstack.delimiter_depth = 0;
5826
726f6388
JA
5827 /* Perform variable and parameter expansion and command substitution on
5828 the prompt string. */
ccc6cda3
JA
5829 if (promptvars || posixly_correct)
5830 {
f73dda09 5831 last_exit_value = last_command_exit_value;
0001803f 5832 last_comsub_pid = last_command_subst_pid;
f1be666c 5833 list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0);
ccc6cda3
JA
5834 free (result);
5835 result = string_list (list);
5836 dispose_words (list);
f73dda09 5837 last_command_exit_value = last_exit_value;
0001803f 5838 last_command_subst_pid = last_comsub_pid;
ccc6cda3
JA
5839 }
5840 else
5841 {
5842 t = dequote_string (result);
5843 free (result);
5844 result = t;
5845 }
5846
5847 dstack = save_dstack;
726f6388
JA
5848
5849 return (result);
5850}
5851
7117c2d2
JA
5852/************************************************
5853 * *
5854 * ERROR HANDLING *
5855 * *
5856 ************************************************/
5857
726f6388
JA
5858/* Report a syntax error, and restart the parser. Call here for fatal
5859 errors. */
ccc6cda3 5860int
f73dda09
JA
5861yyerror (msg)
5862 const char *msg;
726f6388
JA
5863{
5864 report_syntax_error ((char *)NULL);
5865 reset_parser ();
ccc6cda3 5866 return (0);
726f6388
JA
5867}
5868
7117c2d2 5869static char *
0628567a
JA
5870error_token_from_token (tok)
5871 int tok;
7117c2d2
JA
5872{
5873 char *t;
5874
0628567a 5875 if (t = find_token_in_alist (tok, word_token_alist, 0))
7117c2d2
JA
5876 return t;
5877
0628567a 5878 if (t = find_token_in_alist (tok, other_token_alist, 0))
7117c2d2
JA
5879 return t;
5880
5881 t = (char *)NULL;
5882 /* This stuff is dicy and needs closer inspection */
5883 switch (current_token)
5884 {
5885 case WORD:
5886 case ASSIGNMENT_WORD:
5887 if (yylval.word)
5888 t = savestring (yylval.word->word);
5889 break;
5890 case NUMBER:
5891 t = itos (yylval.number);
5892 break;
5893 case ARITH_CMD:
5894 if (yylval.word_list)
5895 t = string_list (yylval.word_list);
5896 break;
5897 case ARITH_FOR_EXPRS:
5898 if (yylval.word_list)
5899 t = string_list_internal (yylval.word_list, " ; ");
5900 break;
5901 case COND_CMD:
5902 t = (char *)NULL; /* punt */
5903 break;
5904 }
5905
5906 return t;
5907}
5908
5909static char *
5910error_token_from_text ()
5911{
5912 char *msg, *t;
5913 int token_end, i;
5914
5915 t = shell_input_line;
5916 i = shell_input_line_index;
5917 token_end = 0;
5918 msg = (char *)NULL;
5919
5920 if (i && t[i] == '\0')
5921 i--;
5922
5923 while (i && (whitespace (t[i]) || t[i] == '\n'))
5924 i--;
5925
5926 if (i)
5927 token_end = i + 1;
5928
5929 while (i && (member (t[i], " \n\t;|&") == 0))
5930 i--;
5931
5932 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
5933 i++;
5934
5935 /* Return our idea of the offending token. */
5936 if (token_end || (i == 0 && token_end == 0))
5937 {
5938 if (token_end)
5939 msg = substring (t, i, token_end);
5940 else /* one-character token */
5941 {
5942 msg = (char *)xmalloc (2);
5943 msg[0] = t[i];
5944 msg[1] = '\0';
5945 }
5946 }
5947
5948 return (msg);
5949}
5950
5951static void
5952print_offending_line ()
5953{
5954 char *msg;
5955 int token_end;
5956
5957 msg = savestring (shell_input_line);
5958 token_end = strlen (msg);
5959 while (token_end && msg[token_end - 1] == '\n')
5960 msg[--token_end] = '\0';
5961
5962 parser_error (line_number, "`%s'", msg);
5963 free (msg);
5964}
5965
726f6388
JA
5966/* Report a syntax error with line numbers, etc.
5967 Call here for recoverable errors. If you have a message to print,
5968 then place it in MESSAGE, otherwise pass NULL and this will figure
5969 out an appropriate message for you. */
5970static void
5971report_syntax_error (message)
5972 char *message;
5973{
495aee44 5974 char *msg, *p;
ccc6cda3 5975
726f6388
JA
5976 if (message)
5977 {
ccc6cda3
JA
5978 parser_error (line_number, "%s", message);
5979 if (interactive && EOF_Reached)
5980 EOF_Reached = 0;
0001803f 5981 last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
726f6388
JA
5982 return;
5983 }
5984
ccc6cda3 5985 /* If the line of input we're reading is not null, try to find the
7117c2d2
JA
5986 objectionable token. First, try to figure out what token the
5987 parser's complaining about by looking at current_token. */
5988 if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
726f6388 5989 {
495aee44
CR
5990 if (ansic_shouldquote (msg))
5991 {
5992 p = ansic_quote (msg, 0, NULL);
5993 free (msg);
5994 msg = p;
5995 }
b80f6443 5996 parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
7117c2d2 5997 free (msg);
726f6388 5998
7117c2d2
JA
5999 if (interactive == 0)
6000 print_offending_line ();
726f6388 6001
0001803f 6002 last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
7117c2d2
JA
6003 return;
6004 }
726f6388 6005
7117c2d2
JA
6006 /* If looking at the current token doesn't prove fruitful, try to find the
6007 offending token by analyzing the text of the input line near the current
6008 input line index and report what we find. */
6009 if (shell_input_line && *shell_input_line)
6010 {
6011 msg = error_token_from_text ();
6012 if (msg)
726f6388 6013 {
b80f6443 6014 parser_error (line_number, _("syntax error near `%s'"), msg);
7117c2d2 6015 free (msg);
726f6388
JA
6016 }
6017
ccc6cda3
JA
6018 /* If not interactive, print the line containing the error. */
6019 if (interactive == 0)
7117c2d2 6020 print_offending_line ();
726f6388
JA
6021 }
6022 else
6023 {
b80f6443 6024 msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
ccc6cda3
JA
6025 parser_error (line_number, "%s", msg);
6026 /* When the shell is interactive, this file uses EOF_Reached
6027 only for error reporting. Other mechanisms are used to
6028 decide whether or not to exit. */
6029 if (interactive && EOF_Reached)
6030 EOF_Reached = 0;
726f6388 6031 }
7117c2d2 6032
0001803f 6033 last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE;
726f6388
JA
6034}
6035
6036/* ??? Needed function. ??? We have to be able to discard the constructs
6037 created during parsing. In the case of error, we want to return
6038 allocated objects to the memory pool. In the case of no error, we want
6039 to throw away the information about where the allocated objects live.
7117c2d2 6040 (dispose_command () will actually free the command.) */
ccc6cda3 6041static void
726f6388
JA
6042discard_parser_constructs (error_p)
6043 int error_p;
6044{
6045}
ccc6cda3 6046
7117c2d2
JA
6047/************************************************
6048 * *
6049 * EOF HANDLING *
6050 * *
6051 ************************************************/
6052
726f6388
JA
6053/* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
6054
6055/* A flag denoting whether or not ignoreeof is set. */
6056int ignoreeof = 0;
6057
6058/* The number of times that we have encountered an EOF character without
6059 another character intervening. When this gets above the limit, the
6060 shell terminates. */
6061int eof_encountered = 0;
6062
6063/* The limit for eof_encountered. */
6064int eof_encountered_limit = 10;
6065
6066/* If we have EOF as the only input unit, this user wants to leave
6067 the shell. If the shell is not interactive, then just leave.
6068 Otherwise, if ignoreeof is set, and we haven't done this the
6069 required number of times in a row, print a message. */
6070static void
6071handle_eof_input_unit ()
6072{
6073 if (interactive)
6074 {
6075 /* shell.c may use this to decide whether or not to write out the
6076 history, among other things. We use it only for error reporting
6077 in this file. */
6078 if (EOF_Reached)
6079 EOF_Reached = 0;
6080
6081 /* If the user wants to "ignore" eof, then let her do so, kind of. */
6082 if (ignoreeof)
6083 {
6084 if (eof_encountered < eof_encountered_limit)
6085 {
b80f6443 6086 fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
726f6388
JA
6087 login_shell ? "logout" : "exit");
6088 eof_encountered++;
7117c2d2
JA
6089 /* Reset the parsing state. */
6090 last_read_token = current_token = '\n';
726f6388
JA
6091 /* Reset the prompt string to be $PS1. */
6092 prompt_string_pointer = (char **)NULL;
6093 prompt_again ();
726f6388 6094 return;
ccc6cda3 6095 }
726f6388
JA
6096 }
6097
6098 /* In this case EOF should exit the shell. Do it now. */
6099 reset_parser ();
6100 exit_builtin ((WORD_LIST *)NULL);
6101 }
6102 else
6103 {
6104 /* We don't write history files, etc., for non-interactive shells. */
6105 EOF_Reached = 1;
6106 }
6107}
bb70624e 6108
7117c2d2
JA
6109/************************************************
6110 * *
6111 * STRING PARSING FUNCTIONS *
6112 * *
6113 ************************************************/
6114
6115/* It's very important that these two functions treat the characters
6116 between ( and ) identically. */
6117
bb70624e
JA
6118static WORD_LIST parse_string_error;
6119
6120/* Take a string and run it through the shell parser, returning the
6121 resultant word list. Used by compound array assignment. */
6122WORD_LIST *
b80f6443 6123parse_string_to_word_list (s, flags, whom)
f73dda09 6124 char *s;
b80f6443 6125 int flags;
f73dda09 6126 const char *whom;
bb70624e
JA
6127{
6128 WORD_LIST *wl;
7117c2d2 6129 int tok, orig_current_token, orig_line_number, orig_input_terminator;
28ef6c31 6130 int orig_line_count;
7117c2d2 6131 int old_echo_input, old_expand_aliases;
bb70624e
JA
6132#if defined (HISTORY)
6133 int old_remember_on_history, old_history_expansion_inhibited;
6134#endif
6135
6136#if defined (HISTORY)
6137 old_remember_on_history = remember_on_history;
6138# if defined (BANG_HISTORY)
6139 old_history_expansion_inhibited = history_expansion_inhibited;
6140# endif
6141 bash_history_disable ();
6142#endif
6143
6144 orig_line_number = line_number;
28ef6c31 6145 orig_line_count = current_command_line_count;
bb70624e 6146 orig_input_terminator = shell_input_line_terminator;
7117c2d2
JA
6147 old_echo_input = echo_input_at_read;
6148 old_expand_aliases = expand_aliases;
bb70624e
JA
6149
6150 push_stream (1);
7117c2d2 6151 last_read_token = WORD; /* WORD to allow reserved words here */
28ef6c31 6152 current_command_line_count = 0;
7117c2d2 6153 echo_input_at_read = expand_aliases = 0;
bb70624e
JA
6154
6155 with_input_from_string (s, whom);
6156 wl = (WORD_LIST *)NULL;
b80f6443
JA
6157
6158 if (flags & 1)
3185942a 6159 parser_state |= PST_COMPASSIGN|PST_REPARSE;
b80f6443 6160
bb70624e
JA
6161 while ((tok = read_token (READ)) != yacc_EOF)
6162 {
6163 if (tok == '\n' && *bash_input.location.string == '\0')
6164 break;
28ef6c31
JA
6165 if (tok == '\n') /* Allow newlines in compound assignments */
6166 continue;
bb70624e
JA
6167 if (tok != WORD && tok != ASSIGNMENT_WORD)
6168 {
6169 line_number = orig_line_number + line_number - 1;
7117c2d2
JA
6170 orig_current_token = current_token;
6171 current_token = tok;
95732b49 6172 yyerror (NULL); /* does the right thing */
7117c2d2 6173 current_token = orig_current_token;
bb70624e
JA
6174 if (wl)
6175 dispose_words (wl);
6176 wl = &parse_string_error;
6177 break;
6178 }
6179 wl = make_word_list (yylval.word, wl);
6180 }
6181
6182 last_read_token = '\n';
6183 pop_stream ();
6184
6185#if defined (HISTORY)
6186 remember_on_history = old_remember_on_history;
6187# if defined (BANG_HISTORY)
6188 history_expansion_inhibited = old_history_expansion_inhibited;
6189# endif /* BANG_HISTORY */
6190#endif /* HISTORY */
6191
7117c2d2
JA
6192 echo_input_at_read = old_echo_input;
6193 expand_aliases = old_expand_aliases;
6194
28ef6c31 6195 current_command_line_count = orig_line_count;
bb70624e
JA
6196 shell_input_line_terminator = orig_input_terminator;
6197
b80f6443 6198 if (flags & 1)
3185942a 6199 parser_state &= ~(PST_COMPASSIGN|PST_REPARSE);
b80f6443 6200
bb70624e
JA
6201 if (wl == &parse_string_error)
6202 {
6203 last_command_exit_value = EXECUTION_FAILURE;
6204 if (interactive_shell == 0 && posixly_correct)
6205 jump_to_top_level (FORCE_EOF);
6206 else
6207 jump_to_top_level (DISCARD);
6208 }
6209
6210 return (REVERSE_LIST (wl, WORD_LIST *));
6211}
7117c2d2
JA
6212
6213static char *
6214parse_compound_assignment (retlenp)
6215 int *retlenp;
6216{
6217 WORD_LIST *wl, *rl;
0628567a 6218 int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
7117c2d2
JA
6219 char *saved_token, *ret;
6220
6221 saved_token = token;
6222 orig_token_size = token_buffer_size;
6223 orig_line_number = line_number;
0628567a 6224 orig_last_token = last_read_token;
7117c2d2
JA
6225
6226 last_read_token = WORD; /* WORD to allow reserved words here */
6227
6228 token = (char *)NULL;
6229 token_buffer_size = 0;
6230
0628567a
JA
6231 assignok = parser_state&PST_ASSIGNOK; /* XXX */
6232
7117c2d2 6233 wl = (WORD_LIST *)NULL; /* ( */
b80f6443
JA
6234 parser_state |= PST_COMPASSIGN;
6235
7117c2d2
JA
6236 while ((tok = read_token (READ)) != ')')
6237 {
6238 if (tok == '\n') /* Allow newlines in compound assignments */
b80f6443
JA
6239 {
6240 if (SHOULD_PROMPT ())
6241 prompt_again ();
6242 continue;
6243 }
7117c2d2
JA
6244 if (tok != WORD && tok != ASSIGNMENT_WORD)
6245 {
6246 current_token = tok; /* for error reporting */
6247 if (tok == yacc_EOF) /* ( */
b80f6443 6248 parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
7117c2d2 6249 else
95732b49 6250 yyerror(NULL); /* does the right thing */
7117c2d2
JA
6251 if (wl)
6252 dispose_words (wl);
6253 wl = &parse_string_error;
6254 break;
6255 }
6256 wl = make_word_list (yylval.word, wl);
6257 }
6258
6259 FREE (token);
6260 token = saved_token;
6261 token_buffer_size = orig_token_size;
6262
b80f6443
JA
6263 parser_state &= ~PST_COMPASSIGN;
6264
7117c2d2
JA
6265 if (wl == &parse_string_error)
6266 {
6267 last_command_exit_value = EXECUTION_FAILURE;
6268 last_read_token = '\n'; /* XXX */
6269 if (interactive_shell == 0 && posixly_correct)
6270 jump_to_top_level (FORCE_EOF);
6271 else
6272 jump_to_top_level (DISCARD);
6273 }
6274
0628567a
JA
6275 last_read_token = orig_last_token; /* XXX - was WORD? */
6276
7117c2d2
JA
6277 if (wl)
6278 {
6279 rl = REVERSE_LIST (wl, WORD_LIST *);
6280 ret = string_list (rl);
6281 dispose_words (rl);
6282 }
6283 else
6284 ret = (char *)NULL;
6285
6286 if (retlenp)
6287 *retlenp = (ret && *ret) ? strlen (ret) : 0;
0628567a
JA
6288
6289 if (assignok)
6290 parser_state |= PST_ASSIGNOK;
6291
7117c2d2
JA
6292 return ret;
6293}
6294
b80f6443
JA
6295/************************************************
6296 * *
6297 * SAVING AND RESTORING PARTIAL PARSE STATE *
6298 * *
6299 ************************************************/
6300
6301sh_parser_state_t *
6302save_parser_state (ps)
6303 sh_parser_state_t *ps;
6304{
a0c0a00f
CR
6305 int i;
6306
b80f6443 6307 if (ps == 0)
95732b49 6308 ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
b80f6443
JA
6309 if (ps == 0)
6310 return ((sh_parser_state_t *)NULL);
6311
6312 ps->parser_state = parser_state;
6313 ps->token_state = save_token_state ();
6314
6315 ps->input_line_terminator = shell_input_line_terminator;
6316 ps->eof_encountered = eof_encountered;
6317
495aee44
CR
6318 ps->prompt_string_pointer = prompt_string_pointer;
6319
b80f6443
JA
6320 ps->current_command_line_count = current_command_line_count;
6321
6322#if defined (HISTORY)
6323 ps->remember_on_history = remember_on_history;
6324# if defined (BANG_HISTORY)
6325 ps->history_expansion_inhibited = history_expansion_inhibited;
6326# endif
6327#endif
6328
6329 ps->last_command_exit_value = last_command_exit_value;
6330#if defined (ARRAY_VARS)
495aee44 6331 ps->pipestatus = save_pipestatus_array ();
b80f6443
JA
6332#endif
6333
6334 ps->last_shell_builtin = last_shell_builtin;
6335 ps->this_shell_builtin = this_shell_builtin;
6336
6337 ps->expand_aliases = expand_aliases;
6338 ps->echo_input_at_read = echo_input_at_read;
daefb2c5 6339 ps->need_here_doc = need_here_doc;
a0c0a00f
CR
6340 ps->here_doc_first_line = here_doc_first_line;
6341
6342#if 0
6343 for (i = 0; i < HEREDOC_MAX; i++)
6344 ps->redir_stack[i] = redir_stack[i];
6345#else
6346 if (need_here_doc == 0)
6347 ps->redir_stack[0] = 0;
6348 else
6349 memcpy (ps->redir_stack, redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX);
6350#endif
b80f6443 6351
b4839c27
CR
6352 ps->token = token;
6353 ps->token_buffer_size = token_buffer_size;
6354 /* Force reallocation on next call to read_token_word */
6355 token = 0;
6356 token_buffer_size = 0;
6357
b80f6443
JA
6358 return (ps);
6359}
6360
6361void
6362restore_parser_state (ps)
6363 sh_parser_state_t *ps;
6364{
a0c0a00f
CR
6365 int i;
6366
b80f6443
JA
6367 if (ps == 0)
6368 return;
6369
6370 parser_state = ps->parser_state;
6371 if (ps->token_state)
6372 {
6373 restore_token_state (ps->token_state);
6374 free (ps->token_state);
6375 }
6376
6377 shell_input_line_terminator = ps->input_line_terminator;
6378 eof_encountered = ps->eof_encountered;
6379
495aee44
CR
6380 prompt_string_pointer = ps->prompt_string_pointer;
6381
b80f6443
JA
6382 current_command_line_count = ps->current_command_line_count;
6383
6384#if defined (HISTORY)
6385 remember_on_history = ps->remember_on_history;
6386# if defined (BANG_HISTORY)
6387 history_expansion_inhibited = ps->history_expansion_inhibited;
6388# endif
6389#endif
6390
6391 last_command_exit_value = ps->last_command_exit_value;
6392#if defined (ARRAY_VARS)
495aee44 6393 restore_pipestatus_array (ps->pipestatus);
b80f6443
JA
6394#endif
6395
6396 last_shell_builtin = ps->last_shell_builtin;
6397 this_shell_builtin = ps->this_shell_builtin;
6398
6399 expand_aliases = ps->expand_aliases;
6400 echo_input_at_read = ps->echo_input_at_read;
daefb2c5 6401 need_here_doc = ps->need_here_doc;
a0c0a00f
CR
6402 here_doc_first_line = ps->here_doc_first_line;
6403
6404#if 0
6405 for (i = 0; i < HEREDOC_MAX; i++)
6406 redir_stack[i] = ps->redir_stack[i];
6407#else
6408 if (need_here_doc == 0)
6409 redir_stack[0] = 0;
6410 else
6411 memcpy (redir_stack, ps->redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX);
6412#endif
b4839c27
CR
6413
6414 FREE (token);
6415 token = ps->token;
6416 token_buffer_size = ps->token_buffer_size;
6417}
6418
6419sh_input_line_state_t *
6420save_input_line_state (ls)
6421 sh_input_line_state_t *ls;
6422{
6423 if (ls == 0)
6424 ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t));
6425 if (ls == 0)
6426 return ((sh_input_line_state_t *)NULL);
6427
6428 ls->input_line = shell_input_line;
6429 ls->input_line_size = shell_input_line_size;
6430 ls->input_line_len = shell_input_line_len;
6431 ls->input_line_index = shell_input_line_index;
6432
6433 /* force reallocation */
6434 shell_input_line = 0;
6435 shell_input_line_size = shell_input_line_len = shell_input_line_index = 0;
ac50fbac
CR
6436
6437 return ls;
b4839c27
CR
6438}
6439
6440void
6441restore_input_line_state (ls)
6442 sh_input_line_state_t *ls;
6443{
6444 FREE (shell_input_line);
6445 shell_input_line = ls->input_line;
6446 shell_input_line_size = ls->input_line_size;
6447 shell_input_line_len = ls->input_line_len;
6448 shell_input_line_index = ls->input_line_index;
6449
6450 set_line_mbstate ();
b80f6443
JA
6451}
6452
7117c2d2
JA
6453/************************************************
6454 * *
6455 * MULTIBYTE CHARACTER HANDLING *
6456 * *
6457 ************************************************/
6458
6459#if defined (HANDLE_MULTIBYTE)
6460static void
6461set_line_mbstate ()
6462{
ac50fbac
CR
6463 int c;
6464 size_t i, previ, len;
7117c2d2
JA
6465 mbstate_t mbs, prevs;
6466 size_t mbclen;
6467
6468 if (shell_input_line == NULL)
6469 return;
6470 len = strlen (shell_input_line); /* XXX - shell_input_line_len ? */
a0c0a00f 6471 shell_input_line_property = (char *)xrealloc (shell_input_line_property, len + 1);
7117c2d2
JA
6472
6473 memset (&prevs, '\0', sizeof (mbstate_t));
6474 for (i = previ = 0; i < len; i++)
6475 {
6476 mbs = prevs;
6477
b80f6443
JA
6478 c = shell_input_line[i];
6479 if (c == EOF)
7117c2d2 6480 {
ac50fbac 6481 size_t j;
7117c2d2
JA
6482 for (j = i; j < len; j++)
6483 shell_input_line_property[j] = 1;
6484 break;
6485 }
6486
6487 mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
6488 if (mbclen == 1 || mbclen == (size_t)-1)
6489 {
6490 mbclen = 1;
6491 previ = i + 1;
6492 }
6493 else if (mbclen == (size_t)-2)
6494 mbclen = 0;
6495 else if (mbclen > 1)
6496 {
6497 mbclen = 0;
6498 previ = i + 1;
6499 prevs = mbs;
6500 }
6501 else
6502 {
b80f6443 6503 /* XXX - what to do if mbrlen returns 0? (null wide character) */
ac50fbac 6504 size_t j;
b80f6443
JA
6505 for (j = i; j < len; j++)
6506 shell_input_line_property[j] = 1;
6507 break;
7117c2d2
JA
6508 }
6509
6510 shell_input_line_property[i] = mbclen;
6511 }
6512}
6513#endif /* HANDLE_MULTIBYTE */