blob: 363430e5b60a9c286004fc108c4a11c3a60c07ff [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* Yacc grammar for bash. */
2
Jari Aaltob80f6442004-07-27 13:29:18 +00003/* Copyright (C) 1989-2004 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
Jari Aaltobb706242000-03-17 21:46:59 +00009 Software Foundation; either version 2, or (at your option) any later
Jari Aalto726f6381996-08-26 18:22:31 +000010 version.
11
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file LICENSE. If not, write to the Free Software
Jari Aaltobb706242000-03-17 21:46:59 +000019 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
Jari Aalto726f6381996-08-26 18:22:31 +000020
21%{
Jari Aaltoccc6cda1996-12-23 17:02:34 +000022#include "config.h"
23
Jari Aalto726f6381996-08-26 18:22:31 +000024#include "bashtypes.h"
Jari Aalto726f6381996-08-26 18:22:31 +000025#include "bashansi.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000026
Jari Aalto28ef6c32001-04-06 19:14:31 +000027#include "filecntl.h"
28
Jari Aaltoccc6cda1996-12-23 17:02:34 +000029#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>
Jari Aaltof73dda02001-11-13 17:56:06 +000038#include "chartypes.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000039#include <signal.h>
40
41#include "memalloc.h"
42
Jari Aaltob80f6442004-07-27 13:29:18 +000043#include "bashintl.h"
44
Jari Aalto7117c2d2002-07-17 14:10:11 +000045#define NEED_STRFTIME_DECL /* used in externs.h */
46
Jari Aalto726f6381996-08-26 18:22:31 +000047#include "shell.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000048#include "trap.h"
Jari Aalto726f6381996-08-26 18:22:31 +000049#include "flags.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000050#include "parser.h"
51#include "mailcheck.h"
Jari Aaltof73dda02001-11-13 17:56:06 +000052#include "test.h"
Jari Aaltoccc6cda1996-12-23 17:02:34 +000053#include "builtins/common.h"
54#include "builtins/builtext.h"
Jari Aalto726f6381996-08-26 18:22:31 +000055
Jari Aalto7117c2d2002-07-17 14:10:11 +000056#include "shmbutil.h"
57
Jari Aalto726f6381996-08-26 18:22:31 +000058#if defined (READLINE)
Jari Aaltoccc6cda1996-12-23 17:02:34 +000059# include "bashline.h"
Jari Aalto726f6381996-08-26 18:22:31 +000060# include <readline/readline.h>
61#endif /* READLINE */
62
63#if defined (HISTORY)
64# include "bashhist.h"
65# include <readline/history.h>
66#endif /* HISTORY */
67
68#if defined (JOB_CONTROL)
69# include "jobs.h"
70#endif /* JOB_CONTROL */
71
72#if defined (ALIAS)
73# include "alias.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000074#else
75typedef void *alias_t;
Jari Aalto726f6381996-08-26 18:22:31 +000076#endif /* ALIAS */
77
78#if defined (PROMPT_STRING_DECODE)
Jari Aaltocce855b1998-04-17 19:52:44 +000079# ifndef _MINIX
80# include <sys/param.h>
81# endif
82# include <time.h>
Jari Aalto7117c2d2002-07-17 14:10:11 +000083# if defined (TM_IN_SYS_TIME)
84# include <sys/types.h>
85# include <sys/time.h>
86# endif /* TM_IN_SYS_TIME */
Jari Aaltocce855b1998-04-17 19:52:44 +000087# include "maxpath.h"
Jari Aalto726f6381996-08-26 18:22:31 +000088#endif /* PROMPT_STRING_DECODE */
89
Jari Aaltoccc6cda1996-12-23 17:02:34 +000090#define RE_READ_TOKEN -99
91#define NO_EXPANSION -100
92
Jari Aalto7117c2d2002-07-17 14:10:11 +000093#ifdef DEBUG
94# define YYDEBUG 1
95#else
96# define YYDEBUG 0
97#endif
98
99#if defined (HANDLE_MULTIBYTE)
100# define last_shell_getc_is_singlebyte \
101 ((shell_input_line_index > 1) \
102 ? shell_input_line_property[shell_input_line_index - 1] \
103 : 1)
104# define MBTEST(x) ((x) && last_shell_getc_is_singlebyte)
105#else
106# define last_shell_getc_is_singlebyte 1
107# define MBTEST(x) ((x))
108#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000109
Jari Aaltocce855b1998-04-17 19:52:44 +0000110#if defined (EXTENDED_GLOB)
Jari Aaltocce855b1998-04-17 19:52:44 +0000111extern int extended_glob;
112#endif
113
Jari Aalto726f6381996-08-26 18:22:31 +0000114extern int eof_encountered;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000115extern int no_line_editing, running_under_emacs;
Jari Aalto726f6381996-08-26 18:22:31 +0000116extern int current_command_number;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000117extern int sourcelevel;
Jari Aalto726f6381996-08-26 18:22:31 +0000118extern int posixly_correct;
119extern int last_command_exit_value;
120extern int interrupt_immediately;
121extern char *shell_name, *current_host_name;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000122extern char *dist_version;
123extern int patch_level;
Jari Aaltocce855b1998-04-17 19:52:44 +0000124extern int dump_translatable_strings, dump_po_strings;
Jari Aaltof73dda02001-11-13 17:56:06 +0000125extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin;
Jari Aalto726f6381996-08-26 18:22:31 +0000126#if defined (BUFFERED_INPUT)
127extern int bash_input_fd_changed;
128#endif
129
Jari Aaltobb706242000-03-17 21:46:59 +0000130extern int errno;
Jari Aalto726f6381996-08-26 18:22:31 +0000131/* **************************************************************** */
132/* */
133/* "Forward" declarations */
134/* */
135/* **************************************************************** */
136
Jari Aaltof73dda02001-11-13 17:56:06 +0000137#ifdef DEBUG
138static void debug_parser __P((int));
Jari Aaltocce855b1998-04-17 19:52:44 +0000139#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000140
Jari Aaltof73dda02001-11-13 17:56:06 +0000141static int yy_getc __P((void));
142static int yy_ungetc __P((int));
143
144#if defined (READLINE)
145static int yy_readline_get __P((void));
146static int yy_readline_unget __P((int));
Jari Aaltod166f041997-06-05 14:59:13 +0000147#endif
Jari Aaltof73dda02001-11-13 17:56:06 +0000148
149static int yy_string_get __P((void));
150static int yy_string_unget __P((int));
151static int yy_stream_get __P((void));
152static int yy_stream_unget __P((int));
153
154static int shell_getc __P((int));
155static void shell_ungetc __P((int));
156static void discard_until __P((int));
157
158#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
159static void push_string __P((char *, int, alias_t *));
160static void pop_string __P((void));
161static void free_string_list __P((void));
162#endif
163
164static char *read_a_line __P((int));
165
Jari Aaltof73dda02001-11-13 17:56:06 +0000166static int reserved_word_acceptable __P((int));
167static int yylex __P((void));
168static int alias_expand_token __P((char *));
169static int time_command_acceptable __P((void));
170static int special_case_tokens __P((char *));
171static int read_token __P((int));
172static char *parse_matched_pair __P((int, int, int, int *, int));
Jari Aalto7117c2d2002-07-17 14:10:11 +0000173#if defined (ARRAY_VARS)
174static char *parse_compound_assignment __P((int *));
175#endif
Jari Aaltof73dda02001-11-13 17:56:06 +0000176#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000177static int parse_dparen __P((int));
Jari Aaltob80f6442004-07-27 13:29:18 +0000178static int parse_arith_cmd __P((char **, int));
Jari Aaltof73dda02001-11-13 17:56:06 +0000179#endif
180#if defined (COND_COMMAND)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000181static void cond_error __P((void));
Jari Aaltof73dda02001-11-13 17:56:06 +0000182static COND_COM *cond_expr __P((void));
183static COND_COM *cond_or __P((void));
184static COND_COM *cond_and __P((void));
185static COND_COM *cond_term __P((void));
186static int cond_skip_newlines __P((void));
187static COMMAND *parse_cond_command __P((void));
188#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000189#if defined (ARRAY_VARS)
190static int token_is_assignment __P((char *, int));
191static int token_is_ident __P((char *, int));
192#endif
Jari Aaltof73dda02001-11-13 17:56:06 +0000193static int read_token_word __P((int));
194static void discard_parser_constructs __P((int));
195
Jari Aalto7117c2d2002-07-17 14:10:11 +0000196static char *error_token_from_token __P((int));
197static char *error_token_from_text __P((void));
198static void print_offending_line __P((void));
Jari Aaltof73dda02001-11-13 17:56:06 +0000199static void report_syntax_error __P((char *));
Jari Aalto7117c2d2002-07-17 14:10:11 +0000200
Jari Aaltof73dda02001-11-13 17:56:06 +0000201static void handle_eof_input_unit __P((void));
202static void prompt_again __P((void));
203#if 0
204static void reset_readline_prompt __P((void));
205#endif
206static void print_prompt __P((void));
Jari Aalto726f6381996-08-26 18:22:31 +0000207
Jari Aalto28ef6c32001-04-06 19:14:31 +0000208#if defined (HISTORY)
Jari Aaltof73dda02001-11-13 17:56:06 +0000209char *history_delimiting_chars __P((void));
Jari Aalto28ef6c32001-04-06 19:14:31 +0000210#endif
211
Jari Aalto7117c2d2002-07-17 14:10:11 +0000212#if defined (HANDLE_MULTIBYTE)
213static void set_line_mbstate __P((void));
214static char *shell_input_line_property = NULL;
215#else
216# define set_line_mbstate()
217#endif
218
Jari Aaltof73dda02001-11-13 17:56:06 +0000219extern int yyerror __P((const char *));
Jari Aaltod166f041997-06-05 14:59:13 +0000220
Jari Aalto7117c2d2002-07-17 14:10:11 +0000221#ifdef DEBUG
222extern int yydebug;
223#endif
224
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000225/* Default prompt strings */
226char *primary_prompt = PPROMPT;
227char *secondary_prompt = SPROMPT;
228
Jari Aalto726f6381996-08-26 18:22:31 +0000229/* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
230char *ps1_prompt, *ps2_prompt;
231
232/* Handle on the current prompt string. Indirectly points through
233 ps1_ or ps2_prompt. */
234char **prompt_string_pointer = (char **)NULL;
235char *current_prompt_string;
236
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000237/* Non-zero means we expand aliases in commands. */
238int expand_aliases = 0;
239
240/* If non-zero, the decoded prompt string undergoes parameter and
241 variable substitution, command substitution, arithmetic substitution,
242 string expansion, process substitution, and quote removal in
243 decode_prompt_string. */
244int promptvars = 1;
245
Jari Aaltob80f6442004-07-27 13:29:18 +0000246/* If non-zero, $'...' and $"..." are expanded when they appear within
247 a ${...} expansion, even when the expansion appears within double
248 quotes. */
249int extended_quote = 1;
250
Jari Aalto726f6381996-08-26 18:22:31 +0000251/* The decoded prompt string. Used if READLINE is not defined or if
252 editing is turned off. Analogous to current_readline_prompt. */
253static char *current_decoded_prompt;
254
255/* The number of lines read from input while creating the current command. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000256int current_command_line_count;
Jari Aalto726f6381996-08-26 18:22:31 +0000257
258/* Variables to manage the task of reading here documents, because we need to
259 defer the reading until after a complete command has been collected. */
260static REDIRECT *redir_stack[10];
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000261int need_here_doc;
Jari Aalto726f6381996-08-26 18:22:31 +0000262
263/* Where shell input comes from. History expansion is performed on each
264 line when the shell is interactive. */
265static char *shell_input_line = (char *)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000266static int shell_input_line_index;
267static int shell_input_line_size; /* Amount allocated for shell_input_line. */
268static int shell_input_line_len; /* strlen (shell_input_line) */
Jari Aalto726f6381996-08-26 18:22:31 +0000269
270/* Either zero or EOF. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000271static int shell_input_line_terminator;
272
273/* The line number in a script on which a function definition starts. */
274static int function_dstart;
275
276/* The line number in a script on which a function body starts. */
277static int function_bstart;
Jari Aalto726f6381996-08-26 18:22:31 +0000278
Jari Aaltobb706242000-03-17 21:46:59 +0000279/* The line number in a script at which an arithmetic for command starts. */
280static int arith_for_lineno;
281
Jari Aaltob80f6442004-07-27 13:29:18 +0000282/* The line number in a script where the word in a `case WORD', `select WORD'
283 or `for WORD' begins. This is a nested command maximum, since the array
284 index is decremented after a case, select, or for command is parsed. */
285#define MAX_CASE_NEST 128
286static int word_lineno[MAX_CASE_NEST];
287static int word_top = -1;
288
289/* If non-zero, it is the token that we want read_token to return
290 regardless of what text is (or isn't) present to be read. This
291 is reset by read_token. If token_to_read == WORD or
292 ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */
293static int token_to_read;
294static WORD_DESC *word_desc_to_read;
295
Jari Aalto726f6381996-08-26 18:22:31 +0000296static REDIRECTEE redir;
297%}
298
299%union {
300 WORD_DESC *word; /* the word that we read. */
301 int number; /* the number that we read. */
302 WORD_LIST *word_list;
303 COMMAND *command;
304 REDIRECT *redirect;
305 ELEMENT element;
306 PATTERN_LIST *pattern;
307}
308
309/* Reserved words. Members of the first group are only recognized
310 in the case that they are preceded by a list_terminator. Members
Jari Aaltocce855b1998-04-17 19:52:44 +0000311 of the second group are for [[...]] commands. Members of the
312 third group are recognized only under special circumstances. */
Jari Aalto726f6381996-08-26 18:22:31 +0000313%token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION
Jari Aaltocce855b1998-04-17 19:52:44 +0000314%token COND_START COND_END COND_ERROR
Jari Aaltobb706242000-03-17 21:46:59 +0000315%token IN BANG TIME TIMEOPT
Jari Aalto726f6381996-08-26 18:22:31 +0000316
317/* More general tokens. yylex () knows how to make these. */
318%token <word> WORD ASSIGNMENT_WORD
319%token <number> NUMBER
Jari Aaltobb706242000-03-17 21:46:59 +0000320%token <word_list> ARITH_CMD ARITH_FOR_EXPRS
Jari Aaltocce855b1998-04-17 19:52:44 +0000321%token <command> COND_CMD
Jari Aalto7117c2d2002-07-17 14:10:11 +0000322%token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND LESS_LESS_LESS
Jari Aalto726f6381996-08-26 18:22:31 +0000323%token GREATER_AND SEMI_SEMI LESS_LESS_MINUS AND_GREATER LESS_GREATER
324%token GREATER_BAR
325
326/* The types that the various syntactical units return. */
327
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000328%type <command> inputunit command pipeline pipeline_command
329%type <command> list list0 list1 compound_list simple_list simple_list1
330%type <command> simple_command shell_command
331%type <command> for_command select_command case_command group_command
Jari Aaltocce855b1998-04-17 19:52:44 +0000332%type <command> arith_command
333%type <command> cond_command
Jari Aaltobb706242000-03-17 21:46:59 +0000334%type <command> arith_for_command
Jari Aalto28ef6c32001-04-06 19:14:31 +0000335%type <command> function_def function_body if_command elif_clause subshell
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000336%type <redirect> redirection redirection_list
Jari Aalto726f6381996-08-26 18:22:31 +0000337%type <element> simple_command_element
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000338%type <word_list> word_list pattern
339%type <pattern> pattern_list case_clause_sequence case_clause
340%type <number> timespec
Jari Aaltob80f6442004-07-27 13:29:18 +0000341%type <number> list_terminator
Jari Aalto726f6381996-08-26 18:22:31 +0000342
343%start inputunit
344
345%left '&' ';' '\n' yacc_EOF
346%left AND_AND OR_OR
347%right '|'
348%%
349
Jari Aalto7117c2d2002-07-17 14:10:11 +0000350inputunit: simple_list simple_list_terminator
Jari Aalto726f6381996-08-26 18:22:31 +0000351 {
352 /* Case of regular command. Discard the error
353 safety net,and return the command just parsed. */
354 global_command = $1;
355 eof_encountered = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000356 /* discard_parser_constructs (0); */
Jari Aalto726f6381996-08-26 18:22:31 +0000357 YYACCEPT;
358 }
359 | '\n'
360 {
361 /* Case of regular command, but not a very
362 interesting one. Return a NULL command. */
363 global_command = (COMMAND *)NULL;
364 YYACCEPT;
365 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000366 | error '\n'
Jari Aalto726f6381996-08-26 18:22:31 +0000367 {
368 /* Error during parsing. Return NULL command. */
369 global_command = (COMMAND *)NULL;
370 eof_encountered = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000371 /* discard_parser_constructs (1); */
Jari Aalto726f6381996-08-26 18:22:31 +0000372 if (interactive)
373 {
374 YYACCEPT;
375 }
376 else
377 {
378 YYABORT;
379 }
380 }
381 | yacc_EOF
382 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000383 /* Case of EOF seen by itself. Do ignoreeof or
Jari Aalto726f6381996-08-26 18:22:31 +0000384 not. */
385 global_command = (COMMAND *)NULL;
386 handle_eof_input_unit ();
387 YYACCEPT;
388 }
389 ;
390
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000391word_list: WORD
392 { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
393 | word_list WORD
Jari Aalto726f6381996-08-26 18:22:31 +0000394 { $$ = make_word_list ($2, $1); }
395 ;
396
397redirection: '>' WORD
398 {
399 redir.filename = $2;
400 $$ = make_redirection (1, r_output_direction, redir);
401 }
402 | '<' WORD
403 {
404 redir.filename = $2;
405 $$ = make_redirection (0, r_input_direction, redir);
406 }
407 | NUMBER '>' WORD
408 {
409 redir.filename = $3;
410 $$ = make_redirection ($1, r_output_direction, redir);
411 }
412 | NUMBER '<' WORD
413 {
414 redir.filename = $3;
415 $$ = make_redirection ($1, r_input_direction, redir);
416 }
417 | GREATER_GREATER WORD
418 {
419 redir.filename = $2;
420 $$ = make_redirection (1, r_appending_to, redir);
421 }
422 | NUMBER GREATER_GREATER WORD
423 {
424 redir.filename = $3;
425 $$ = make_redirection ($1, r_appending_to, redir);
426 }
427 | LESS_LESS WORD
428 {
429 redir.filename = $2;
430 $$ = make_redirection (0, r_reading_until, redir);
431 redir_stack[need_here_doc++] = $$;
432 }
433 | NUMBER LESS_LESS WORD
434 {
435 redir.filename = $3;
436 $$ = make_redirection ($1, r_reading_until, redir);
437 redir_stack[need_here_doc++] = $$;
438 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000439 | LESS_LESS_LESS WORD
440 {
441 redir.filename = $2;
442 $$ = make_redirection (0, r_reading_string, redir);
443 }
444 | NUMBER LESS_LESS_LESS WORD
445 {
446 redir.filename = $3;
447 $$ = make_redirection ($1, r_reading_string, redir);
448 }
Jari Aalto726f6381996-08-26 18:22:31 +0000449 | LESS_AND NUMBER
450 {
451 redir.dest = $2;
452 $$ = make_redirection (0, r_duplicating_input, redir);
453 }
454 | NUMBER LESS_AND NUMBER
455 {
456 redir.dest = $3;
457 $$ = make_redirection ($1, r_duplicating_input, redir);
458 }
459 | GREATER_AND NUMBER
460 {
461 redir.dest = $2;
462 $$ = make_redirection (1, r_duplicating_output, redir);
463 }
464 | NUMBER GREATER_AND NUMBER
465 {
466 redir.dest = $3;
467 $$ = make_redirection ($1, r_duplicating_output, redir);
468 }
469 | LESS_AND WORD
470 {
471 redir.filename = $2;
472 $$ = make_redirection (0, r_duplicating_input_word, redir);
473 }
474 | NUMBER LESS_AND WORD
475 {
476 redir.filename = $3;
477 $$ = make_redirection ($1, r_duplicating_input_word, redir);
478 }
479 | GREATER_AND WORD
480 {
481 redir.filename = $2;
482 $$ = make_redirection (1, r_duplicating_output_word, redir);
483 }
484 | NUMBER GREATER_AND WORD
485 {
486 redir.filename = $3;
487 $$ = make_redirection ($1, r_duplicating_output_word, redir);
488 }
489 | LESS_LESS_MINUS WORD
490 {
491 redir.filename = $2;
492 $$ = make_redirection
493 (0, r_deblank_reading_until, redir);
494 redir_stack[need_here_doc++] = $$;
495 }
496 | NUMBER LESS_LESS_MINUS WORD
497 {
498 redir.filename = $3;
499 $$ = make_redirection
500 ($1, r_deblank_reading_until, redir);
501 redir_stack[need_here_doc++] = $$;
502 }
503 | GREATER_AND '-'
504 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000505 redir.dest = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000506 $$ = make_redirection (1, r_close_this, redir);
507 }
508 | NUMBER GREATER_AND '-'
509 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000510 redir.dest = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000511 $$ = make_redirection ($1, r_close_this, redir);
512 }
513 | LESS_AND '-'
514 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000515 redir.dest = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000516 $$ = make_redirection (0, r_close_this, redir);
517 }
518 | NUMBER LESS_AND '-'
519 {
Jari Aaltof73dda02001-11-13 17:56:06 +0000520 redir.dest = 0;
Jari Aalto726f6381996-08-26 18:22:31 +0000521 $$ = make_redirection ($1, r_close_this, redir);
522 }
523 | AND_GREATER WORD
524 {
525 redir.filename = $2;
526 $$ = make_redirection (1, r_err_and_out, redir);
527 }
528 | NUMBER LESS_GREATER WORD
529 {
530 redir.filename = $3;
531 $$ = make_redirection ($1, r_input_output, redir);
532 }
533 | LESS_GREATER WORD
534 {
Jari Aalto726f6381996-08-26 18:22:31 +0000535 redir.filename = $2;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000536 $$ = make_redirection (0, r_input_output, redir);
537 }
Jari Aalto726f6381996-08-26 18:22:31 +0000538 | GREATER_BAR WORD
539 {
540 redir.filename = $2;
541 $$ = make_redirection (1, r_output_force, redir);
542 }
543 | NUMBER GREATER_BAR WORD
544 {
545 redir.filename = $3;
546 $$ = make_redirection ($1, r_output_force, redir);
547 }
548 ;
549
550simple_command_element: WORD
551 { $$.word = $1; $$.redirect = 0; }
552 | ASSIGNMENT_WORD
553 { $$.word = $1; $$.redirect = 0; }
554 | redirection
555 { $$.redirect = $1; $$.word = 0; }
556 ;
557
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000558redirection_list: redirection
Jari Aalto726f6381996-08-26 18:22:31 +0000559 {
560 $$ = $1;
561 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000562 | redirection_list redirection
563 {
564 register REDIRECT *t;
Jari Aalto726f6381996-08-26 18:22:31 +0000565
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000566 for (t = $1; t->next; t = t->next)
567 ;
568 t->next = $2;
Jari Aalto726f6381996-08-26 18:22:31 +0000569 $$ = $1;
570 }
571 ;
572
573simple_command: simple_command_element
574 { $$ = make_simple_command ($1, (COMMAND *)NULL); }
575 | simple_command simple_command_element
576 { $$ = make_simple_command ($2, $1); }
577 ;
578
579command: simple_command
580 { $$ = clean_simple_command ($1); }
581 | shell_command
582 { $$ = $1; }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000583 | shell_command redirection_list
Jari Aalto726f6381996-08-26 18:22:31 +0000584 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000585 COMMAND *tc;
586
587 tc = $1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000588 if (tc->redirects)
Jari Aalto726f6381996-08-26 18:22:31 +0000589 {
590 register REDIRECT *t;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000591 for (t = tc->redirects; t->next; t = t->next)
Jari Aalto726f6381996-08-26 18:22:31 +0000592 ;
593 t->next = $2;
594 }
595 else
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000596 tc->redirects = $2;
Jari Aalto726f6381996-08-26 18:22:31 +0000597 $$ = $1;
598 }
Jari Aalto28ef6c32001-04-06 19:14:31 +0000599 | function_def
600 { $$ = $1; }
Jari Aalto726f6381996-08-26 18:22:31 +0000601 ;
602
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000603shell_command: for_command
604 { $$ = $1; }
605 | case_command
606 { $$ = $1; }
607 | WHILE compound_list DO compound_list DONE
Jari Aalto726f6381996-08-26 18:22:31 +0000608 { $$ = make_while_command ($2, $4); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000609 | UNTIL compound_list DO compound_list DONE
Jari Aalto726f6381996-08-26 18:22:31 +0000610 { $$ = make_until_command ($2, $4); }
611 | select_command
612 { $$ = $1; }
613 | if_command
614 { $$ = $1; }
615 | subshell
616 { $$ = $1; }
617 | group_command
618 { $$ = $1; }
Jari Aaltocce855b1998-04-17 19:52:44 +0000619 | arith_command
620 { $$ = $1; }
621 | cond_command
622 { $$ = $1; }
Jari Aaltobb706242000-03-17 21:46:59 +0000623 | arith_for_command
624 { $$ = $1; }
Jari Aalto726f6381996-08-26 18:22:31 +0000625 ;
626
Jari Aaltod166f041997-06-05 14:59:13 +0000627for_command: FOR WORD newline_list DO compound_list DONE
Jari Aaltob80f6442004-07-27 13:29:18 +0000628 {
629 $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
630 if (word_top > 0) word_top--;
631 }
Jari Aaltod166f041997-06-05 14:59:13 +0000632 | FOR WORD newline_list '{' compound_list '}'
Jari Aaltob80f6442004-07-27 13:29:18 +0000633 {
634 $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
635 if (word_top > 0) word_top--;
636 }
Jari Aaltod166f041997-06-05 14:59:13 +0000637 | FOR WORD ';' newline_list DO compound_list DONE
Jari Aaltob80f6442004-07-27 13:29:18 +0000638 {
639 $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
640 if (word_top > 0) word_top--;
641 }
Jari Aaltod166f041997-06-05 14:59:13 +0000642 | FOR WORD ';' newline_list '{' compound_list '}'
Jari Aaltob80f6442004-07-27 13:29:18 +0000643 {
644 $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
645 if (word_top > 0) word_top--;
646 }
Jari Aaltod166f041997-06-05 14:59:13 +0000647 | FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE
Jari Aaltob80f6442004-07-27 13:29:18 +0000648 {
649 $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
650 if (word_top > 0) word_top--;
651 }
Jari Aaltod166f041997-06-05 14:59:13 +0000652 | FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}'
Jari Aaltob80f6442004-07-27 13:29:18 +0000653 {
654 $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
655 if (word_top > 0) word_top--;
656 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000657 | FOR WORD newline_list IN list_terminator newline_list DO compound_list DONE
Jari Aaltob80f6442004-07-27 13:29:18 +0000658 {
659 $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
660 if (word_top > 0) word_top--;
661 }
Jari Aaltof73dda02001-11-13 17:56:06 +0000662 | FOR WORD newline_list IN list_terminator newline_list '{' compound_list '}'
Jari Aaltob80f6442004-07-27 13:29:18 +0000663 {
664 $$ = make_for_command ($2, (WORD_LIST *)NULL, $8, word_lineno[word_top]);
665 if (word_top > 0) word_top--;
666 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000667 ;
668
Jari Aaltobb706242000-03-17 21:46:59 +0000669arith_for_command: FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE
Jari Aaltob80f6442004-07-27 13:29:18 +0000670 {
671 $$ = make_arith_for_command ($2, $6, arith_for_lineno);
672 if (word_top > 0) word_top--;
673 }
Jari Aaltobb706242000-03-17 21:46:59 +0000674 | FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}'
Jari Aaltob80f6442004-07-27 13:29:18 +0000675 {
676 $$ = make_arith_for_command ($2, $6, arith_for_lineno);
677 if (word_top > 0) word_top--;
678 }
Jari Aalto28ef6c32001-04-06 19:14:31 +0000679 | FOR ARITH_FOR_EXPRS DO compound_list DONE
Jari Aaltob80f6442004-07-27 13:29:18 +0000680 {
681 $$ = make_arith_for_command ($2, $4, arith_for_lineno);
682 if (word_top > 0) word_top--;
683 }
Jari Aalto28ef6c32001-04-06 19:14:31 +0000684 | FOR ARITH_FOR_EXPRS '{' compound_list '}'
Jari Aaltob80f6442004-07-27 13:29:18 +0000685 {
686 $$ = make_arith_for_command ($2, $4, arith_for_lineno);
687 if (word_top > 0) word_top--;
688 }
Jari Aaltobb706242000-03-17 21:46:59 +0000689 ;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000690
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000691select_command: SELECT WORD newline_list DO list DONE
Jari Aalto726f6381996-08-26 18:22:31 +0000692 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000693 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
694 if (word_top > 0) word_top--;
Jari Aalto726f6381996-08-26 18:22:31 +0000695 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000696 | SELECT WORD newline_list '{' list '}'
Jari Aalto726f6381996-08-26 18:22:31 +0000697 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000698 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5, word_lineno[word_top]);
699 if (word_top > 0) word_top--;
Jari Aalto726f6381996-08-26 18:22:31 +0000700 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000701 | SELECT WORD ';' newline_list DO list DONE
Jari Aalto726f6381996-08-26 18:22:31 +0000702 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000703 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
704 if (word_top > 0) word_top--;
Jari Aalto726f6381996-08-26 18:22:31 +0000705 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000706 | SELECT WORD ';' newline_list '{' list '}'
Jari Aalto726f6381996-08-26 18:22:31 +0000707 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000708 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6, word_lineno[word_top]);
709 if (word_top > 0) word_top--;
Jari Aalto726f6381996-08-26 18:22:31 +0000710 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000711 | SELECT WORD newline_list IN word_list list_terminator newline_list DO list DONE
Jari Aalto726f6381996-08-26 18:22:31 +0000712 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000713 $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
714 if (word_top > 0) word_top--;
Jari Aalto726f6381996-08-26 18:22:31 +0000715 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000716 | SELECT WORD newline_list IN word_list list_terminator newline_list '{' list '}'
Jari Aalto726f6381996-08-26 18:22:31 +0000717 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000718 $$ = make_select_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9, word_lineno[word_top]);
719 if (word_top > 0) word_top--;
Jari Aalto726f6381996-08-26 18:22:31 +0000720 }
721 ;
722
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000723case_command: CASE WORD newline_list IN newline_list ESAC
Jari Aaltob80f6442004-07-27 13:29:18 +0000724 {
725 $$ = make_case_command ($2, (PATTERN_LIST *)NULL, word_lineno[word_top]);
726 if (word_top > 0) word_top--;
727 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000728 | CASE WORD newline_list IN case_clause_sequence newline_list ESAC
Jari Aaltob80f6442004-07-27 13:29:18 +0000729 {
730 $$ = make_case_command ($2, $5, word_lineno[word_top]);
731 if (word_top > 0) word_top--;
732 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000733 | CASE WORD newline_list IN case_clause ESAC
Jari Aaltob80f6442004-07-27 13:29:18 +0000734 {
735 $$ = make_case_command ($2, $5, word_lineno[word_top]);
736 if (word_top > 0) word_top--;
737 }
Jari Aalto726f6381996-08-26 18:22:31 +0000738 ;
739
Jari Aalto28ef6c32001-04-06 19:14:31 +0000740function_def: WORD '(' ')' newline_list function_body
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000741 { $$ = make_function_def ($1, $5, function_dstart, function_bstart); }
742
Jari Aalto28ef6c32001-04-06 19:14:31 +0000743 | FUNCTION WORD '(' ')' newline_list function_body
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000744 { $$ = make_function_def ($2, $6, function_dstart, function_bstart); }
745
Jari Aalto28ef6c32001-04-06 19:14:31 +0000746 | FUNCTION WORD newline_list function_body
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000747 { $$ = make_function_def ($2, $4, function_dstart, function_bstart); }
748 ;
749
Jari Aalto28ef6c32001-04-06 19:14:31 +0000750
751function_body: shell_command
752 { $$ = $1; }
753 | shell_command redirection_list
754 {
755 COMMAND *tc;
756
757 tc = $1;
758 /* According to Posix.2 3.9.5, redirections
759 specified after the body of a function should
760 be attached to the function and performed when
761 the function is executed, not as part of the
762 function definition command. */
763 /* XXX - I don't think it matters, but we might
764 want to change this in the future to avoid
765 problems differentiating between a function
766 definition with a redirection and a function
767 definition containing a single command with a
768 redirection. The two are semantically equivalent,
769 though -- the only difference is in how the
770 command printing code displays the redirections. */
771 if (tc->redirects)
772 {
773 register REDIRECT *t;
774 for (t = tc->redirects; t->next; t = t->next)
775 ;
776 t->next = $2;
777 }
778 else
779 tc->redirects = $2;
780 $$ = $1;
781 }
782 ;
783
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000784subshell: '(' compound_list ')'
Jari Aaltobb706242000-03-17 21:46:59 +0000785 {
786 $$ = make_subshell_command ($2);
787 $$->flags |= CMD_WANT_SUBSHELL;
788 }
Jari Aalto726f6381996-08-26 18:22:31 +0000789 ;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000790
791if_command: IF compound_list THEN compound_list FI
Jari Aalto726f6381996-08-26 18:22:31 +0000792 { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000793 | IF compound_list THEN compound_list ELSE compound_list FI
Jari Aalto726f6381996-08-26 18:22:31 +0000794 { $$ = make_if_command ($2, $4, $6); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000795 | IF compound_list THEN compound_list elif_clause FI
Jari Aalto726f6381996-08-26 18:22:31 +0000796 { $$ = make_if_command ($2, $4, $5); }
797 ;
798
799
Jari Aalto28ef6c32001-04-06 19:14:31 +0000800group_command: '{' compound_list '}'
Jari Aalto726f6381996-08-26 18:22:31 +0000801 { $$ = make_group_command ($2); }
802 ;
803
Jari Aaltocce855b1998-04-17 19:52:44 +0000804arith_command: ARITH_CMD
805 { $$ = make_arith_command ($1); }
806 ;
807
808cond_command: COND_START COND_CMD COND_END
809 { $$ = $2; }
810 ;
811
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000812elif_clause: ELIF compound_list THEN compound_list
Jari Aalto726f6381996-08-26 18:22:31 +0000813 { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000814 | ELIF compound_list THEN compound_list ELSE compound_list
Jari Aalto726f6381996-08-26 18:22:31 +0000815 { $$ = make_if_command ($2, $4, $6); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000816 | ELIF compound_list THEN compound_list elif_clause
Jari Aalto726f6381996-08-26 18:22:31 +0000817 { $$ = make_if_command ($2, $4, $5); }
818 ;
819
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000820case_clause: pattern_list
Jari Aalto726f6381996-08-26 18:22:31 +0000821 | case_clause_sequence pattern_list
822 { $2->next = $1; $$ = $2; }
823 ;
824
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000825pattern_list: newline_list pattern ')' compound_list
Jari Aalto726f6381996-08-26 18:22:31 +0000826 { $$ = make_pattern_list ($2, $4); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000827 | newline_list pattern ')' newline_list
Jari Aalto726f6381996-08-26 18:22:31 +0000828 { $$ = make_pattern_list ($2, (COMMAND *)NULL); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000829 | newline_list '(' pattern ')' compound_list
Jari Aalto726f6381996-08-26 18:22:31 +0000830 { $$ = make_pattern_list ($3, $5); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000831 | newline_list '(' pattern ')' newline_list
Jari Aalto726f6381996-08-26 18:22:31 +0000832 { $$ = make_pattern_list ($3, (COMMAND *)NULL); }
833 ;
834
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000835case_clause_sequence: pattern_list SEMI_SEMI
836 | case_clause_sequence pattern_list SEMI_SEMI
837 { $2->next = $1; $$ = $2; }
838 ;
839
Jari Aalto726f6381996-08-26 18:22:31 +0000840pattern: WORD
841 { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
842 | pattern '|' WORD
843 { $$ = make_word_list ($3, $1); }
844 ;
845
846/* A list allows leading or trailing newlines and
847 newlines as operators (equivalent to semicolons).
848 It must end with a newline or semicolon.
849 Lists are used within commands such as if, for, while. */
850
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000851list: newline_list list0
Jari Aalto726f6381996-08-26 18:22:31 +0000852 {
853 $$ = $2;
854 if (need_here_doc)
855 gather_here_documents ();
856 }
857 ;
858
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000859compound_list: list
860 | newline_list list1
861 {
862 $$ = $2;
863 }
864 ;
865
866list0: list1 '\n' newline_list
867 | list1 '&' newline_list
Jari Aalto726f6381996-08-26 18:22:31 +0000868 {
869 if ($1->type == cm_connection)
870 $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
871 else
872 $$ = command_connect ($1, (COMMAND *)NULL, '&');
873 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000874 | list1 ';' newline_list
Jari Aalto726f6381996-08-26 18:22:31 +0000875
876 ;
877
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000878list1: list1 AND_AND newline_list list1
Jari Aalto726f6381996-08-26 18:22:31 +0000879 { $$ = command_connect ($1, $4, AND_AND); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000880 | list1 OR_OR newline_list list1
Jari Aalto726f6381996-08-26 18:22:31 +0000881 { $$ = command_connect ($1, $4, OR_OR); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000882 | list1 '&' newline_list list1
Jari Aalto726f6381996-08-26 18:22:31 +0000883 {
884 if ($1->type == cm_connection)
885 $$ = connect_async_list ($1, $4, '&');
886 else
887 $$ = command_connect ($1, $4, '&');
888 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000889 | list1 ';' newline_list list1
Jari Aalto726f6381996-08-26 18:22:31 +0000890 { $$ = command_connect ($1, $4, ';'); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000891 | list1 '\n' newline_list list1
Jari Aalto726f6381996-08-26 18:22:31 +0000892 { $$ = command_connect ($1, $4, ';'); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000893 | pipeline_command
Jari Aalto726f6381996-08-26 18:22:31 +0000894 { $$ = $1; }
Jari Aalto726f6381996-08-26 18:22:31 +0000895 ;
896
Jari Aalto7117c2d2002-07-17 14:10:11 +0000897simple_list_terminator: '\n'
898 | yacc_EOF
899 ;
900
Jari Aalto726f6381996-08-26 18:22:31 +0000901list_terminator:'\n'
Jari Aaltob80f6442004-07-27 13:29:18 +0000902 { $$ = '\n'; }
Jari Aalto726f6381996-08-26 18:22:31 +0000903 | ';'
Jari Aaltob80f6442004-07-27 13:29:18 +0000904 { $$ = ';'; }
Jari Aalto726f6381996-08-26 18:22:31 +0000905 | yacc_EOF
Jari Aaltob80f6442004-07-27 13:29:18 +0000906 { $$ = yacc_EOF; }
Jari Aalto726f6381996-08-26 18:22:31 +0000907 ;
908
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000909newline_list:
910 | newline_list '\n'
Jari Aalto726f6381996-08-26 18:22:31 +0000911 ;
912
913/* A simple_list is a list that contains no significant newlines
914 and no leading or trailing newlines. Newlines are allowed
915 only following operators, where they are not significant.
916
917 This is what an inputunit consists of. */
918
919simple_list: simple_list1
920 {
921 $$ = $1;
922 if (need_here_doc)
923 gather_here_documents ();
924 }
925 | simple_list1 '&'
926 {
927 if ($1->type == cm_connection)
928 $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
929 else
930 $$ = command_connect ($1, (COMMAND *)NULL, '&');
931 if (need_here_doc)
932 gather_here_documents ();
933 }
934 | simple_list1 ';'
935 {
936 $$ = $1;
937 if (need_here_doc)
938 gather_here_documents ();
939 }
940 ;
941
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000942simple_list1: simple_list1 AND_AND newline_list simple_list1
Jari Aalto726f6381996-08-26 18:22:31 +0000943 { $$ = command_connect ($1, $4, AND_AND); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000944 | simple_list1 OR_OR newline_list simple_list1
Jari Aalto726f6381996-08-26 18:22:31 +0000945 { $$ = command_connect ($1, $4, OR_OR); }
946 | simple_list1 '&' simple_list1
947 {
948 if ($1->type == cm_connection)
949 $$ = connect_async_list ($1, $3, '&');
950 else
951 $$ = command_connect ($1, $3, '&');
952 }
953 | simple_list1 ';' simple_list1
954 { $$ = command_connect ($1, $3, ';'); }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000955
956 | pipeline_command
957 { $$ = $1; }
958 ;
959
960pipeline_command: pipeline
Jari Aalto726f6381996-08-26 18:22:31 +0000961 { $$ = $1; }
962 | BANG pipeline
963 {
964 $2->flags |= CMD_INVERT_RETURN;
965 $$ = $2;
966 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000967 | timespec pipeline
968 {
969 $2->flags |= $1;
970 $$ = $2;
971 }
972 | timespec BANG pipeline
973 {
Jari Aaltobb706242000-03-17 21:46:59 +0000974 $3->flags |= $1|CMD_INVERT_RETURN;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000975 $$ = $3;
976 }
977 | BANG timespec pipeline
978 {
979 $3->flags |= $2|CMD_INVERT_RETURN;
980 $$ = $3;
981 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000982 | timespec list_terminator
983 {
984 ELEMENT x;
985
986 /* Boy, this is unclean. `time' by itself can
987 time a null command. We cheat and push a
988 newline back if the list_terminator was a newline
989 to avoid the double-newline problem (one to
990 terminate this, one to terminate the command) */
991 x.word = 0;
992 x.redirect = 0;
993 $$ = make_simple_command (x, (COMMAND *)NULL);
994 $$->flags |= $1;
995 /* XXX - let's cheat and push a newline back */
996 if ($2 == '\n')
997 token_to_read = '\n';
998 }
999
Jari Aalto726f6381996-08-26 18:22:31 +00001000 ;
1001
1002pipeline:
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001003 pipeline '|' newline_list pipeline
Jari Aalto726f6381996-08-26 18:22:31 +00001004 { $$ = command_connect ($1, $4, '|'); }
1005 | command
1006 { $$ = $1; }
1007 ;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001008
1009timespec: TIME
1010 { $$ = CMD_TIME_PIPELINE; }
1011 | TIME TIMEOPT
1012 { $$ = CMD_TIME_PIPELINE|CMD_TIME_POSIX; }
1013 ;
Jari Aalto726f6381996-08-26 18:22:31 +00001014%%
1015
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001016/* Possible states for the parser that require it to do special things. */
Jari Aaltob80f6442004-07-27 13:29:18 +00001017#define PST_CASEPAT 0x0001 /* in a case pattern list */
1018#define PST_ALEXPNEXT 0x0002 /* expand next word for aliases */
1019#define PST_ALLOWOPNBRC 0x0004 /* allow open brace for function def */
1020#define PST_NEEDCLOSBRC 0x0008 /* need close brace */
1021#define PST_DBLPAREN 0x0010 /* double-paren parsing */
1022#define PST_SUBSHELL 0x0020 /* ( ... ) subshell */
1023#define PST_CMDSUBST 0x0040 /* $( ... ) command substitution */
1024#define PST_CASESTMT 0x0080 /* parsing a case statement */
1025#define PST_CONDCMD 0x0100 /* parsing a [[...]] command */
1026#define PST_CONDEXPR 0x0200 /* parsing the guts of [[...]] */
1027#define PST_ARITHFOR 0x0400 /* parsing an arithmetic for command */
1028#define PST_ALEXPAND 0x0800 /* OK to expand aliases - unused */
1029#define PST_CMDTOKEN 0x1000 /* command token OK - unused */
1030#define PST_COMPASSIGN 0x2000 /* parsing x=(...) compound assignment */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001031
Jari Aalto726f6381996-08-26 18:22:31 +00001032/* Initial size to allocate for tokens, and the
1033 amount to grow them by. */
Jari Aaltod166f041997-06-05 14:59:13 +00001034#define TOKEN_DEFAULT_INITIAL_SIZE 496
Jari Aalto726f6381996-08-26 18:22:31 +00001035#define TOKEN_DEFAULT_GROW_SIZE 512
1036
Jari Aaltob80f6442004-07-27 13:29:18 +00001037/* Should we call prompt_again? */
1038#define SHOULD_PROMPT() \
1039 (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream))
1040
1041#if defined (ALIAS)
1042# define expanding_alias() (pushed_string_list && pushed_string_list->expander)
1043#else
1044# define expanding_alias() 0
1045#endif
1046
Jari Aalto726f6381996-08-26 18:22:31 +00001047/* The token currently being read. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001048static int current_token;
Jari Aalto726f6381996-08-26 18:22:31 +00001049
1050/* The last read token, or NULL. read_token () uses this for context
1051 checking. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001052static int last_read_token;
Jari Aalto726f6381996-08-26 18:22:31 +00001053
1054/* The token read prior to last_read_token. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001055static int token_before_that;
1056
1057/* The token read prior to token_before_that. */
1058static int two_tokens_ago;
Jari Aalto726f6381996-08-26 18:22:31 +00001059
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001060/* The current parser state. */
1061static int parser_state;
Jari Aalto726f6381996-08-26 18:22:31 +00001062
1063/* Global var is non-zero when end of file has been reached. */
1064int EOF_Reached = 0;
1065
Jari Aaltof73dda02001-11-13 17:56:06 +00001066#ifdef DEBUG
1067static void
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001068debug_parser (i)
1069 int i;
1070{
1071#if YYDEBUG != 0
1072 yydebug = i;
1073#endif
1074}
Jari Aaltof73dda02001-11-13 17:56:06 +00001075#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001076
Jari Aalto726f6381996-08-26 18:22:31 +00001077/* yy_getc () returns the next available character from input or EOF.
1078 yy_ungetc (c) makes `c' the next character to read.
1079 init_yy_io (get, unget, type, location) makes the function GET the
1080 installed function for getting the next character, makes UNGET the
1081 installed function for un-getting a character, sets the type of stream
1082 (either string or file) from TYPE, and makes LOCATION point to where
1083 the input is coming from. */
1084
1085/* Unconditionally returns end-of-file. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001086int
Jari Aalto726f6381996-08-26 18:22:31 +00001087return_EOF ()
1088{
1089 return (EOF);
1090}
1091
1092/* Variable containing the current get and unget functions.
1093 See ./input.h for a clearer description. */
1094BASH_INPUT bash_input;
1095
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001096/* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it
1097 is non-null, avoiding a memory leak. */
Jari Aalto726f6381996-08-26 18:22:31 +00001098void
1099initialize_bash_input ()
1100{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001101 bash_input.type = st_none;
1102 FREE (bash_input.name);
Jari Aalto726f6381996-08-26 18:22:31 +00001103 bash_input.name = (char *)NULL;
1104 bash_input.location.file = (FILE *)NULL;
1105 bash_input.location.string = (char *)NULL;
Jari Aaltof73dda02001-11-13 17:56:06 +00001106 bash_input.getter = (sh_cget_func_t *)NULL;
1107 bash_input.ungetter = (sh_cunget_func_t *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001108}
1109
1110/* Set the contents of the current bash input stream from
1111 GET, UNGET, TYPE, NAME, and LOCATION. */
1112void
1113init_yy_io (get, unget, type, name, location)
Jari Aaltof73dda02001-11-13 17:56:06 +00001114 sh_cget_func_t *get;
1115 sh_cunget_func_t *unget;
Jari Aaltod166f041997-06-05 14:59:13 +00001116 enum stream_type type;
Jari Aaltof73dda02001-11-13 17:56:06 +00001117 const char *name;
Jari Aalto726f6381996-08-26 18:22:31 +00001118 INPUT_STREAM location;
1119{
1120 bash_input.type = type;
1121 FREE (bash_input.name);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001122 bash_input.name = name ? savestring (name) : (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001123
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001124 /* XXX */
Jari Aalto726f6381996-08-26 18:22:31 +00001125#if defined (CRAY)
1126 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
1127#else
1128 bash_input.location = location;
1129#endif
1130 bash_input.getter = get;
1131 bash_input.ungetter = unget;
1132}
1133
Jari Aalto7117c2d2002-07-17 14:10:11 +00001134char *
1135yy_input_name ()
1136{
1137 return (bash_input.name ? bash_input.name : "stdin");
1138}
1139
Jari Aalto726f6381996-08-26 18:22:31 +00001140/* Call this to get the next character of input. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001141static int
Jari Aalto726f6381996-08-26 18:22:31 +00001142yy_getc ()
1143{
1144 return (*(bash_input.getter)) ();
1145}
1146
1147/* Call this to unget C. That is, to make C the next character
1148 to be read. */
Jari Aaltof73dda02001-11-13 17:56:06 +00001149static int
Jari Aalto726f6381996-08-26 18:22:31 +00001150yy_ungetc (c)
1151 int c;
1152{
1153 return (*(bash_input.ungetter)) (c);
1154}
1155
1156#if defined (BUFFERED_INPUT)
Jari Aaltof73dda02001-11-13 17:56:06 +00001157#ifdef INCLUDE_UNUSED
Jari Aalto726f6381996-08-26 18:22:31 +00001158int
1159input_file_descriptor ()
1160{
1161 switch (bash_input.type)
1162 {
1163 case st_stream:
1164 return (fileno (bash_input.location.file));
1165 case st_bstream:
1166 return (bash_input.location.buffered_fd);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001167 case st_stdin:
Jari Aalto726f6381996-08-26 18:22:31 +00001168 default:
1169 return (fileno (stdin));
1170 }
1171}
Jari Aaltof73dda02001-11-13 17:56:06 +00001172#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001173#endif /* BUFFERED_INPUT */
1174
1175/* **************************************************************** */
1176/* */
1177/* Let input be read from readline (). */
1178/* */
1179/* **************************************************************** */
1180
1181#if defined (READLINE)
1182char *current_readline_prompt = (char *)NULL;
1183char *current_readline_line = (char *)NULL;
1184int current_readline_line_index = 0;
1185
1186static int
1187yy_readline_get ()
1188{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001189 SigHandler *old_sigint;
Jari Aaltof73dda02001-11-13 17:56:06 +00001190 int line_len;
1191 unsigned char c;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001192
Jari Aalto726f6381996-08-26 18:22:31 +00001193 if (!current_readline_line)
1194 {
Jari Aalto726f6381996-08-26 18:22:31 +00001195 if (!bash_readline_initialized)
1196 initialize_readline ();
1197
1198#if defined (JOB_CONTROL)
1199 if (job_control)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001200 give_terminal_to (shell_pgrp, 0);
Jari Aalto726f6381996-08-26 18:22:31 +00001201#endif /* JOB_CONTROL */
1202
Jari Aaltof73dda02001-11-13 17:56:06 +00001203 old_sigint = (SigHandler *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00001204 if (signal_is_ignored (SIGINT) == 0)
1205 {
1206 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
1207 interrupt_immediately++;
1208 }
1209
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001210 current_readline_line = readline (current_readline_prompt ?
1211 current_readline_prompt : "");
Jari Aalto726f6381996-08-26 18:22:31 +00001212
Jari Aaltof73dda02001-11-13 17:56:06 +00001213 if (signal_is_ignored (SIGINT) == 0 && old_sigint)
Jari Aalto726f6381996-08-26 18:22:31 +00001214 {
1215 interrupt_immediately--;
1216 set_signal_handler (SIGINT, old_sigint);
1217 }
1218
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001219#if 0
1220 /* Reset the prompt to the decoded value of prompt_string_pointer. */
Jari Aalto726f6381996-08-26 18:22:31 +00001221 reset_readline_prompt ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001222#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001223
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001224 if (current_readline_line == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001225 return (EOF);
1226
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001227 current_readline_line_index = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001228 line_len = strlen (current_readline_line);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001229
Jari Aaltof73dda02001-11-13 17:56:06 +00001230 current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len);
Jari Aalto726f6381996-08-26 18:22:31 +00001231 current_readline_line[line_len++] = '\n';
1232 current_readline_line[line_len] = '\0';
1233 }
1234
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001235 if (current_readline_line[current_readline_line_index] == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001236 {
1237 free (current_readline_line);
1238 current_readline_line = (char *)NULL;
1239 return (yy_readline_get ());
1240 }
1241 else
1242 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001243 c = current_readline_line[current_readline_line_index++];
Jari Aalto726f6381996-08-26 18:22:31 +00001244 return (c);
1245 }
1246}
1247
1248static int
1249yy_readline_unget (c)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001250 int c;
Jari Aalto726f6381996-08-26 18:22:31 +00001251{
1252 if (current_readline_line_index && current_readline_line)
1253 current_readline_line[--current_readline_line_index] = c;
1254 return (c);
1255}
1256
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001257void
Jari Aalto726f6381996-08-26 18:22:31 +00001258with_input_from_stdin ()
1259{
1260 INPUT_STREAM location;
1261
1262 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
1263 {
1264 location.string = current_readline_line;
1265 init_yy_io (yy_readline_get, yy_readline_unget,
1266 st_stdin, "readline stdin", location);
1267 }
1268}
1269
1270#else /* !READLINE */
1271
1272void
1273with_input_from_stdin ()
1274{
1275 with_input_from_stream (stdin, "stdin");
1276}
1277#endif /* !READLINE */
1278
1279/* **************************************************************** */
1280/* */
1281/* Let input come from STRING. STRING is zero terminated. */
1282/* */
1283/* **************************************************************** */
1284
1285static int
1286yy_string_get ()
1287{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001288 register char *string;
Jari Aaltof73dda02001-11-13 17:56:06 +00001289 register unsigned char c;
Jari Aalto726f6381996-08-26 18:22:31 +00001290
1291 string = bash_input.location.string;
Jari Aalto726f6381996-08-26 18:22:31 +00001292
1293 /* If the string doesn't exist, or is empty, EOF found. */
1294 if (string && *string)
1295 {
Jari Aaltof73dda02001-11-13 17:56:06 +00001296 c = *string++;
Jari Aalto726f6381996-08-26 18:22:31 +00001297 bash_input.location.string = string;
Jari Aaltof73dda02001-11-13 17:56:06 +00001298 return (c);
Jari Aalto726f6381996-08-26 18:22:31 +00001299 }
Jari Aaltof73dda02001-11-13 17:56:06 +00001300 else
1301 return (EOF);
Jari Aalto726f6381996-08-26 18:22:31 +00001302}
1303
1304static int
1305yy_string_unget (c)
1306 int c;
1307{
1308 *(--bash_input.location.string) = c;
1309 return (c);
1310}
1311
1312void
1313with_input_from_string (string, name)
Jari Aaltof73dda02001-11-13 17:56:06 +00001314 char *string;
1315 const char *name;
Jari Aalto726f6381996-08-26 18:22:31 +00001316{
1317 INPUT_STREAM location;
1318
1319 location.string = string;
Jari Aalto726f6381996-08-26 18:22:31 +00001320 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
1321}
1322
1323/* **************************************************************** */
1324/* */
1325/* Let input come from STREAM. */
1326/* */
1327/* **************************************************************** */
1328
Jari Aaltobb706242000-03-17 21:46:59 +00001329/* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
1330 define, and just use getc/ungetc if it was defined, but since bash
1331 installs its signal handlers without the SA_RESTART flag, some signals
1332 (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
1333 the read to be restarted. We need to restart it ourselves. */
1334
Jari Aalto726f6381996-08-26 18:22:31 +00001335static int
1336yy_stream_get ()
1337{
Jari Aaltobb706242000-03-17 21:46:59 +00001338 int result;
Jari Aalto726f6381996-08-26 18:22:31 +00001339
Jari Aaltobb706242000-03-17 21:46:59 +00001340 result = EOF;
Jari Aalto726f6381996-08-26 18:22:31 +00001341 if (bash_input.location.file)
Jari Aaltobb706242000-03-17 21:46:59 +00001342 result = getc_with_restart (bash_input.location.file);
1343
Jari Aalto726f6381996-08-26 18:22:31 +00001344 return (result);
1345}
1346
1347static int
1348yy_stream_unget (c)
1349 int c;
1350{
Jari Aalto726f6381996-08-26 18:22:31 +00001351 return (ungetc_with_restart (c, bash_input.location.file));
Jari Aalto726f6381996-08-26 18:22:31 +00001352}
1353
1354void
1355with_input_from_stream (stream, name)
1356 FILE *stream;
Jari Aaltof73dda02001-11-13 17:56:06 +00001357 const char *name;
Jari Aalto726f6381996-08-26 18:22:31 +00001358{
1359 INPUT_STREAM location;
1360
1361 location.file = stream;
1362 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
1363}
1364
1365typedef struct stream_saver {
1366 struct stream_saver *next;
1367 BASH_INPUT bash_input;
1368 int line;
1369#if defined (BUFFERED_INPUT)
1370 BUFFERED_STREAM *bstream;
1371#endif /* BUFFERED_INPUT */
1372} STREAM_SAVER;
1373
1374/* The globally known line number. */
1375int line_number = 0;
1376
Jari Aaltocce855b1998-04-17 19:52:44 +00001377#if defined (COND_COMMAND)
1378static int cond_lineno;
1379static int cond_token;
1380#endif
1381
Jari Aalto726f6381996-08-26 18:22:31 +00001382STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
1383
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001384void
1385push_stream (reset_lineno)
1386 int reset_lineno;
Jari Aalto726f6381996-08-26 18:22:31 +00001387{
1388 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1389
1390 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1391
1392#if defined (BUFFERED_INPUT)
1393 saver->bstream = (BUFFERED_STREAM *)NULL;
1394 /* If we have a buffered stream, clear out buffers[fd]. */
1395 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
Jari Aaltocce855b1998-04-17 19:52:44 +00001396 saver->bstream = set_buffered_stream (bash_input.location.buffered_fd,
1397 (BUFFERED_STREAM *)NULL);
Jari Aalto726f6381996-08-26 18:22:31 +00001398#endif /* BUFFERED_INPUT */
1399
1400 saver->line = line_number;
1401 bash_input.name = (char *)NULL;
1402 saver->next = stream_list;
1403 stream_list = saver;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001404 EOF_Reached = 0;
1405 if (reset_lineno)
1406 line_number = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001407}
1408
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001409void
Jari Aalto726f6381996-08-26 18:22:31 +00001410pop_stream ()
1411{
Jari Aalto726f6381996-08-26 18:22:31 +00001412 if (!stream_list)
1413 EOF_Reached = 1;
1414 else
1415 {
1416 STREAM_SAVER *saver = stream_list;
1417
1418 EOF_Reached = 0;
1419 stream_list = stream_list->next;
1420
1421 init_yy_io (saver->bash_input.getter,
1422 saver->bash_input.ungetter,
1423 saver->bash_input.type,
1424 saver->bash_input.name,
1425 saver->bash_input.location);
1426
1427#if defined (BUFFERED_INPUT)
1428 /* If we have a buffered stream, restore buffers[fd]. */
1429 /* If the input file descriptor was changed while this was on the
1430 save stack, update the buffered fd to the new file descriptor and
1431 re-establish the buffer <-> bash_input fd correspondence. */
1432 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001433 {
1434 if (bash_input_fd_changed)
Jari Aalto726f6381996-08-26 18:22:31 +00001435 {
1436 bash_input_fd_changed = 0;
1437 if (default_buffered_input >= 0)
1438 {
1439 bash_input.location.buffered_fd = default_buffered_input;
1440 saver->bstream->b_fd = default_buffered_input;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001441 SET_CLOSE_ON_EXEC (default_buffered_input);
Jari Aalto726f6381996-08-26 18:22:31 +00001442 }
1443 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00001444 /* XXX could free buffered stream returned as result here. */
Jari Aaltocce855b1998-04-17 19:52:44 +00001445 set_buffered_stream (bash_input.location.buffered_fd, saver->bstream);
Jari Aalto28ef6c32001-04-06 19:14:31 +00001446 }
Jari Aalto726f6381996-08-26 18:22:31 +00001447#endif /* BUFFERED_INPUT */
1448
1449 line_number = saver->line;
1450
1451 FREE (saver->bash_input.name);
1452 free (saver);
1453 }
1454}
1455
1456/* Return 1 if a stream of type TYPE is saved on the stack. */
1457int
1458stream_on_stack (type)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001459 enum stream_type type;
Jari Aalto726f6381996-08-26 18:22:31 +00001460{
1461 register STREAM_SAVER *s;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001462
Jari Aalto726f6381996-08-26 18:22:31 +00001463 for (s = stream_list; s; s = s->next)
1464 if (s->bash_input.type == type)
1465 return 1;
1466 return 0;
1467}
1468
Jari Aaltobb706242000-03-17 21:46:59 +00001469/* Save the current token state and return it in a malloced array. */
1470int *
1471save_token_state ()
1472{
1473 int *ret;
1474
1475 ret = (int *)xmalloc (3 * sizeof (int));
1476 ret[0] = last_read_token;
1477 ret[1] = token_before_that;
1478 ret[2] = two_tokens_ago;
1479 return ret;
1480}
1481
1482void
1483restore_token_state (ts)
1484 int *ts;
1485{
1486 if (ts == 0)
1487 return;
1488 last_read_token = ts[0];
1489 token_before_that = ts[1];
1490 two_tokens_ago = ts[2];
1491}
1492
Jari Aalto726f6381996-08-26 18:22:31 +00001493/*
1494 * This is used to inhibit alias expansion and reserved word recognition
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001495 * inside case statement pattern lists. A `case statement pattern list' is:
1496 *
Jari Aalto726f6381996-08-26 18:22:31 +00001497 * everything between the `in' in a `case word in' and the next ')'
1498 * or `esac'
1499 * everything between a `;;' and the next `)' or `esac'
1500 */
Jari Aalto726f6381996-08-26 18:22:31 +00001501
Jari Aaltocce855b1998-04-17 19:52:44 +00001502#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1503
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001504#define END_OF_ALIAS 0
1505
Jari Aalto726f6381996-08-26 18:22:31 +00001506/*
1507 * Pseudo-global variables used in implementing token-wise alias expansion.
1508 */
1509
Jari Aalto726f6381996-08-26 18:22:31 +00001510/*
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001511 * Pushing and popping strings. This works together with shell_getc to
Jari Aalto726f6381996-08-26 18:22:31 +00001512 * implement alias expansion on a per-token basis.
1513 */
1514
1515typedef struct string_saver {
1516 struct string_saver *next;
1517 int expand_alias; /* Value to set expand_alias to when string is popped. */
1518 char *saved_line;
Jari Aaltocce855b1998-04-17 19:52:44 +00001519#if defined (ALIAS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001520 alias_t *expander; /* alias that caused this line to be pushed. */
Jari Aaltocce855b1998-04-17 19:52:44 +00001521#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001522 int saved_line_size, saved_line_index, saved_line_terminator;
1523} STRING_SAVER;
1524
1525STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1526
Jari Aalto726f6381996-08-26 18:22:31 +00001527/*
1528 * Push the current shell_input_line onto a stack of such lines and make S
1529 * the current input. Used when expanding aliases. EXPAND is used to set
1530 * the value of expand_next_token when the string is popped, so that the
1531 * word after the alias in the original line is handled correctly when the
1532 * alias expands to multiple words. TOKEN is the token that was expanded
1533 * into S; it is saved and used to prevent infinite recursive expansion.
1534 */
1535static void
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001536push_string (s, expand, ap)
Jari Aalto726f6381996-08-26 18:22:31 +00001537 char *s;
1538 int expand;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001539 alias_t *ap;
Jari Aalto726f6381996-08-26 18:22:31 +00001540{
Jari Aaltof73dda02001-11-13 17:56:06 +00001541 STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER));
Jari Aalto726f6381996-08-26 18:22:31 +00001542
1543 temp->expand_alias = expand;
1544 temp->saved_line = shell_input_line;
1545 temp->saved_line_size = shell_input_line_size;
1546 temp->saved_line_index = shell_input_line_index;
1547 temp->saved_line_terminator = shell_input_line_terminator;
Jari Aaltocce855b1998-04-17 19:52:44 +00001548#if defined (ALIAS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001549 temp->expander = ap;
Jari Aaltocce855b1998-04-17 19:52:44 +00001550#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001551 temp->next = pushed_string_list;
1552 pushed_string_list = temp;
1553
Jari Aaltocce855b1998-04-17 19:52:44 +00001554#if defined (ALIAS)
Jari Aaltod166f041997-06-05 14:59:13 +00001555 if (ap)
1556 ap->flags |= AL_BEINGEXPANDED;
Jari Aaltocce855b1998-04-17 19:52:44 +00001557#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001558
1559 shell_input_line = s;
1560 shell_input_line_size = strlen (s);
1561 shell_input_line_index = 0;
1562 shell_input_line_terminator = '\0';
Jari Aaltob80f6442004-07-27 13:29:18 +00001563#if 0
1564 parser_state &= ~PST_ALEXPNEXT; /* XXX */
1565#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +00001566
1567 set_line_mbstate ();
Jari Aalto726f6381996-08-26 18:22:31 +00001568}
1569
1570/*
1571 * Make the top of the pushed_string stack be the current shell input.
1572 * Only called when there is something on the stack. Called from shell_getc
1573 * when it thinks it has consumed the string generated by an alias expansion
1574 * and needs to return to the original input line.
1575 */
1576static void
1577pop_string ()
1578{
1579 STRING_SAVER *t;
1580
1581 FREE (shell_input_line);
1582 shell_input_line = pushed_string_list->saved_line;
1583 shell_input_line_index = pushed_string_list->saved_line_index;
1584 shell_input_line_size = pushed_string_list->saved_line_size;
1585 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001586
1587 if (pushed_string_list->expand_alias)
1588 parser_state |= PST_ALEXPNEXT;
1589 else
1590 parser_state &= ~PST_ALEXPNEXT;
Jari Aalto726f6381996-08-26 18:22:31 +00001591
1592 t = pushed_string_list;
1593 pushed_string_list = pushed_string_list->next;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001594
Jari Aaltocce855b1998-04-17 19:52:44 +00001595#if defined (ALIAS)
Jari Aaltod166f041997-06-05 14:59:13 +00001596 if (t->expander)
1597 t->expander->flags &= ~AL_BEINGEXPANDED;
Jari Aaltocce855b1998-04-17 19:52:44 +00001598#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001599
1600 free ((char *)t);
Jari Aalto7117c2d2002-07-17 14:10:11 +00001601
1602 set_line_mbstate ();
Jari Aalto726f6381996-08-26 18:22:31 +00001603}
1604
1605static void
1606free_string_list ()
1607{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001608 register STRING_SAVER *t, *t1;
Jari Aalto726f6381996-08-26 18:22:31 +00001609
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001610 for (t = pushed_string_list; t; )
Jari Aalto726f6381996-08-26 18:22:31 +00001611 {
1612 t1 = t->next;
1613 FREE (t->saved_line);
Jari Aaltocce855b1998-04-17 19:52:44 +00001614#if defined (ALIAS)
1615 if (t->expander)
1616 t->expander->flags &= ~AL_BEINGEXPANDED;
1617#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001618 free ((char *)t);
1619 t = t1;
1620 }
1621 pushed_string_list = (STRING_SAVER *)NULL;
1622}
1623
Jari Aaltocce855b1998-04-17 19:52:44 +00001624#endif /* ALIAS || DPAREN_ARITHMETIC */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001625
Jari Aaltob80f6442004-07-27 13:29:18 +00001626void
1627free_pushed_string_input ()
1628{
1629#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
1630 free_string_list ();
1631#endif
1632}
1633
Jari Aalto726f6381996-08-26 18:22:31 +00001634/* Return a line of text, taken from wherever yylex () reads input.
1635 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
1636 is non-zero, we remove unquoted \<newline> pairs. This is used by
1637 read_secondary_line to read here documents. */
1638static char *
1639read_a_line (remove_quoted_newline)
1640 int remove_quoted_newline;
1641{
1642 static char *line_buffer = (char *)NULL;
1643 static int buffer_size = 0;
1644 int indx = 0, c, peekc, pass_next;
1645
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001646#if defined (READLINE)
Jari Aaltob80f6442004-07-27 13:29:18 +00001647 if (no_line_editing && SHOULD_PROMPT ())
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001648#else
Jari Aaltob80f6442004-07-27 13:29:18 +00001649 if (SHOULD_PROMPT ())
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001650#endif
1651 print_prompt ();
1652
Jari Aalto726f6381996-08-26 18:22:31 +00001653 pass_next = 0;
1654 while (1)
1655 {
1656 c = yy_getc ();
1657
1658 /* Allow immediate exit if interrupted during input. */
1659 QUIT;
1660
Jari Aalto28ef6c32001-04-06 19:14:31 +00001661 /* Ignore null bytes in input. */
Jari Aalto726f6381996-08-26 18:22:31 +00001662 if (c == 0)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001663 {
1664#if 0
1665 internal_warning ("read_a_line: ignored null byte in input");
1666#endif
1667 continue;
1668 }
Jari Aalto726f6381996-08-26 18:22:31 +00001669
1670 /* If there is no more input, then we return NULL. */
1671 if (c == EOF)
1672 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001673 if (interactive && bash_input.type == st_stream)
1674 clearerr (stdin);
Jari Aalto726f6381996-08-26 18:22:31 +00001675 if (indx == 0)
1676 return ((char *)NULL);
1677 c = '\n';
1678 }
1679
1680 /* `+2' in case the final character in the buffer is a newline. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001681 RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128);
Jari Aalto726f6381996-08-26 18:22:31 +00001682
1683 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
1684 here document with an unquoted delimiter. In this case,
1685 the line will be expanded as if it were in double quotes.
1686 We allow a backslash to escape the next character, but we
1687 need to treat the backslash specially only if a backslash
1688 quoting a backslash-newline pair appears in the line. */
1689 if (pass_next)
Jari Aalto28ef6c32001-04-06 19:14:31 +00001690 {
Jari Aalto726f6381996-08-26 18:22:31 +00001691 line_buffer[indx++] = c;
1692 pass_next = 0;
Jari Aalto28ef6c32001-04-06 19:14:31 +00001693 }
Jari Aalto726f6381996-08-26 18:22:31 +00001694 else if (c == '\\' && remove_quoted_newline)
1695 {
1696 peekc = yy_getc ();
1697 if (peekc == '\n')
Jari Aaltob80f6442004-07-27 13:29:18 +00001698 {
1699 line_number++;
1700 continue; /* Make the unquoted \<newline> pair disappear. */
1701 }
Jari Aalto726f6381996-08-26 18:22:31 +00001702 else
1703 {
1704 yy_ungetc (peekc);
1705 pass_next = 1;
1706 line_buffer[indx++] = c; /* Preserve the backslash. */
1707 }
1708 }
1709 else
1710 line_buffer[indx++] = c;
1711
1712 if (c == '\n')
1713 {
1714 line_buffer[indx] = '\0';
1715 return (line_buffer);
1716 }
1717 }
1718}
1719
1720/* Return a line as in read_a_line (), but insure that the prompt is
1721 the secondary prompt. This is used to read the lines of a here
1722 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
1723 newlines quoted with backslashes while reading the line. It is
1724 non-zero unless the delimiter of the here document was quoted. */
1725char *
1726read_secondary_line (remove_quoted_newline)
1727 int remove_quoted_newline;
1728{
1729 prompt_string_pointer = &ps2_prompt;
Jari Aaltob80f6442004-07-27 13:29:18 +00001730 if (SHOULD_PROMPT())
1731 prompt_again ();
Jari Aalto726f6381996-08-26 18:22:31 +00001732 return (read_a_line (remove_quoted_newline));
1733}
1734
Jari Aalto726f6381996-08-26 18:22:31 +00001735/* **************************************************************** */
1736/* */
1737/* YYLEX () */
1738/* */
1739/* **************************************************************** */
1740
1741/* Reserved words. These are only recognized as the first word of a
1742 command. */
1743STRING_INT_ALIST word_token_alist[] = {
1744 { "if", IF },
1745 { "then", THEN },
1746 { "else", ELSE },
1747 { "elif", ELIF },
1748 { "fi", FI },
1749 { "case", CASE },
1750 { "esac", ESAC },
1751 { "for", FOR },
1752#if defined (SELECT_COMMAND)
1753 { "select", SELECT },
1754#endif
1755 { "while", WHILE },
1756 { "until", UNTIL },
1757 { "do", DO },
1758 { "done", DONE },
1759 { "in", IN },
1760 { "function", FUNCTION },
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001761#if defined (COMMAND_TIMING)
1762 { "time", TIME },
1763#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001764 { "{", '{' },
1765 { "}", '}' },
1766 { "!", BANG },
Jari Aaltocce855b1998-04-17 19:52:44 +00001767#if defined (COND_COMMAND)
1768 { "[[", COND_START },
1769 { "]]", COND_END },
1770#endif
Jari Aalto726f6381996-08-26 18:22:31 +00001771 { (char *)NULL, 0}
1772};
1773
Jari Aalto7117c2d2002-07-17 14:10:11 +00001774/* other tokens that can be returned by read_token() */
1775STRING_INT_ALIST other_token_alist[] = {
1776 /* Multiple-character tokens with special values */
1777 { "-p", TIMEOPT },
1778 { "&&", AND_AND },
1779 { "||", OR_OR },
1780 { ">>", GREATER_GREATER },
1781 { "<<", LESS_LESS },
1782 { "<&", LESS_AND },
1783 { ">&", GREATER_AND },
1784 { ";;", SEMI_SEMI },
1785 { "<<-", LESS_LESS_MINUS },
1786 { "<<<", LESS_LESS_LESS },
1787 { "&>", AND_GREATER },
1788 { "<>", LESS_GREATER },
1789 { ">|", GREATER_BAR },
1790 { "EOF", yacc_EOF },
1791 /* Tokens whose value is the character itself */
1792 { ">", '>' },
1793 { "<", '<' },
1794 { "-", '-' },
1795 { "{", '{' },
1796 { "}", '}' },
1797 { ";", ';' },
1798 { "(", '(' },
1799 { ")", ')' },
1800 { "|", '|' },
1801 { "&", '&' },
1802 { "newline", '\n' },
1803 { (char *)NULL, 0}
1804};
1805
1806/* others not listed here:
1807 WORD look at yylval.word
1808 ASSIGNMENT_WORD look at yylval.word
1809 NUMBER look at yylval.number
1810 ARITH_CMD look at yylval.word_list
1811 ARITH_FOR_EXPRS look at yylval.word_list
1812 COND_CMD look at yylval.command
1813*/
Jari Aaltob72432f1999-02-19 17:11:39 +00001814
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001815/* These are used by read_token_word, but appear up here so that shell_getc
1816 can use them to decide when to add otherwise blank lines to the history. */
1817
1818/* The primary delimiter stack. */
1819struct dstack dstack = { (char *)NULL, 0, 0 };
1820
1821/* A temporary delimiter stack to be used when decoding prompt strings.
1822 This is needed because command substitutions in prompt strings (e.g., PS2)
1823 can screw up the parser's quoting state. */
1824static struct dstack temp_dstack = { (char *)NULL, 0, 0 };
1825
1826/* Macro for accessing the top delimiter on the stack. Returns the
1827 delimiter or zero if none. */
1828#define current_delimiter(ds) \
1829 (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0)
1830
1831#define push_delimiter(ds, character) \
1832 do \
1833 { \
1834 if (ds.delimiter_depth + 2 > ds.delimiter_space) \
Jari Aaltof73dda02001-11-13 17:56:06 +00001835 ds.delimiters = (char *)xrealloc \
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001836 (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \
1837 ds.delimiters[ds.delimiter_depth] = character; \
1838 ds.delimiter_depth++; \
1839 } \
1840 while (0)
1841
1842#define pop_delimiter(ds) ds.delimiter_depth--
1843
Jari Aalto726f6381996-08-26 18:22:31 +00001844/* Return the next shell input character. This always reads characters
1845 from shell_input_line; when that line is exhausted, it is time to
1846 read the next line. This is called by read_token when the shell is
1847 processing normal command input. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001848
Jari Aalto28ef6c32001-04-06 19:14:31 +00001849/* This implements one-character lookahead/lookbehind across physical input
1850 lines, to avoid something being lost because it's pushed back with
1851 shell_ungetc when we're at the start of a line. */
1852static int eol_ungetc_lookahead = 0;
1853
Jari Aalto726f6381996-08-26 18:22:31 +00001854static int
1855shell_getc (remove_quoted_newline)
1856 int remove_quoted_newline;
1857{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001858 register int i;
Jari Aalto726f6381996-08-26 18:22:31 +00001859 int c;
Jari Aaltof73dda02001-11-13 17:56:06 +00001860 unsigned char uc;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001861 static int mustpop = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00001862
1863 QUIT;
1864
Jari Aalto28ef6c32001-04-06 19:14:31 +00001865 if (eol_ungetc_lookahead)
1866 {
1867 c = eol_ungetc_lookahead;
1868 eol_ungetc_lookahead = 0;
1869 return (c);
1870 }
1871
Jari Aaltocce855b1998-04-17 19:52:44 +00001872#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
Jari Aalto726f6381996-08-26 18:22:31 +00001873 /* If shell_input_line[shell_input_line_index] == 0, but there is
1874 something on the pushed list of strings, then we don't want to go
1875 off and get another line. We let the code down below handle it. */
1876
1877 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
1878 (pushed_string_list == (STRING_SAVER *)NULL)))
Jari Aaltocce855b1998-04-17 19:52:44 +00001879#else /* !ALIAS && !DPAREN_ARITHMETIC */
Jari Aalto726f6381996-08-26 18:22:31 +00001880 if (!shell_input_line || !shell_input_line[shell_input_line_index])
Jari Aaltocce855b1998-04-17 19:52:44 +00001881#endif /* !ALIAS && !DPAREN_ARITHMETIC */
Jari Aalto726f6381996-08-26 18:22:31 +00001882 {
Jari Aalto726f6381996-08-26 18:22:31 +00001883 line_number++;
1884
1885 restart_read:
1886
1887 /* Allow immediate exit if interrupted during input. */
1888 QUIT;
1889
1890 i = 0;
1891 shell_input_line_terminator = 0;
1892
Jari Aaltob80f6442004-07-27 13:29:18 +00001893 /* If the shell is interatctive, but not currently printing a prompt
1894 (interactive_shell && interactive == 0), we don't want to print
1895 notifies or cleanup the jobs -- we want to defer it until we do
1896 print the next prompt. */
1897 if (interactive_shell == 0 || SHOULD_PROMPT())
1898 {
Jari Aalto726f6381996-08-26 18:22:31 +00001899#if defined (JOB_CONTROL)
1900 /* This can cause a problem when reading a command as the result
1901 of a trap, when the trap is called from flush_child. This call
1902 had better not cause jobs to disappear from the job table in
1903 that case, or we will have big trouble. */
Jari Aaltob80f6442004-07-27 13:29:18 +00001904 notify_and_cleanup ();
Jari Aalto726f6381996-08-26 18:22:31 +00001905#else /* !JOB_CONTROL */
Jari Aaltob80f6442004-07-27 13:29:18 +00001906 cleanup_dead_jobs ();
Jari Aalto726f6381996-08-26 18:22:31 +00001907#endif /* !JOB_CONTROL */
Jari Aaltob80f6442004-07-27 13:29:18 +00001908 }
Jari Aalto726f6381996-08-26 18:22:31 +00001909
1910#if defined (READLINE)
Jari Aaltob80f6442004-07-27 13:29:18 +00001911 if (no_line_editing && SHOULD_PROMPT())
Jari Aalto726f6381996-08-26 18:22:31 +00001912#else
Jari Aaltob80f6442004-07-27 13:29:18 +00001913 if (SHOULD_PROMPT())
Jari Aalto726f6381996-08-26 18:22:31 +00001914#endif
1915 print_prompt ();
1916
1917 if (bash_input.type == st_stream)
1918 clearerr (stdin);
1919
Jari Aalto28ef6c32001-04-06 19:14:31 +00001920 while (1)
Jari Aalto726f6381996-08-26 18:22:31 +00001921 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00001922 c = yy_getc ();
1923
Jari Aalto726f6381996-08-26 18:22:31 +00001924 /* Allow immediate exit if interrupted during input. */
1925 QUIT;
1926
Jari Aalto28ef6c32001-04-06 19:14:31 +00001927 if (c == '\0')
1928 {
1929#if 0
1930 internal_warning ("shell_getc: ignored null byte in input");
1931#endif
1932 continue;
1933 }
1934
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001935 RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
Jari Aalto726f6381996-08-26 18:22:31 +00001936
1937 if (c == EOF)
1938 {
1939 if (bash_input.type == st_stream)
1940 clearerr (stdin);
1941
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001942 if (i == 0)
Jari Aalto726f6381996-08-26 18:22:31 +00001943 shell_input_line_terminator = EOF;
1944
1945 shell_input_line[i] = '\0';
1946 break;
1947 }
1948
1949 shell_input_line[i++] = c;
1950
1951 if (c == '\n')
1952 {
1953 shell_input_line[--i] = '\0';
1954 current_command_line_count++;
1955 break;
1956 }
1957 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00001958
Jari Aalto726f6381996-08-26 18:22:31 +00001959 shell_input_line_index = 0;
1960 shell_input_line_len = i; /* == strlen (shell_input_line) */
1961
Jari Aalto7117c2d2002-07-17 14:10:11 +00001962 set_line_mbstate ();
1963
Jari Aalto726f6381996-08-26 18:22:31 +00001964#if defined (HISTORY)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001965 if (remember_on_history && shell_input_line && shell_input_line[0])
Jari Aalto726f6381996-08-26 18:22:31 +00001966 {
1967 char *expansions;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001968# if defined (BANG_HISTORY)
1969 int old_hist;
Jari Aalto726f6381996-08-26 18:22:31 +00001970
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001971 /* If the current delimiter is a single quote, we should not be
1972 performing history expansion, even if we're on a different
1973 line from the original single quote. */
1974 old_hist = history_expansion_inhibited;
1975 if (current_delimiter (dstack) == '\'')
1976 history_expansion_inhibited = 1;
1977# endif
Jari Aalto726f6381996-08-26 18:22:31 +00001978 expansions = pre_process_line (shell_input_line, 1, 1);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00001979# if defined (BANG_HISTORY)
1980 history_expansion_inhibited = old_hist;
1981# endif
Jari Aaltod166f041997-06-05 14:59:13 +00001982 if (expansions != shell_input_line)
1983 {
1984 free (shell_input_line);
1985 shell_input_line = expansions;
1986 shell_input_line_len = shell_input_line ?
1987 strlen (shell_input_line) : 0;
1988 if (!shell_input_line_len)
1989 current_command_line_count--;
Jari Aalto726f6381996-08-26 18:22:31 +00001990
Jari Aaltod166f041997-06-05 14:59:13 +00001991 /* We have to force the xrealloc below because we don't know
Jari Aalto28ef6c32001-04-06 19:14:31 +00001992 the true allocated size of shell_input_line anymore. */
Jari Aaltod166f041997-06-05 14:59:13 +00001993 shell_input_line_size = shell_input_line_len;
Jari Aalto7117c2d2002-07-17 14:10:11 +00001994
1995 set_line_mbstate ();
Jari Aaltod166f041997-06-05 14:59:13 +00001996 }
Jari Aalto726f6381996-08-26 18:22:31 +00001997 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00001998 /* Try to do something intelligent with blank lines encountered while
1999 entering multi-line commands. XXX - this is grotesque */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002000 else if (remember_on_history && shell_input_line &&
2001 shell_input_line[0] == '\0' &&
Jari Aalto28ef6c32001-04-06 19:14:31 +00002002 current_command_line_count > 1)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002003 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00002004 if (current_delimiter (dstack))
2005 /* We know shell_input_line[0] == 0 and we're reading some sort of
2006 quoted string. This means we've got a line consisting of only
2007 a newline in a quoted string. We want to make sure this line
2008 gets added to the history. */
2009 maybe_add_history (shell_input_line);
2010 else
2011 {
2012 char *hdcs;
2013 hdcs = history_delimiting_chars ();
2014 if (hdcs && hdcs[0] == ';')
2015 maybe_add_history (shell_input_line);
2016 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002017 }
2018
Jari Aalto726f6381996-08-26 18:22:31 +00002019#endif /* HISTORY */
2020
2021 if (shell_input_line)
2022 {
2023 /* Lines that signify the end of the shell's input should not be
2024 echoed. */
2025 if (echo_input_at_read && (shell_input_line[0] ||
2026 shell_input_line_terminator != EOF))
2027 fprintf (stderr, "%s\n", shell_input_line);
2028 }
2029 else
2030 {
2031 shell_input_line_size = 0;
2032 prompt_string_pointer = &current_prompt_string;
Jari Aaltob80f6442004-07-27 13:29:18 +00002033 if (SHOULD_PROMPT ())
2034 prompt_again ();
Jari Aalto726f6381996-08-26 18:22:31 +00002035 goto restart_read;
2036 }
2037
2038 /* Add the newline to the end of this string, iff the string does
2039 not already end in an EOF character. */
2040 if (shell_input_line_terminator != EOF)
2041 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002042 if (shell_input_line_len + 3 > shell_input_line_size)
Jari Aaltof73dda02001-11-13 17:56:06 +00002043 shell_input_line = (char *)xrealloc (shell_input_line,
Jari Aalto726f6381996-08-26 18:22:31 +00002044 1 + (shell_input_line_size += 2));
2045
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002046 shell_input_line[shell_input_line_len] = '\n';
2047 shell_input_line[shell_input_line_len + 1] = '\0';
Jari Aalto7117c2d2002-07-17 14:10:11 +00002048
2049 set_line_mbstate ();
Jari Aalto726f6381996-08-26 18:22:31 +00002050 }
2051 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002052
Jari Aaltof73dda02001-11-13 17:56:06 +00002053 uc = shell_input_line[shell_input_line_index];
Jari Aalto726f6381996-08-26 18:22:31 +00002054
Jari Aaltof73dda02001-11-13 17:56:06 +00002055 if (uc)
Jari Aalto726f6381996-08-26 18:22:31 +00002056 shell_input_line_index++;
2057
Jari Aalto7117c2d2002-07-17 14:10:11 +00002058 if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n')
Jari Aalto726f6381996-08-26 18:22:31 +00002059 {
Jari Aaltob80f6442004-07-27 13:29:18 +00002060 if (SHOULD_PROMPT ())
2061 prompt_again ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002062 line_number++;
2063 goto restart_read;
Jari Aalto726f6381996-08-26 18:22:31 +00002064 }
2065
Jari Aaltocce855b1998-04-17 19:52:44 +00002066#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
Jari Aaltof73dda02001-11-13 17:56:06 +00002067 /* If UC is NULL, we have reached the end of the current input string. If
Jari Aalto726f6381996-08-26 18:22:31 +00002068 pushed_string_list is non-empty, it's time to pop to the previous string
2069 because we have fully consumed the result of the last alias expansion.
2070 Do it transparently; just return the next character of the string popped
2071 to. */
Jari Aaltof73dda02001-11-13 17:56:06 +00002072 if (!uc && (pushed_string_list != (STRING_SAVER *)NULL))
Jari Aalto726f6381996-08-26 18:22:31 +00002073 {
Jari Aaltob80f6442004-07-27 13:29:18 +00002074 pop_string ();
2075 uc = shell_input_line[shell_input_line_index];
2076 if (uc)
2077 shell_input_line_index++;
Jari Aalto726f6381996-08-26 18:22:31 +00002078 }
Jari Aaltocce855b1998-04-17 19:52:44 +00002079#endif /* ALIAS || DPAREN_ARITHMETIC */
Jari Aalto726f6381996-08-26 18:22:31 +00002080
Jari Aaltof73dda02001-11-13 17:56:06 +00002081 if (!uc && shell_input_line_terminator == EOF)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002082 return ((shell_input_line_index != 0) ? '\n' : EOF);
Jari Aalto726f6381996-08-26 18:22:31 +00002083
Jari Aaltof73dda02001-11-13 17:56:06 +00002084 return (uc);
Jari Aalto726f6381996-08-26 18:22:31 +00002085}
2086
Jari Aalto7117c2d2002-07-17 14:10:11 +00002087/* Put C back into the input for the shell. This might need changes for
2088 HANDLE_MULTIBYTE around EOLs. Since we (currently) never push back a
2089 character different than we read, shell_input_line_property doesn't need
2090 to change when manipulating shell_input_line. The define for
2091 last_shell_getc_is_singlebyte should take care of it, though. */
Jari Aalto726f6381996-08-26 18:22:31 +00002092static void
2093shell_ungetc (c)
2094 int c;
2095{
2096 if (shell_input_line && shell_input_line_index)
2097 shell_input_line[--shell_input_line_index] = c;
Jari Aalto28ef6c32001-04-06 19:14:31 +00002098 else
2099 eol_ungetc_lookahead = c;
Jari Aalto726f6381996-08-26 18:22:31 +00002100}
2101
Jari Aaltof73dda02001-11-13 17:56:06 +00002102#ifdef INCLUDE_UNUSED
2103/* Back the input pointer up by one, effectively `ungetting' a character. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002104static void
2105shell_ungetchar ()
2106{
2107 if (shell_input_line && shell_input_line_index)
2108 shell_input_line_index--;
2109}
Jari Aaltof73dda02001-11-13 17:56:06 +00002110#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002111
2112/* Discard input until CHARACTER is seen, then push that character back
2113 onto the input stream. */
Jari Aalto726f6381996-08-26 18:22:31 +00002114static void
2115discard_until (character)
2116 int character;
2117{
2118 int c;
2119
2120 while ((c = shell_getc (0)) != EOF && c != character)
2121 ;
2122
2123 if (c != EOF)
2124 shell_ungetc (c);
2125}
Jari Aalto726f6381996-08-26 18:22:31 +00002126
2127void
2128execute_prompt_command (command)
2129 char *command;
2130{
Jari Aalto726f6381996-08-26 18:22:31 +00002131 char *last_lastarg;
Jari Aaltob80f6442004-07-27 13:29:18 +00002132 sh_parser_state_t ps;
Jari Aalto726f6381996-08-26 18:22:31 +00002133
Jari Aaltob80f6442004-07-27 13:29:18 +00002134 save_parser_state (&ps);
Jari Aalto726f6381996-08-26 18:22:31 +00002135 last_lastarg = get_string_value ("_");
2136 if (last_lastarg)
2137 last_lastarg = savestring (last_lastarg);
2138
Jari Aaltod166f041997-06-05 14:59:13 +00002139 parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
Jari Aalto726f6381996-08-26 18:22:31 +00002140
Jari Aaltob80f6442004-07-27 13:29:18 +00002141 restore_parser_state (&ps);
Jari Aalto726f6381996-08-26 18:22:31 +00002142 bind_variable ("_", last_lastarg);
2143 FREE (last_lastarg);
2144
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002145 if (token_to_read == '\n') /* reset_parser was called */
Jari Aalto726f6381996-08-26 18:22:31 +00002146 token_to_read = 0;
2147}
2148
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002149/* Place to remember the token. We try to keep the buffer
2150 at a reasonable size, but it can grow. */
2151static char *token = (char *)NULL;
2152
2153/* Current size of the token buffer. */
2154static int token_buffer_size;
2155
Jari Aalto726f6381996-08-26 18:22:31 +00002156/* Command to read_token () explaining what we want it to do. */
2157#define READ 0
2158#define RESET 1
2159#define prompt_is_ps1 \
2160 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
2161
2162/* Function for yyparse to call. yylex keeps track of
2163 the last two tokens read, and calls read_token. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002164static int
Jari Aalto726f6381996-08-26 18:22:31 +00002165yylex ()
2166{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002167 if (interactive && (current_token == 0 || current_token == '\n'))
Jari Aalto726f6381996-08-26 18:22:31 +00002168 {
2169 /* Before we print a prompt, we might have to check mailboxes.
2170 We do this only if it is time to do so. Notice that only here
2171 is the mail alarm reset; nothing takes place in check_mail ()
2172 except the checking of mail. Please don't change this. */
2173 if (prompt_is_ps1 && time_to_check_mail ())
2174 {
2175 check_mail ();
2176 reset_mail_timer ();
2177 }
2178
2179 /* Avoid printing a prompt if we're not going to read anything, e.g.
2180 after resetting the parser with read_token (RESET). */
Jari Aaltob80f6442004-07-27 13:29:18 +00002181 if (token_to_read == 0 && SHOULD_PROMPT ())
Jari Aalto726f6381996-08-26 18:22:31 +00002182 prompt_again ();
2183 }
2184
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002185 two_tokens_ago = token_before_that;
Jari Aalto726f6381996-08-26 18:22:31 +00002186 token_before_that = last_read_token;
2187 last_read_token = current_token;
2188 current_token = read_token (READ);
2189 return (current_token);
2190}
2191
Jari Aalto726f6381996-08-26 18:22:31 +00002192/* When non-zero, we have read the required tokens
2193 which allow ESAC to be the next one read. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002194static int esacs_needed_count;
Jari Aalto726f6381996-08-26 18:22:31 +00002195
2196void
2197gather_here_documents ()
2198{
2199 int r = 0;
2200 while (need_here_doc)
2201 {
2202 make_here_document (redir_stack[r++]);
2203 need_here_doc--;
2204 }
2205}
2206
Jari Aalto726f6381996-08-26 18:22:31 +00002207/* When non-zero, an open-brace used to create a group is awaiting a close
2208 brace partner. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002209static int open_brace_count;
Jari Aalto726f6381996-08-26 18:22:31 +00002210
2211#define command_token_position(token) \
2212 (((token) == ASSIGNMENT_WORD) || \
2213 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
2214
Jari Aaltob80f6442004-07-27 13:29:18 +00002215#define assignment_acceptable(token) \
2216 (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0))
Jari Aalto726f6381996-08-26 18:22:31 +00002217
2218/* Check to see if TOKEN is a reserved word and return the token
2219 value if it is. */
2220#define CHECK_FOR_RESERVED_WORD(tok) \
2221 do { \
2222 if (!dollar_present && !quoted && \
2223 reserved_word_acceptable (last_read_token)) \
2224 { \
2225 int i; \
2226 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
2227 if (STREQ (tok, word_token_alist[i].word)) \
2228 { \
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002229 if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \
Jari Aalto726f6381996-08-26 18:22:31 +00002230 break; \
Jari Aaltob80f6442004-07-27 13:29:18 +00002231 if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \
Jari Aaltocce855b1998-04-17 19:52:44 +00002232 break; \
Jari Aalto726f6381996-08-26 18:22:31 +00002233 if (word_token_alist[i].token == ESAC) \
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002234 parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \
2235 else if (word_token_alist[i].token == CASE) \
2236 parser_state |= PST_CASESTMT; \
Jari Aaltocce855b1998-04-17 19:52:44 +00002237 else if (word_token_alist[i].token == COND_END) \
2238 parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \
2239 else if (word_token_alist[i].token == COND_START) \
2240 parser_state |= PST_CONDCMD; \
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002241 else if (word_token_alist[i].token == '{') \
2242 open_brace_count++; \
2243 else if (word_token_alist[i].token == '}' && open_brace_count) \
2244 open_brace_count--; \
Jari Aalto726f6381996-08-26 18:22:31 +00002245 return (word_token_alist[i].token); \
2246 } \
2247 } \
2248 } while (0)
2249
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002250#if defined (ALIAS)
2251
2252 /* OK, we have a token. Let's try to alias expand it, if (and only if)
2253 it's eligible.
2254
Jari Aalto7117c2d2002-07-17 14:10:11 +00002255 It is eligible for expansion if EXPAND_ALIASES is set, and
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002256 the token is unquoted and the last token read was a command
2257 separator (or expand_next_token is set), and we are currently
2258 processing an alias (pushed_string_list is non-empty) and this
2259 token is not the same as the current or any previously
2260 processed alias.
2261
2262 Special cases that disqualify:
2263 In a pattern list in a case statement (parser_state & PST_CASEPAT). */
Jari Aaltob80f6442004-07-27 13:29:18 +00002264
2265static char *
2266mk_alexpansion (s)
2267 char *s;
2268{
2269 int l;
2270 char *r;
2271
2272 l = strlen (s);
2273 r = xmalloc (l + 2);
2274 strcpy (r, s);
2275 if (r[l -1] != ' ')
2276 r[l++] = ' ';
2277 r[l] = '\0';
2278 return r;
2279}
2280
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002281static int
Jari Aaltof73dda02001-11-13 17:56:06 +00002282alias_expand_token (tokstr)
2283 char *tokstr;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002284{
2285 char *expanded;
2286 alias_t *ap;
2287
2288 if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) &&
2289 (parser_state & PST_CASEPAT) == 0)
2290 {
Jari Aaltof73dda02001-11-13 17:56:06 +00002291 ap = find_alias (tokstr);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002292
2293 /* Currently expanding this token. */
2294 if (ap && (ap->flags & AL_BEINGEXPANDED))
2295 return (NO_EXPANSION);
2296
Jari Aaltob80f6442004-07-27 13:29:18 +00002297 /* mk_alexpansion puts an extra space on the end of the alias expansion,
2298 so the lookahead by the parser works right. If this gets changed,
2299 make sure the code in shell_getc that deals with reaching the end of
2300 an expanded alias is changed with it. */
2301 expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL;
2302
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002303 if (expanded)
2304 {
2305 push_string (expanded, ap->flags & AL_EXPANDNEXT, ap);
2306 return (RE_READ_TOKEN);
2307 }
2308 else
2309 /* This is an eligible token that does not have an expansion. */
2310 return (NO_EXPANSION);
2311 }
2312 return (NO_EXPANSION);
2313}
2314#endif /* ALIAS */
2315
Jari Aaltocce855b1998-04-17 19:52:44 +00002316static int
2317time_command_acceptable ()
2318{
2319#if defined (COMMAND_TIMING)
2320 switch (last_read_token)
2321 {
2322 case 0:
2323 case ';':
2324 case '\n':
2325 case AND_AND:
2326 case OR_OR:
2327 case '&':
Jari Aaltob72432f1999-02-19 17:11:39 +00002328 case DO:
2329 case THEN:
2330 case ELSE:
Jari Aalto28ef6c32001-04-06 19:14:31 +00002331 case '{': /* } */
2332 case '(': /* ) */
Jari Aaltocce855b1998-04-17 19:52:44 +00002333 return 1;
2334 default:
2335 return 0;
2336 }
2337#else
2338 return 0;
2339#endif /* COMMAND_TIMING */
2340}
2341
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002342/* Handle special cases of token recognition:
2343 IN is recognized if the last token was WORD and the token
2344 before that was FOR or CASE or SELECT.
2345
2346 DO is recognized if the last token was WORD and the token
2347 before that was FOR or SELECT.
2348
2349 ESAC is recognized if the last token caused `esacs_needed_count'
2350 to be set
2351
2352 `{' is recognized if the last token as WORD and the token
Jari Aalto28ef6c32001-04-06 19:14:31 +00002353 before that was FUNCTION, or if we just parsed an arithmetic
2354 `for' command.
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002355
Jari Aalto28ef6c32001-04-06 19:14:31 +00002356 `}' is recognized if there is an unclosed `{' present.
Jari Aaltocce855b1998-04-17 19:52:44 +00002357
2358 `-p' is returned as TIMEOPT if the last read token was TIME.
2359
2360 ']]' is returned as COND_END if the parser is currently parsing
2361 a conditional expression ((parser_state & PST_CONDEXPR) != 0)
2362
2363 `time' is returned as TIME if and only if it is immediately
2364 preceded by one of `;', `\n', `||', `&&', or `&'.
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002365*/
2366
2367static int
Jari Aaltof73dda02001-11-13 17:56:06 +00002368special_case_tokens (tokstr)
2369 char *tokstr;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002370{
2371 if ((last_read_token == WORD) &&
2372#if defined (SELECT_COMMAND)
2373 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
2374#else
2375 ((token_before_that == FOR) || (token_before_that == CASE)) &&
2376#endif
Jari Aaltof73dda02001-11-13 17:56:06 +00002377 (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002378 {
2379 if (token_before_that == CASE)
2380 {
2381 parser_state |= PST_CASEPAT;
2382 esacs_needed_count++;
2383 }
2384 return (IN);
2385 }
2386
2387 if (last_read_token == WORD &&
2388#if defined (SELECT_COMMAND)
2389 (token_before_that == FOR || token_before_that == SELECT) &&
2390#else
2391 (token_before_that == FOR) &&
2392#endif
Jari Aaltof73dda02001-11-13 17:56:06 +00002393 (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0'))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002394 return (DO);
2395
2396 /* Ditto for ESAC in the CASE case.
2397 Specifically, this handles "case word in esac", which is a legal
2398 construct, certainly because someone will pass an empty arg to the
2399 case construct, and we don't want it to barf. Of course, we should
2400 insist that the case construct has at least one pattern in it, but
2401 the designers disagree. */
2402 if (esacs_needed_count)
2403 {
2404 esacs_needed_count--;
Jari Aaltof73dda02001-11-13 17:56:06 +00002405 if (STREQ (tokstr, "esac"))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002406 {
2407 parser_state &= ~PST_CASEPAT;
2408 return (ESAC);
2409 }
2410 }
2411
2412 /* The start of a shell function definition. */
2413 if (parser_state & PST_ALLOWOPNBRC)
2414 {
2415 parser_state &= ~PST_ALLOWOPNBRC;
Jari Aaltof73dda02001-11-13 17:56:06 +00002416 if (tokstr[0] == '{' && tokstr[1] == '\0') /* } */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002417 {
2418 open_brace_count++;
2419 function_bstart = line_number;
2420 return ('{'); /* } */
2421 }
2422 }
2423
Jari Aalto28ef6c32001-04-06 19:14:31 +00002424 /* We allow a `do' after a for ((...)) without an intervening
2425 list_terminator */
Jari Aaltof73dda02001-11-13 17:56:06 +00002426 if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2])
Jari Aalto28ef6c32001-04-06 19:14:31 +00002427 return (DO);
Jari Aaltof73dda02001-11-13 17:56:06 +00002428 if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0') /* } */
Jari Aalto28ef6c32001-04-06 19:14:31 +00002429 {
2430 open_brace_count++;
2431 return ('{'); /* } */
2432 }
2433
Jari Aaltof73dda02001-11-13 17:56:06 +00002434 if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1])
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002435 {
2436 open_brace_count--; /* { */
2437 return ('}');
2438 }
2439
Jari Aaltocce855b1998-04-17 19:52:44 +00002440#if defined (COMMAND_TIMING)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002441 /* Handle -p after `time'. */
Jari Aaltof73dda02001-11-13 17:56:06 +00002442 if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2])
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002443 return (TIMEOPT);
Jari Aaltocce855b1998-04-17 19:52:44 +00002444#endif
2445
Jari Aaltob80f6442004-07-27 13:29:18 +00002446#if 0
Jari Aaltocce855b1998-04-17 19:52:44 +00002447#if defined (COMMAND_TIMING)
Jari Aaltob72432f1999-02-19 17:11:39 +00002448 if (STREQ (token, "time") && ((parser_state & PST_CASEPAT) == 0) && time_command_acceptable ())
Jari Aaltocce855b1998-04-17 19:52:44 +00002449 return (TIME);
2450#endif /* COMMAND_TIMING */
Jari Aaltob80f6442004-07-27 13:29:18 +00002451#endif
Jari Aaltocce855b1998-04-17 19:52:44 +00002452
2453#if defined (COND_COMMAND) /* [[ */
Jari Aaltof73dda02001-11-13 17:56:06 +00002454 if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0')
Jari Aaltocce855b1998-04-17 19:52:44 +00002455 return (COND_END);
2456#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002457
2458 return (-1);
2459}
2460
2461/* Called from shell.c when Control-C is typed at top level. Or
2462 by the error rule at top level. */
2463void
2464reset_parser ()
2465{
2466 dstack.delimiter_depth = 0; /* No delimiters found so far. */
2467 open_brace_count = 0;
2468
2469 parser_state = 0;
2470
Jari Aaltocce855b1998-04-17 19:52:44 +00002471#if defined (ALIAS) || defined (DPAREN_ARITHMETIC)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002472 if (pushed_string_list)
Jari Aaltocce855b1998-04-17 19:52:44 +00002473 free_string_list ();
2474#endif /* ALIAS || DPAREN_ARITHMETIC */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002475
2476 if (shell_input_line)
2477 {
2478 free (shell_input_line);
2479 shell_input_line = (char *)NULL;
2480 shell_input_line_size = shell_input_line_index = 0;
2481 }
2482
2483 FREE (word_desc_to_read);
2484 word_desc_to_read = (WORD_DESC *)NULL;
2485
2486 last_read_token = '\n';
2487 token_to_read = '\n';
2488}
2489
2490/* Read the next token. Command can be READ (normal operation) or
Jari Aalto726f6381996-08-26 18:22:31 +00002491 RESET (to normalize state). */
2492static int
2493read_token (command)
2494 int command;
2495{
2496 int character; /* Current character. */
2497 int peek_char; /* Temporary look-ahead character. */
2498 int result; /* The thing to return. */
Jari Aalto726f6381996-08-26 18:22:31 +00002499
2500 if (command == RESET)
2501 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002502 reset_parser ();
Jari Aalto726f6381996-08-26 18:22:31 +00002503 return ('\n');
2504 }
2505
2506 if (token_to_read)
2507 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002508 result = token_to_read;
2509 if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD)
Jari Aaltod166f041997-06-05 14:59:13 +00002510 {
2511 yylval.word = word_desc_to_read;
2512 word_desc_to_read = (WORD_DESC *)NULL;
2513 }
Jari Aalto726f6381996-08-26 18:22:31 +00002514 token_to_read = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002515 return (result);
Jari Aalto726f6381996-08-26 18:22:31 +00002516 }
2517
Jari Aaltocce855b1998-04-17 19:52:44 +00002518#if defined (COND_COMMAND)
2519 if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD)
2520 {
2521 cond_lineno = line_number;
2522 parser_state |= PST_CONDEXPR;
2523 yylval.command = parse_cond_command ();
2524 if (cond_token != COND_END)
2525 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00002526 cond_error ();
Jari Aaltocce855b1998-04-17 19:52:44 +00002527 return (-1);
2528 }
2529 token_to_read = COND_END;
2530 parser_state &= ~(PST_CONDEXPR|PST_CONDCMD);
2531 return (COND_CMD);
2532 }
2533#endif
2534
Jari Aalto726f6381996-08-26 18:22:31 +00002535#if defined (ALIAS)
Jari Aalto726f6381996-08-26 18:22:31 +00002536 /* This is a place to jump back to once we have successfully expanded a
2537 token with an alias and pushed the string with push_string () */
2538 re_read_token:
Jari Aalto726f6381996-08-26 18:22:31 +00002539#endif /* ALIAS */
2540
2541 /* Read a single word from input. Start by skipping blanks. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002542 while ((character = shell_getc (1)) != EOF && whitespace (character))
2543 ;
Jari Aalto726f6381996-08-26 18:22:31 +00002544
2545 if (character == EOF)
2546 {
2547 EOF_Reached = 1;
2548 return (yacc_EOF);
2549 }
2550
Jari Aalto7117c2d2002-07-17 14:10:11 +00002551 if MBTEST(character == '#' && (!interactive || interactive_comments))
Jari Aalto726f6381996-08-26 18:22:31 +00002552 {
2553 /* A comment. Discard until EOL or EOF, and then return a newline. */
2554 discard_until ('\n');
2555 shell_getc (0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002556 character = '\n'; /* this will take the next if statement and return. */
Jari Aalto726f6381996-08-26 18:22:31 +00002557 }
2558
2559 if (character == '\n')
2560 {
2561 /* If we're about to return an unquoted newline, we can go and collect
2562 the text of any pending here document. */
2563 if (need_here_doc)
2564 gather_here_documents ();
2565
2566#if defined (ALIAS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002567 parser_state &= ~PST_ALEXPNEXT;
Jari Aalto726f6381996-08-26 18:22:31 +00002568#endif /* ALIAS */
2569
2570 return (character);
2571 }
2572
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002573 /* Shell meta-characters. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002574 if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0))
Jari Aalto726f6381996-08-26 18:22:31 +00002575 {
2576#if defined (ALIAS)
2577 /* Turn off alias tokenization iff this character sequence would
2578 not leave us ready to read a command. */
2579 if (character == '<' || character == '>')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002580 parser_state &= ~PST_ALEXPNEXT;
Jari Aalto726f6381996-08-26 18:22:31 +00002581#endif /* ALIAS */
2582
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002583 peek_char = shell_getc (1);
2584 if (character == peek_char)
Jari Aalto726f6381996-08-26 18:22:31 +00002585 {
2586 switch (character)
2587 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002588 case '<':
Jari Aalto726f6381996-08-26 18:22:31 +00002589 /* If '<' then we could be at "<<" or at "<<-". We have to
2590 look ahead one more character. */
Jari Aalto726f6381996-08-26 18:22:31 +00002591 peek_char = shell_getc (1);
2592 if (peek_char == '-')
2593 return (LESS_LESS_MINUS);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002594 else if (peek_char == '<')
2595 return (LESS_LESS_LESS);
Jari Aalto726f6381996-08-26 18:22:31 +00002596 else
2597 {
2598 shell_ungetc (peek_char);
2599 return (LESS_LESS);
2600 }
2601
2602 case '>':
2603 return (GREATER_GREATER);
2604
2605 case ';':
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002606 parser_state |= PST_CASEPAT;
Jari Aalto726f6381996-08-26 18:22:31 +00002607#if defined (ALIAS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002608 parser_state &= ~PST_ALEXPNEXT;
Jari Aalto726f6381996-08-26 18:22:31 +00002609#endif /* ALIAS */
2610 return (SEMI_SEMI);
2611
2612 case '&':
2613 return (AND_AND);
2614
2615 case '|':
2616 return (OR_OR);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002617
Jari Aaltobb706242000-03-17 21:46:59 +00002618#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002619 case '(': /* ) */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002620 result = parse_dparen (character);
2621 if (result == -2)
2622 break;
2623 else
2624 return result;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002625#endif
Jari Aalto726f6381996-08-26 18:22:31 +00002626 }
Jari Aalto726f6381996-08-26 18:22:31 +00002627 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00002628 else if MBTEST(character == '<' && peek_char == '&')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002629 return (LESS_AND);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002630 else if MBTEST(character == '>' && peek_char == '&')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002631 return (GREATER_AND);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002632 else if MBTEST(character == '<' && peek_char == '>')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002633 return (LESS_GREATER);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002634 else if MBTEST(character == '>' && peek_char == '|')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002635 return (GREATER_BAR);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002636 else if MBTEST(peek_char == '>' && character == '&')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002637 return (AND_GREATER);
2638
Jari Aalto726f6381996-08-26 18:22:31 +00002639 shell_ungetc (peek_char);
2640
2641 /* If we look like we are reading the start of a function
2642 definition, then let the reader know about it so that
2643 we will do the right thing with `{'. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002644 if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD)
Jari Aalto726f6381996-08-26 18:22:31 +00002645 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002646 parser_state |= PST_ALLOWOPNBRC;
Jari Aalto726f6381996-08-26 18:22:31 +00002647#if defined (ALIAS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002648 parser_state &= ~PST_ALEXPNEXT;
Jari Aalto726f6381996-08-26 18:22:31 +00002649#endif /* ALIAS */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002650 function_dstart = line_number;
Jari Aalto726f6381996-08-26 18:22:31 +00002651 }
2652
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002653 /* case pattern lists may be preceded by an optional left paren. If
2654 we're not trying to parse a case pattern list, the left paren
2655 indicates a subshell. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002656 if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002657 parser_state |= PST_SUBSHELL;
2658 /*(*/
Jari Aalto7117c2d2002-07-17 14:10:11 +00002659 else if MBTEST((parser_state & PST_CASEPAT) && character == ')')
Jari Aalto28ef6c32001-04-06 19:14:31 +00002660 parser_state &= ~PST_CASEPAT;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002661 /*(*/
Jari Aalto7117c2d2002-07-17 14:10:11 +00002662 else if MBTEST((parser_state & PST_SUBSHELL) && character == ')')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002663 parser_state &= ~PST_SUBSHELL;
Jari Aalto726f6381996-08-26 18:22:31 +00002664
2665#if defined (PROCESS_SUBSTITUTION)
2666 /* Check for the constructs which introduce process substitution.
2667 Shells running in `posix mode' don't do process substitution. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002668 if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/
Jari Aalto726f6381996-08-26 18:22:31 +00002669#endif /* PROCESS_SUBSTITUTION */
2670 return (character);
2671 }
2672
Jari Aalto7117c2d2002-07-17 14:10:11 +00002673 /* Hack <&- (close stdin) case. Also <&N- (dup and close). */
2674 if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002675 return (character);
2676
Jari Aalto726f6381996-08-26 18:22:31 +00002677 /* Okay, if we got this far, we have to read a word. Read one,
2678 and then check it against the known ones. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002679 result = read_token_word (character);
2680#if defined (ALIAS)
2681 if (result == RE_READ_TOKEN)
2682 goto re_read_token;
2683#endif
2684 return result;
2685}
Jari Aalto726f6381996-08-26 18:22:31 +00002686
Jari Aalto7117c2d2002-07-17 14:10:11 +00002687/*
2688 * Match a $(...) or other grouping construct. This has to handle embedded
2689 * quoted strings ('', ``, "") and nested constructs. It also must handle
2690 * reprompting the user, if necessary, after reading a newline (unless the
2691 * P_NONL flag is passed), and returning correct error values if it reads
2692 * EOF.
2693 */
Jari Aaltob72432f1999-02-19 17:11:39 +00002694#define P_FIRSTCLOSE 0x01
Jari Aaltobb706242000-03-17 21:46:59 +00002695#define P_ALLOWESC 0x02
Jari Aaltob80f6442004-07-27 13:29:18 +00002696#define P_DQUOTE 0x04
Jari Aaltob72432f1999-02-19 17:11:39 +00002697
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002698static char matched_pair_error;
2699static char *
2700parse_matched_pair (qc, open, close, lenp, flags)
2701 int qc; /* `"' if this construct is within double quotes */
2702 int open, close;
2703 int *lenp, flags;
2704{
2705 int count, ch, was_dollar;
Jari Aalto28ef6c32001-04-06 19:14:31 +00002706 int pass_next_character, nestlen, ttranslen, start_lineno;
2707 char *ret, *nestret, *ttrans;
Jari Aaltob80f6442004-07-27 13:29:18 +00002708 int retind, retsize, rflags;
Jari Aalto726f6381996-08-26 18:22:31 +00002709
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002710 count = 1;
2711 pass_next_character = was_dollar = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002712
Jari Aaltob80f6442004-07-27 13:29:18 +00002713 /* RFLAGS is the set of flags we want to pass to recursive calls. */
2714 rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE);
2715
Jari Aaltof73dda02001-11-13 17:56:06 +00002716 ret = (char *)xmalloc (retsize = 64);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002717 retind = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00002718
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002719 start_lineno = line_number;
2720 while (count)
2721 {
Jari Aaltobb706242000-03-17 21:46:59 +00002722 ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002723 if (ch == EOF)
2724 {
2725 free (ret);
Jari Aaltob80f6442004-07-27 13:29:18 +00002726 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002727 EOF_Reached = 1; /* XXX */
2728 return (&matched_pair_error);
2729 }
Jari Aalto726f6381996-08-26 18:22:31 +00002730
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002731 /* Possible reprompting. */
Jari Aaltob80f6442004-07-27 13:29:18 +00002732 if (ch == '\n' && SHOULD_PROMPT ())
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002733 prompt_again ();
Jari Aalto726f6381996-08-26 18:22:31 +00002734
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002735 if (pass_next_character) /* last char was backslash */
2736 {
2737 pass_next_character = 0;
2738 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
2739 {
2740 if (retind > 0) retind--; /* swallow previously-added backslash */
2741 continue;
2742 }
Jari Aalto726f6381996-08-26 18:22:31 +00002743
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002744 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002745 if MBTEST(ch == CTLESC || ch == CTLNUL)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002746 ret[retind++] = CTLESC;
2747 ret[retind++] = ch;
2748 continue;
2749 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00002750 else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002751 {
2752 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2753 ret[retind++] = CTLESC;
2754 ret[retind++] = ch;
2755 continue;
2756 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00002757 else if MBTEST(ch == close) /* ending delimiter */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002758 count--;
Jari Aaltobb706242000-03-17 21:46:59 +00002759#if 1
2760 /* handle nested ${...} specially. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002761 else if MBTEST(open != close && was_dollar && open == '{' && ch == open) /* } */
Jari Aalto28ef6c32001-04-06 19:14:31 +00002762 count++;
Jari Aaltobb706242000-03-17 21:46:59 +00002763#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +00002764 else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002765 count++;
Jari Aalto726f6381996-08-26 18:22:31 +00002766
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002767 /* Add this character. */
2768 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
2769 ret[retind++] = ch;
Jari Aalto726f6381996-08-26 18:22:31 +00002770
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002771 if (open == '\'') /* '' inside grouping construct */
Jari Aaltobb706242000-03-17 21:46:59 +00002772 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00002773 if MBTEST((flags & P_ALLOWESC) && ch == '\\')
Jari Aaltobb706242000-03-17 21:46:59 +00002774 pass_next_character++;
2775 continue;
2776 }
Jari Aalto726f6381996-08-26 18:22:31 +00002777
Jari Aalto7117c2d2002-07-17 14:10:11 +00002778 if MBTEST(ch == '\\') /* backslashes */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002779 pass_next_character++;
Jari Aalto726f6381996-08-26 18:22:31 +00002780
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002781 if (open != close) /* a grouping construct */
2782 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00002783 if MBTEST(shellquote (ch))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002784 {
2785 /* '', ``, or "" inside $(...) or other grouping construct. */
2786 push_delimiter (dstack, ch);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002787 if MBTEST(was_dollar && ch == '\'') /* $'...' inside group */
Jari Aaltob80f6442004-07-27 13:29:18 +00002788 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
Jari Aalto28ef6c32001-04-06 19:14:31 +00002789 else
Jari Aaltob80f6442004-07-27 13:29:18 +00002790 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002791 pop_delimiter (dstack);
2792 if (nestret == &matched_pair_error)
2793 {
2794 free (ret);
2795 return &matched_pair_error;
2796 }
Jari Aaltob80f6442004-07-27 13:29:18 +00002797 if MBTEST(was_dollar && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
Jari Aalto28ef6c32001-04-06 19:14:31 +00002798 {
2799 /* Translate $'...' here. */
2800 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
Jari Aaltof73dda02001-11-13 17:56:06 +00002801 xfree (nestret);
Jari Aalto28ef6c32001-04-06 19:14:31 +00002802 nestret = sh_single_quote (ttrans);
2803 free (ttrans);
2804 nestlen = strlen (nestret);
2805 retind -= 2; /* back up before the $' */
2806 }
Jari Aaltob80f6442004-07-27 13:29:18 +00002807 else if MBTEST(was_dollar && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
Jari Aalto28ef6c32001-04-06 19:14:31 +00002808 {
2809 /* Locale expand $"..." here. */
2810 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
Jari Aaltof73dda02001-11-13 17:56:06 +00002811 xfree (nestret);
2812 nestret = (char *)xmalloc (ttranslen + 3);
Jari Aalto28ef6c32001-04-06 19:14:31 +00002813 nestret[0] = '"';
2814 strcpy (nestret + 1, ttrans);
2815 nestret[ttranslen + 1] = '"';
2816 nestret[ttranslen += 2] = '\0';
2817 free (ttrans);
2818 nestlen = ttranslen;
2819 retind -= 2; /* back up before the $" */
2820 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00002821
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002822 if (nestlen)
2823 {
2824 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2825 strcpy (ret + retind, nestret);
2826 retind += nestlen;
2827 }
2828 FREE (nestret);
2829 }
2830 }
2831 /* Parse an old-style command substitution within double quotes as a
2832 single word. */
2833 /* XXX - sh and ksh93 don't do this - XXX */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002834 else if MBTEST(open == '"' && ch == '`')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002835 {
Jari Aaltob80f6442004-07-27 13:29:18 +00002836 nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002837 if (nestret == &matched_pair_error)
2838 {
2839 free (ret);
2840 return &matched_pair_error;
2841 }
2842 if (nestlen)
2843 {
2844 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2845 strcpy (ret + retind, nestret);
2846 retind += nestlen;
2847 }
2848 FREE (nestret);
2849 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00002850 else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002851 /* check for $(), $[], or ${} inside quoted string. */
2852 {
2853 if (open == ch) /* undo previous increment */
2854 count--;
2855 if (ch == '(') /* ) */
Jari Aaltob80f6442004-07-27 13:29:18 +00002856 nestret = parse_matched_pair (0, '(', ')', &nestlen, rflags);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002857 else if (ch == '{') /* } */
Jari Aaltob80f6442004-07-27 13:29:18 +00002858 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|rflags);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002859 else if (ch == '[') /* ] */
Jari Aaltob80f6442004-07-27 13:29:18 +00002860 nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002861 if (nestret == &matched_pair_error)
2862 {
2863 free (ret);
2864 return &matched_pair_error;
2865 }
2866 if (nestlen)
2867 {
2868 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2869 strcpy (ret + retind, nestret);
2870 retind += nestlen;
2871 }
2872 FREE (nestret);
2873 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00002874 was_dollar = MBTEST(ch == '$');
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002875 }
Jari Aalto726f6381996-08-26 18:22:31 +00002876
Jari Aaltoccc6cda1996-12-23 17:02:34 +00002877 ret[retind] = '\0';
2878 if (lenp)
2879 *lenp = retind;
2880 return ret;
2881}
Jari Aalto726f6381996-08-26 18:22:31 +00002882
Jari Aaltobb706242000-03-17 21:46:59 +00002883#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
Jari Aalto7117c2d2002-07-17 14:10:11 +00002884/* Parse a double-paren construct. It can be either an arithmetic
2885 command, an arithmetic `for' command, or a nested subshell. Returns
2886 the parsed token, -1 on error, or -2 if we didn't do anything and
2887 should just go on. */
2888static int
2889parse_dparen (c)
2890 int c;
2891{
2892 int cmdtyp, len, sline;
2893 char *wval, *wv2;
2894 WORD_DESC *wd;
2895
2896#if defined (ARITH_FOR_COMMAND)
2897 if (last_read_token == FOR)
2898 {
2899 arith_for_lineno = line_number;
Jari Aaltob80f6442004-07-27 13:29:18 +00002900 cmdtyp = parse_arith_cmd (&wval, 0);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002901 if (cmdtyp == 1)
2902 {
Jari Aaltob80f6442004-07-27 13:29:18 +00002903 wd = make_word (wval);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002904 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2905 free (wval);
Jari Aalto7117c2d2002-07-17 14:10:11 +00002906 return (ARITH_FOR_EXPRS);
2907 }
2908 else
2909 return -1; /* ERROR */
2910 }
2911#endif
2912
2913#if defined (DPAREN_ARITHMETIC)
2914 if (reserved_word_acceptable (last_read_token))
2915 {
2916 sline = line_number;
Jari Aaltob80f6442004-07-27 13:29:18 +00002917#if 0
2918 cmdtyp = parse_arith_cmd (&wval, 1);
2919#else
2920 cmdtyp = parse_arith_cmd (&wval, 0);
2921#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +00002922 if (cmdtyp == 1) /* arithmetic command */
2923 {
2924 wd = make_word (wval);
Jari Aaltob80f6442004-07-27 13:29:18 +00002925#if 0
Jari Aalto7117c2d2002-07-17 14:10:11 +00002926 wd->flags = W_QUOTED;
Jari Aaltob80f6442004-07-27 13:29:18 +00002927#else
2928 wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB;
2929#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +00002930 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2931 free (wval); /* make_word copies it */
2932 return (ARITH_CMD);
2933 }
2934 else if (cmdtyp == 0) /* nested subshell */
2935 {
2936 push_string (wval, 0, (alias_t *)NULL);
2937 if ((parser_state & PST_CASEPAT) == 0)
2938 parser_state |= PST_SUBSHELL;
2939 return (c);
2940 }
2941 else /* ERROR */
2942 return -1;
2943 }
2944#endif
2945
2946 return -2; /* XXX */
2947}
2948
Jari Aaltod166f041997-06-05 14:59:13 +00002949/* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
2950 If not, assume it's a nested subshell for backwards compatibility and
2951 return 0. In any case, put the characters we've consumed into a locally-
2952 allocated buffer and make *ep point to that buffer. Return -1 on an
2953 error, for example EOF. */
2954static int
Jari Aaltob80f6442004-07-27 13:29:18 +00002955parse_arith_cmd (ep, adddq)
Jari Aaltod166f041997-06-05 14:59:13 +00002956 char **ep;
Jari Aaltob80f6442004-07-27 13:29:18 +00002957 int adddq;
Jari Aaltod166f041997-06-05 14:59:13 +00002958{
2959 int exp_lineno, rval, c;
Jari Aaltof73dda02001-11-13 17:56:06 +00002960 char *ttok, *tokstr;
Jari Aaltod166f041997-06-05 14:59:13 +00002961 int ttoklen;
2962
2963 exp_lineno = line_number;
2964 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
2965 rval = 1;
2966 if (ttok == &matched_pair_error)
2967 return -1;
2968 /* Check that the next character is the closing right paren. If
2969 not, this is a syntax error. ( */
Jari Aalto7117c2d2002-07-17 14:10:11 +00002970 c = shell_getc (0);
2971 if MBTEST(c != ')')
Jari Aaltod166f041997-06-05 14:59:13 +00002972 rval = 0;
2973
Jari Aaltof73dda02001-11-13 17:56:06 +00002974 tokstr = (char *)xmalloc (ttoklen + 4);
Jari Aaltod166f041997-06-05 14:59:13 +00002975
Jari Aaltob80f6442004-07-27 13:29:18 +00002976 /* if ADDDQ != 0 then (( ... )) -> "..." */
2977 if (rval == 1 && adddq) /* arith cmd, add double quotes */
Jari Aaltod166f041997-06-05 14:59:13 +00002978 {
Jari Aaltob80f6442004-07-27 13:29:18 +00002979 tokstr[0] = '"';
2980 strncpy (tokstr + 1, ttok, ttoklen - 1);
Jari Aaltof73dda02001-11-13 17:56:06 +00002981 tokstr[ttoklen] = '"';
2982 tokstr[ttoklen+1] = '\0';
Jari Aaltod166f041997-06-05 14:59:13 +00002983 }
Jari Aaltob80f6442004-07-27 13:29:18 +00002984 else if (rval == 1) /* arith cmd, don't add double quotes */
Jari Aaltod166f041997-06-05 14:59:13 +00002985 {
Jari Aaltob80f6442004-07-27 13:29:18 +00002986 strncpy (tokstr, ttok, ttoklen - 1);
2987 tokstr[ttoklen-1] = '\0';
2988 }
2989 else /* nested subshell */
2990 {
2991 tokstr[0] = '(';
2992 strncpy (tokstr + 1, ttok, ttoklen - 1);
Jari Aaltof73dda02001-11-13 17:56:06 +00002993 tokstr[ttoklen] = ')';
2994 tokstr[ttoklen+1] = c;
2995 tokstr[ttoklen+2] = '\0';
Jari Aaltod166f041997-06-05 14:59:13 +00002996 }
Jari Aaltob80f6442004-07-27 13:29:18 +00002997
Jari Aaltof73dda02001-11-13 17:56:06 +00002998 *ep = tokstr;
Jari Aaltod166f041997-06-05 14:59:13 +00002999 FREE (ttok);
3000 return rval;
3001}
Jari Aaltobb706242000-03-17 21:46:59 +00003002#endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
Jari Aaltod166f041997-06-05 14:59:13 +00003003
Jari Aaltocce855b1998-04-17 19:52:44 +00003004#if defined (COND_COMMAND)
Jari Aalto7117c2d2002-07-17 14:10:11 +00003005static void
3006cond_error ()
3007{
3008 char *etext;
3009
3010 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
Jari Aaltob80f6442004-07-27 13:29:18 +00003011 parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
Jari Aalto7117c2d2002-07-17 14:10:11 +00003012 else if (cond_token != COND_ERROR)
3013 {
3014 if (etext = error_token_from_token (cond_token))
3015 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003016 parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003017 free (etext);
3018 }
3019 else
Jari Aaltob80f6442004-07-27 13:29:18 +00003020 parser_error (cond_lineno, _("syntax error in conditional expression"));
Jari Aalto7117c2d2002-07-17 14:10:11 +00003021 }
3022}
3023
Jari Aaltocce855b1998-04-17 19:52:44 +00003024static COND_COM *
3025cond_expr ()
3026{
3027 return (cond_or ());
3028}
3029
3030static COND_COM *
3031cond_or ()
3032{
3033 COND_COM *l, *r;
3034
3035 l = cond_and ();
3036 if (cond_token == OR_OR)
3037 {
3038 r = cond_or ();
3039 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
3040 }
3041 return l;
3042}
3043
3044static COND_COM *
3045cond_and ()
3046{
3047 COND_COM *l, *r;
3048
3049 l = cond_term ();
3050 if (cond_token == AND_AND)
3051 {
3052 r = cond_and ();
3053 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
3054 }
3055 return l;
3056}
3057
3058static int
3059cond_skip_newlines ()
3060{
3061 while ((cond_token = read_token (READ)) == '\n')
3062 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003063 if (SHOULD_PROMPT ())
Jari Aaltocce855b1998-04-17 19:52:44 +00003064 prompt_again ();
3065 }
3066 return (cond_token);
3067}
3068
3069#define COND_RETURN_ERROR() \
3070 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
3071
3072static COND_COM *
3073cond_term ()
3074{
3075 WORD_DESC *op;
3076 COND_COM *term, *tleft, *tright;
3077 int tok, lineno;
Jari Aalto7117c2d2002-07-17 14:10:11 +00003078 char *etext;
Jari Aaltocce855b1998-04-17 19:52:44 +00003079
3080 /* Read a token. It can be a left paren, a `!', a unary operator, or a
3081 word that should be the first argument of a binary operator. Start by
3082 skipping newlines, since this is a compound command. */
3083 tok = cond_skip_newlines ();
3084 lineno = line_number;
3085 if (tok == COND_END)
3086 {
3087 COND_RETURN_ERROR ();
3088 }
3089 else if (tok == '(')
3090 {
3091 term = cond_expr ();
3092 if (cond_token != ')')
3093 {
3094 if (term)
3095 dispose_cond_node (term); /* ( */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003096 if (etext = error_token_from_token (cond_token))
3097 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003098 parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003099 free (etext);
3100 }
3101 else
Jari Aaltob80f6442004-07-27 13:29:18 +00003102 parser_error (lineno, _("expected `)'"));
Jari Aaltocce855b1998-04-17 19:52:44 +00003103 COND_RETURN_ERROR ();
3104 }
3105 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
3106 (void)cond_skip_newlines ();
3107 }
3108 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
3109 {
3110 if (tok == WORD)
3111 dispose_word (yylval.word); /* not needed */
3112 term = cond_term ();
3113 if (term)
3114 term->flags |= CMD_INVERT_RETURN;
3115 }
3116 else if (tok == WORD && test_unop (yylval.word->word))
3117 {
3118 op = yylval.word;
3119 tok = read_token (READ);
3120 if (tok == WORD)
3121 {
3122 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3123 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3124 }
3125 else
3126 {
3127 dispose_word (op);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003128 if (etext = error_token_from_token (tok))
3129 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003130 parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003131 free (etext);
3132 }
3133 else
Jari Aaltob80f6442004-07-27 13:29:18 +00003134 parser_error (line_number, _("unexpected argument to conditional unary operator"));
Jari Aaltocce855b1998-04-17 19:52:44 +00003135 COND_RETURN_ERROR ();
3136 }
3137
3138 (void)cond_skip_newlines ();
3139 }
Jari Aaltobb706242000-03-17 21:46:59 +00003140 else if (tok == WORD) /* left argument to binary operator */
Jari Aaltocce855b1998-04-17 19:52:44 +00003141 {
3142 /* lhs */
3143 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3144
3145 /* binop */
3146 tok = read_token (READ);
3147 if (tok == WORD && test_binop (yylval.word->word))
Jari Aalto28ef6c32001-04-06 19:14:31 +00003148 op = yylval.word;
Jari Aaltob80f6442004-07-27 13:29:18 +00003149#if defined (COND_REGEXP)
3150 else if (tok == WORD && STREQ (yylval.word->word,"=~"))
3151 op = yylval.word;
3152#endif
Jari Aaltocce855b1998-04-17 19:52:44 +00003153 else if (tok == '<' || tok == '>')
Jari Aalto28ef6c32001-04-06 19:14:31 +00003154 op = make_word_from_token (tok); /* ( */
3155 /* There should be a check before blindly accepting the `)' that we have
3156 seen the opening `('. */
3157 else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
Jari Aaltocce855b1998-04-17 19:52:44 +00003158 {
3159 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
3160 the test command. Similarly for [[ x && expr ]] or
Jari Aalto28ef6c32001-04-06 19:14:31 +00003161 [[ x || expr ]] or [[ (x) ]]. */
Jari Aaltocce855b1998-04-17 19:52:44 +00003162 op = make_word ("-n");
3163 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3164 cond_token = tok;
3165 return (term);
3166 }
3167 else
3168 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00003169 if (etext = error_token_from_token (tok))
3170 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003171 parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003172 free (etext);
3173 }
3174 else
Jari Aaltob80f6442004-07-27 13:29:18 +00003175 parser_error (line_number, _("conditional binary operator expected"));
Jari Aaltocce855b1998-04-17 19:52:44 +00003176 dispose_cond_node (tleft);
3177 COND_RETURN_ERROR ();
3178 }
3179
3180 /* rhs */
3181 tok = read_token (READ);
3182 if (tok == WORD)
3183 {
3184 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3185 term = make_cond_node (COND_BINARY, op, tleft, tright);
3186 }
3187 else
3188 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00003189 if (etext = error_token_from_token (tok))
3190 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003191 parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003192 free (etext);
3193 }
3194 else
Jari Aaltob80f6442004-07-27 13:29:18 +00003195 parser_error (line_number, _("unexpected argument to conditional binary operator"));
Jari Aaltocce855b1998-04-17 19:52:44 +00003196 dispose_cond_node (tleft);
3197 dispose_word (op);
3198 COND_RETURN_ERROR ();
3199 }
3200
3201 (void)cond_skip_newlines ();
3202 }
Jari Aaltobb706242000-03-17 21:46:59 +00003203 else
3204 {
3205 if (tok < 256)
Jari Aaltob80f6442004-07-27 13:29:18 +00003206 parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003207 else if (etext = error_token_from_token (tok))
3208 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003209 parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003210 free (etext);
3211 }
Jari Aaltobb706242000-03-17 21:46:59 +00003212 else
Jari Aaltob80f6442004-07-27 13:29:18 +00003213 parser_error (line_number, _("unexpected token %d in conditional command"), tok);
Jari Aaltobb706242000-03-17 21:46:59 +00003214 COND_RETURN_ERROR ();
3215 }
Jari Aaltocce855b1998-04-17 19:52:44 +00003216 return (term);
3217}
3218
3219/* This is kind of bogus -- we slip a mini recursive-descent parser in
3220 here to handle the conditional statement syntax. */
3221static COMMAND *
3222parse_cond_command ()
3223{
3224 COND_COM *cexp;
3225
3226 cexp = cond_expr ();
3227 return (make_cond_command (cexp));
3228}
3229#endif
3230
Jari Aalto7117c2d2002-07-17 14:10:11 +00003231#if defined (ARRAY_VARS)
3232/* When this is called, it's guaranteed that we don't care about anything
3233 in t beyond i. We do save and restore the chars, though. */
3234static int
3235token_is_assignment (t, i)
3236 char *t;
3237 int i;
3238{
3239 unsigned char c, c1;
3240 int r;
3241
3242 c = t[i]; c1 = t[i+1];
3243 t[i] = '='; t[i+1] = '\0';
Jari Aaltob80f6442004-07-27 13:29:18 +00003244 r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003245 t[i] = c; t[i+1] = c1;
3246 return r;
3247}
3248
3249static int
3250token_is_ident (t, i)
3251 char *t;
3252 int i;
3253{
3254 unsigned char c;
3255 int r;
3256
3257 c = t[i];
3258 t[i] = '\0';
3259 r = legal_identifier (t);
3260 t[i] = c;
3261 return r;
3262}
3263#endif
3264
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003265static int
3266read_token_word (character)
3267 int character;
3268{
3269 /* The value for YYLVAL when a WORD is read. */
3270 WORD_DESC *the_word;
Jari Aalto726f6381996-08-26 18:22:31 +00003271
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003272 /* Index into the token that we are building. */
3273 int token_index;
Jari Aalto726f6381996-08-26 18:22:31 +00003274
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003275 /* ALL_DIGITS becomes zero when we see a non-digit. */
Jari Aaltof73dda02001-11-13 17:56:06 +00003276 int all_digit_token;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003277
3278 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3279 int dollar_present;
3280
3281 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3282 int quoted;
3283
3284 /* Non-zero means to ignore the value of the next character, and just
3285 to add it no matter what. */
3286 int pass_next_character;
3287
3288 /* The current delimiting character. */
3289 int cd;
3290 int result, peek_char;
3291 char *ttok, *ttrans;
3292 int ttoklen, ttranslen;
Jari Aalto7117c2d2002-07-17 14:10:11 +00003293 intmax_t lvalue;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003294
Jari Aaltod166f041997-06-05 14:59:13 +00003295 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
Jari Aaltof73dda02001-11-13 17:56:06 +00003296 token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003297
3298 token_index = 0;
Jari Aaltof73dda02001-11-13 17:56:06 +00003299 all_digit_token = DIGIT (character);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003300 dollar_present = quoted = pass_next_character = 0;
3301
3302 for (;;)
3303 {
3304 if (character == EOF)
3305 goto got_token;
3306
3307 if (pass_next_character)
3308 {
3309 pass_next_character = 0;
3310 goto got_character;
3311 }
3312
3313 cd = current_delimiter (dstack);
3314
3315 /* Handle backslashes. Quote lots of things when not inside of
3316 double-quotes, quote some things inside of double-quotes. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003317 if MBTEST(character == '\\')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003318 {
3319 peek_char = shell_getc (0);
3320
3321 /* Backslash-newline is ignored in all cases except
3322 when quoted with single quotes. */
3323 if (peek_char == '\n')
3324 {
3325 character = '\n';
3326 goto next_character;
3327 }
3328 else
3329 {
Jari Aalto726f6381996-08-26 18:22:31 +00003330 shell_ungetc (peek_char);
Jari Aalto726f6381996-08-26 18:22:31 +00003331
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003332 /* If the next character is to be quoted, note it now. */
3333 if (cd == 0 || cd == '`' ||
Jari Aaltof73dda02001-11-13 17:56:06 +00003334 (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003335 pass_next_character++;
Jari Aalto726f6381996-08-26 18:22:31 +00003336
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003337 quoted = 1;
3338 goto got_character;
3339 }
3340 }
Jari Aalto726f6381996-08-26 18:22:31 +00003341
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003342 /* Parse a matched pair of quote characters. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003343 if MBTEST(shellquote (character))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003344 {
3345 push_delimiter (dstack, character);
3346 ttok = parse_matched_pair (character, character, character, &ttoklen, 0);
3347 pop_delimiter (dstack);
3348 if (ttok == &matched_pair_error)
3349 return -1; /* Bail immediately. */
3350 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3351 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3352 token[token_index++] = character;
3353 strcpy (token + token_index, ttok);
3354 token_index += ttoklen;
Jari Aaltof73dda02001-11-13 17:56:06 +00003355 all_digit_token = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003356 quoted = 1;
3357 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3358 FREE (ttok);
3359 goto next_character;
3360 }
Jari Aalto726f6381996-08-26 18:22:31 +00003361
Jari Aaltocce855b1998-04-17 19:52:44 +00003362#ifdef EXTENDED_GLOB
3363 /* Parse a ksh-style extended pattern matching specification. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00003364 if (extended_glob && PATTERN_CHAR (character))
Jari Aaltocce855b1998-04-17 19:52:44 +00003365 {
3366 peek_char = shell_getc (1);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003367 if MBTEST(peek_char == '(') /* ) */
Jari Aaltocce855b1998-04-17 19:52:44 +00003368 {
3369 push_delimiter (dstack, peek_char);
3370 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3371 pop_delimiter (dstack);
3372 if (ttok == &matched_pair_error)
3373 return -1; /* Bail immediately. */
3374 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3375 token_buffer_size,
3376 TOKEN_DEFAULT_GROW_SIZE);
3377 token[token_index++] = character;
3378 token[token_index++] = peek_char;
3379 strcpy (token + token_index, ttok);
3380 token_index += ttoklen;
3381 FREE (ttok);
Jari Aaltof73dda02001-11-13 17:56:06 +00003382 dollar_present = all_digit_token = 0;
Jari Aaltocce855b1998-04-17 19:52:44 +00003383 goto next_character;
3384 }
3385 else
3386 shell_ungetc (peek_char);
3387 }
3388#endif /* EXTENDED_GLOB */
3389
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003390 /* If the delimiter character is not single quote, parse some of
3391 the shell expansions that must be read as a single word. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00003392 if (shellexp (character))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003393 {
3394 peek_char = shell_getc (1);
3395 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003396 if MBTEST(peek_char == '(' || \
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003397 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
3398 {
3399 if (peek_char == '{') /* } */
Jari Aalto28ef6c32001-04-06 19:14:31 +00003400 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003401 else if (peek_char == '(') /* ) */
Jari Aaltod166f041997-06-05 14:59:13 +00003402 {
3403 /* XXX - push and pop the `(' as a delimiter for use by
3404 the command-oriented-history code. This way newlines
3405 appearing in the $(...) string get added to the
3406 history literally rather than causing a possibly-
Jari Aaltobb706242000-03-17 21:46:59 +00003407 incorrect `;' to be added. ) */
Jari Aaltod166f041997-06-05 14:59:13 +00003408 push_delimiter (dstack, peek_char);
3409 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3410 pop_delimiter (dstack);
3411 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003412 else
3413 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3414 if (ttok == &matched_pair_error)
3415 return -1; /* Bail immediately. */
3416 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3417 token_buffer_size,
3418 TOKEN_DEFAULT_GROW_SIZE);
3419 token[token_index++] = character;
3420 token[token_index++] = peek_char;
3421 strcpy (token + token_index, ttok);
3422 token_index += ttoklen;
3423 FREE (ttok);
3424 dollar_present = 1;
Jari Aaltof73dda02001-11-13 17:56:06 +00003425 all_digit_token = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003426 goto next_character;
3427 }
3428 /* This handles $'...' and $"..." new-style quoted strings. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003429 else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003430 {
Jari Aaltocce855b1998-04-17 19:52:44 +00003431 int first_line;
3432
3433 first_line = line_number;
Jari Aaltobb706242000-03-17 21:46:59 +00003434 push_delimiter (dstack, peek_char);
3435 ttok = parse_matched_pair (peek_char, peek_char, peek_char,
3436 &ttoklen,
3437 (peek_char == '\'') ? P_ALLOWESC : 0);
3438 pop_delimiter (dstack);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003439 if (ttok == &matched_pair_error)
3440 return -1;
3441 if (peek_char == '\'')
Jari Aaltobb706242000-03-17 21:46:59 +00003442 {
3443 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
3444 free (ttok);
3445 /* Insert the single quotes and correctly quote any
3446 embedded single quotes (allowed because P_ALLOWESC was
3447 passed to parse_matched_pair). */
Jari Aalto28ef6c32001-04-06 19:14:31 +00003448 ttok = sh_single_quote (ttrans);
Jari Aaltobb706242000-03-17 21:46:59 +00003449 free (ttrans);
3450 ttrans = ttok;
3451 ttranslen = strlen (ttrans);
3452 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003453 else
Jari Aaltobb706242000-03-17 21:46:59 +00003454 {
3455 /* Try to locale-expand the converted string. */
3456 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
3457 free (ttok);
3458
3459 /* Add the double quotes back */
Jari Aaltof73dda02001-11-13 17:56:06 +00003460 ttok = (char *)xmalloc (ttranslen + 3);
Jari Aaltobb706242000-03-17 21:46:59 +00003461 ttok[0] = '"';
3462 strcpy (ttok + 1, ttrans);
3463 ttok[ttranslen + 1] = '"';
3464 ttok[ttranslen += 2] = '\0';
3465 free (ttrans);
3466 ttrans = ttok;
3467 }
3468
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003469 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
3470 token_buffer_size,
3471 TOKEN_DEFAULT_GROW_SIZE);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003472 strcpy (token + token_index, ttrans);
3473 token_index += ttranslen;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003474 FREE (ttrans);
3475 quoted = 1;
Jari Aaltof73dda02001-11-13 17:56:06 +00003476 all_digit_token = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003477 goto next_character;
3478 }
Jari Aaltob72432f1999-02-19 17:11:39 +00003479 /* This could eventually be extended to recognize all of the
3480 shell's single-character parameter expansions, and set flags.*/
Jari Aalto7117c2d2002-07-17 14:10:11 +00003481 else if MBTEST(character == '$' && peek_char == '$')
Jari Aaltob72432f1999-02-19 17:11:39 +00003482 {
Jari Aaltof73dda02001-11-13 17:56:06 +00003483 ttok = (char *)xmalloc (3);
Jari Aaltob72432f1999-02-19 17:11:39 +00003484 ttok[0] = ttok[1] = '$';
3485 ttok[2] = '\0';
3486 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
3487 token_buffer_size,
3488 TOKEN_DEFAULT_GROW_SIZE);
3489 strcpy (token + token_index, ttok);
3490 token_index += 2;
3491 dollar_present = 1;
Jari Aaltof73dda02001-11-13 17:56:06 +00003492 all_digit_token = 0;
Jari Aaltob72432f1999-02-19 17:11:39 +00003493 FREE (ttok);
3494 goto next_character;
3495 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003496 else
3497 shell_ungetc (peek_char);
3498 }
3499
3500#if defined (ARRAY_VARS)
Jari Aalto7117c2d2002-07-17 14:10:11 +00003501 /* Identify possible array subscript assignment; match [...] */
3502 else if MBTEST(character == '[' && token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) /* ] */
3503 {
3504 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3505 if (ttok == &matched_pair_error)
3506 return -1; /* Bail immediately. */
3507 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3508 token_buffer_size,
3509 TOKEN_DEFAULT_GROW_SIZE);
3510 token[token_index++] = character;
3511 strcpy (token + token_index, ttok);
3512 token_index += ttoklen;
3513 FREE (ttok);
3514 all_digit_token = 0;
3515 goto next_character;
3516 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003517 /* Identify possible compound array variable assignment. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003518 else if MBTEST(character == '=' && token_index > 0 && token_is_assignment (token, token_index))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003519 {
3520 peek_char = shell_getc (1);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003521 if MBTEST(peek_char == '(') /* ) */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003522 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00003523 ttok = parse_compound_assignment (&ttoklen);
3524
3525 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003526 token_buffer_size,
3527 TOKEN_DEFAULT_GROW_SIZE);
Jari Aalto7117c2d2002-07-17 14:10:11 +00003528
3529 token[token_index++] = '=';
3530 token[token_index++] = '(';
3531 if (ttok)
3532 {
3533 strcpy (token + token_index, ttok);
3534 token_index += ttoklen;
3535 }
3536 token[token_index++] = ')';
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003537 FREE (ttok);
Jari Aaltof73dda02001-11-13 17:56:06 +00003538 all_digit_token = 0;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003539 goto next_character;
3540 }
3541 else
3542 shell_ungetc (peek_char);
3543 }
Jari Aalto726f6381996-08-26 18:22:31 +00003544#endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003545
3546 /* When not parsing a multi-character word construct, shell meta-
3547 characters break words. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003548 if MBTEST(shellbreak (character))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003549 {
3550 shell_ungetc (character);
3551 goto got_token;
3552 }
3553
3554 got_character:
3555
Jari Aaltof73dda02001-11-13 17:56:06 +00003556 all_digit_token &= DIGIT (character);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003557 dollar_present |= character == '$';
3558
3559 if (character == CTLESC || character == CTLNUL)
3560 token[token_index++] = CTLESC;
3561
3562 token[token_index++] = character;
3563
3564 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
3565 TOKEN_DEFAULT_GROW_SIZE);
3566
3567 next_character:
Jari Aaltob80f6442004-07-27 13:29:18 +00003568 if (character == '\n' && SHOULD_PROMPT ())
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003569 prompt_again ();
3570
3571 /* We want to remove quoted newlines (that is, a \<newline> pair)
3572 unless we are within single quotes or pass_next_character is
3573 set (the shell equivalent of literal-next). */
3574 cd = current_delimiter (dstack);
3575 character = shell_getc (cd != '\'' && pass_next_character == 0);
3576 } /* end for (;;) */
3577
3578got_token:
3579
3580 token[token_index] = '\0';
3581
3582 /* Check to see what thing we should return. If the last_read_token
3583 is a `<', or a `&', or the character which ended this token is
3584 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
3585 Otherwise, it is just a word, and should be returned as such. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003586 if MBTEST(all_digit_token && (character == '<' || character == '>' || \
3587 last_read_token == LESS_AND || \
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003588 last_read_token == GREATER_AND))
Jari Aalto726f6381996-08-26 18:22:31 +00003589 {
Jari Aaltof73dda02001-11-13 17:56:06 +00003590 if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
3591 yylval.number = lvalue;
3592 else
3593 yylval.number = -1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003594 return (NUMBER);
Jari Aalto726f6381996-08-26 18:22:31 +00003595 }
3596
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003597 /* Check for special case tokens. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003598 result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003599 if (result >= 0)
3600 return result;
Jari Aalto726f6381996-08-26 18:22:31 +00003601
3602#if defined (ALIAS)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003603 /* Posix.2 does not allow reserved words to be aliased, so check for all
3604 of them, including special cases, before expanding the current token
3605 as an alias. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003606 if MBTEST(posixly_correct)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003607 CHECK_FOR_RESERVED_WORD (token);
Jari Aalto726f6381996-08-26 18:22:31 +00003608
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003609 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
3610 inhibits alias expansion. */
3611 if (expand_aliases && quoted == 0)
3612 {
3613 result = alias_expand_token (token);
3614 if (result == RE_READ_TOKEN)
3615 return (RE_READ_TOKEN);
3616 else if (result == NO_EXPANSION)
3617 parser_state &= ~PST_ALEXPNEXT;
3618 }
Jari Aalto726f6381996-08-26 18:22:31 +00003619
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003620 /* If not in Posix.2 mode, check for reserved words after alias
3621 expansion. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003622 if MBTEST(posixly_correct == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003623#endif
3624 CHECK_FOR_RESERVED_WORD (token);
Jari Aalto726f6381996-08-26 18:22:31 +00003625
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003626 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
Jari Aaltof73dda02001-11-13 17:56:06 +00003627 the_word->word = (char *)xmalloc (1 + token_index);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003628 the_word->flags = 0;
3629 strcpy (the_word->word, token);
3630 if (dollar_present)
3631 the_word->flags |= W_HASDOLLAR;
3632 if (quoted)
3633 the_word->flags |= W_QUOTED;
3634 /* A word is an assignment if it appears at the beginning of a
3635 simple command, or after another assignment word. This is
3636 context-dependent, so it cannot be handled in the grammar. */
Jari Aaltob80f6442004-07-27 13:29:18 +00003637 if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003638 {
3639 the_word->flags |= W_ASSIGNMENT;
3640 /* Don't perform word splitting on assignment statements. */
Jari Aaltob80f6442004-07-27 13:29:18 +00003641 if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003642 the_word->flags |= W_NOSPLIT;
3643 }
Jari Aalto726f6381996-08-26 18:22:31 +00003644
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003645 yylval.word = the_word;
Jari Aalto726f6381996-08-26 18:22:31 +00003646
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003647 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
3648 ? ASSIGNMENT_WORD : WORD;
Jari Aalto726f6381996-08-26 18:22:31 +00003649
Jari Aaltob80f6442004-07-27 13:29:18 +00003650 switch (last_read_token)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003651 {
Jari Aaltob80f6442004-07-27 13:29:18 +00003652 case FUNCTION:
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003653 parser_state |= PST_ALLOWOPNBRC;
3654 function_dstart = line_number;
Jari Aaltob80f6442004-07-27 13:29:18 +00003655 break;
3656 case CASE:
3657 case SELECT:
3658 case FOR:
3659 if (word_top < MAX_CASE_NEST)
3660 word_top++;
3661 word_lineno[word_top] = line_number;
3662 break;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003663 }
Jari Aalto726f6381996-08-26 18:22:31 +00003664
Jari Aalto726f6381996-08-26 18:22:31 +00003665 return (result);
3666}
3667
Jari Aaltof73dda02001-11-13 17:56:06 +00003668/* Return 1 if TOKSYM is a token that after being read would allow
Jari Aalto726f6381996-08-26 18:22:31 +00003669 a reserved word to be seen, else 0. */
3670static int
Jari Aaltof73dda02001-11-13 17:56:06 +00003671reserved_word_acceptable (toksym)
3672 int toksym;
Jari Aalto726f6381996-08-26 18:22:31 +00003673{
Jari Aalto7117c2d2002-07-17 14:10:11 +00003674 switch (toksym)
3675 {
3676 case '\n':
3677 case ';':
3678 case '(':
3679 case ')':
3680 case '|':
3681 case '&':
3682 case '{':
3683 case '}': /* XXX */
3684 case AND_AND:
3685 case BANG:
3686 case DO:
3687 case DONE:
3688 case ELIF:
3689 case ELSE:
3690 case ESAC:
3691 case FI:
3692 case IF:
3693 case OR_OR:
3694 case SEMI_SEMI:
3695 case THEN:
3696 case TIME:
3697 case TIMEOPT:
3698 case UNTIL:
3699 case WHILE:
3700 case 0:
3701 return 1;
3702 default:
3703 return 0;
3704 }
Jari Aalto726f6381996-08-26 18:22:31 +00003705}
Jari Aalto7117c2d2002-07-17 14:10:11 +00003706
Jari Aalto726f6381996-08-26 18:22:31 +00003707/* Return the index of TOKEN in the alist of reserved words, or -1 if
3708 TOKEN is not a shell reserved word. */
3709int
Jari Aaltof73dda02001-11-13 17:56:06 +00003710find_reserved_word (tokstr)
3711 char *tokstr;
Jari Aalto726f6381996-08-26 18:22:31 +00003712{
3713 int i;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003714 for (i = 0; word_token_alist[i].word; i++)
Jari Aaltof73dda02001-11-13 17:56:06 +00003715 if (STREQ (tokstr, word_token_alist[i].word))
Jari Aalto726f6381996-08-26 18:22:31 +00003716 return i;
3717 return -1;
3718}
3719
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003720#if 0
Jari Aalto726f6381996-08-26 18:22:31 +00003721#if defined (READLINE)
3722/* Called after each time readline is called. This insures that whatever
3723 the new prompt string is gets propagated to readline's local prompt
3724 variable. */
3725static void
3726reset_readline_prompt ()
3727{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003728 char *temp_prompt;
3729
Jari Aalto726f6381996-08-26 18:22:31 +00003730 if (prompt_string_pointer)
3731 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003732 temp_prompt = (*prompt_string_pointer)
Jari Aalto726f6381996-08-26 18:22:31 +00003733 ? decode_prompt_string (*prompt_string_pointer)
3734 : (char *)NULL;
3735
3736 if (temp_prompt == 0)
3737 {
Jari Aaltof73dda02001-11-13 17:56:06 +00003738 temp_prompt = (char *)xmalloc (1);
Jari Aalto726f6381996-08-26 18:22:31 +00003739 temp_prompt[0] = '\0';
3740 }
3741
3742 FREE (current_readline_prompt);
Jari Aalto726f6381996-08-26 18:22:31 +00003743 current_readline_prompt = temp_prompt;
3744 }
3745}
3746#endif /* READLINE */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003747#endif /* 0 */
Jari Aalto726f6381996-08-26 18:22:31 +00003748
3749#if defined (HISTORY)
3750/* A list of tokens which can be followed by newlines, but not by
3751 semi-colons. When concatenating multiple lines of history, the
3752 newline separator for such tokens is replaced with a space. */
3753static int no_semi_successors[] = {
3754 '\n', '{', '(', ')', ';', '&', '|',
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003755 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
Jari Aalto726f6381996-08-26 18:22:31 +00003756 0
3757};
3758
3759/* If we are not within a delimited expression, try to be smart
3760 about which separators can be semi-colons and which must be
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003761 newlines. Returns the string that should be added into the
3762 history entry. */
Jari Aalto726f6381996-08-26 18:22:31 +00003763char *
3764history_delimiting_chars ()
3765{
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003766 register int i;
Jari Aalto726f6381996-08-26 18:22:31 +00003767
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003768 if (dstack.delimiter_depth != 0)
Jari Aalto726f6381996-08-26 18:22:31 +00003769 return ("\n");
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003770
3771 /* First, handle some special cases. */
3772 /*(*/
3773 /* If we just read `()', assume it's a function definition, and don't
3774 add a semicolon. If the token before the `)' was not `(', and we're
3775 not in the midst of parsing a case statement, assume it's a
3776 parenthesized command and add the semicolon. */
3777 /*)(*/
3778 if (token_before_that == ')')
3779 {
3780 if (two_tokens_ago == '(') /*)*/ /* function def */
3781 return " ";
3782 /* This does not work for subshells inside case statement
3783 command lists. It's a suboptimal solution. */
3784 else if (parser_state & PST_CASESTMT) /* case statement pattern */
Jari Aalto28ef6c32001-04-06 19:14:31 +00003785 return " ";
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003786 else
Jari Aalto28ef6c32001-04-06 19:14:31 +00003787 return "; "; /* (...) subshell */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003788 }
Jari Aaltocce855b1998-04-17 19:52:44 +00003789 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
3790 return " "; /* function def using `function name' without `()' */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003791
Jari Aaltobb706242000-03-17 21:46:59 +00003792 else if (token_before_that == WORD && two_tokens_ago == FOR)
3793 {
3794 /* Tricky. `for i\nin ...' should not have a semicolon, but
3795 `for i\ndo ...' should. We do what we can. */
3796 for (i = shell_input_line_index; whitespace(shell_input_line[i]); i++)
Jari Aalto28ef6c32001-04-06 19:14:31 +00003797 ;
Jari Aaltobb706242000-03-17 21:46:59 +00003798 if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
3799 return " ";
3800 return ";";
3801 }
3802
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003803 for (i = 0; no_semi_successors[i]; i++)
3804 {
3805 if (token_before_that == no_semi_successors[i])
3806 return (" ");
3807 }
3808
3809 return ("; ");
Jari Aalto726f6381996-08-26 18:22:31 +00003810}
3811#endif /* HISTORY */
3812
3813/* Issue a prompt, or prepare to issue a prompt when the next character
3814 is read. */
3815static void
3816prompt_again ()
3817{
3818 char *temp_prompt;
3819
Jari Aaltob80f6442004-07-27 13:29:18 +00003820 if (interactive == 0 || expanding_alias()) /* XXX */
Jari Aalto726f6381996-08-26 18:22:31 +00003821 return;
3822
3823 ps1_prompt = get_string_value ("PS1");
3824 ps2_prompt = get_string_value ("PS2");
3825
3826 if (!prompt_string_pointer)
3827 prompt_string_pointer = &ps1_prompt;
3828
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003829 temp_prompt = *prompt_string_pointer
Jari Aalto726f6381996-08-26 18:22:31 +00003830 ? decode_prompt_string (*prompt_string_pointer)
3831 : (char *)NULL;
3832
3833 if (temp_prompt == 0)
3834 {
Jari Aaltof73dda02001-11-13 17:56:06 +00003835 temp_prompt = (char *)xmalloc (1);
Jari Aalto726f6381996-08-26 18:22:31 +00003836 temp_prompt[0] = '\0';
3837 }
3838
3839 current_prompt_string = *prompt_string_pointer;
3840 prompt_string_pointer = &ps2_prompt;
3841
3842#if defined (READLINE)
3843 if (!no_line_editing)
3844 {
3845 FREE (current_readline_prompt);
3846 current_readline_prompt = temp_prompt;
3847 }
3848 else
3849#endif /* READLINE */
3850 {
3851 FREE (current_decoded_prompt);
3852 current_decoded_prompt = temp_prompt;
3853 }
3854}
3855
Jari Aaltobb706242000-03-17 21:46:59 +00003856int
3857get_current_prompt_level ()
3858{
3859 return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
3860}
3861
3862void
3863set_current_prompt_level (x)
3864 int x;
3865{
3866 prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
3867 current_prompt_string = *prompt_string_pointer;
3868}
3869
Jari Aalto726f6381996-08-26 18:22:31 +00003870static void
3871print_prompt ()
3872{
3873 fprintf (stderr, "%s", current_decoded_prompt);
3874 fflush (stderr);
3875}
3876
3877/* Return a string which will be printed as a prompt. The string
3878 may contain special characters which are decoded as follows:
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003879
3880 \a bell (ascii 07)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003881 \d the date in Day Mon Date format
Jari Aalto7117c2d2002-07-17 14:10:11 +00003882 \e escape (ascii 033)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003883 \h the hostname up to the first `.'
3884 \H the hostname
Jari Aaltobb706242000-03-17 21:46:59 +00003885 \j the number of active jobs
3886 \l the basename of the shell's tty device name
Jari Aalto726f6381996-08-26 18:22:31 +00003887 \n CRLF
Jari Aalto7117c2d2002-07-17 14:10:11 +00003888 \r CR
Jari Aalto726f6381996-08-26 18:22:31 +00003889 \s the name of the shell
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003890 \t the time in 24-hour hh:mm:ss format
3891 \T the time in 12-hour hh:mm:ss format
Jari Aalto7117c2d2002-07-17 14:10:11 +00003892 \@ the time in 12-hour hh:mm am/pm format
3893 \A the time in 24-hour hh:mm format
3894 \D{fmt} the result of passing FMT to strftime(3)
3895 \u your username
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003896 \v the version of bash (e.g., 2.00)
3897 \V the release of bash, version + patchlevel (e.g., 2.00.0)
Jari Aalto726f6381996-08-26 18:22:31 +00003898 \w the current working directory
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003899 \W the last element of $PWD
Jari Aalto726f6381996-08-26 18:22:31 +00003900 \! the history number of this command
Jari Aalto7117c2d2002-07-17 14:10:11 +00003901 \# the command number of this command
Jari Aalto726f6381996-08-26 18:22:31 +00003902 \$ a $ or a # if you are root
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003903 \nnn character code nnn in octal
Jari Aalto726f6381996-08-26 18:22:31 +00003904 \\ a backslash
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003905 \[ begin a sequence of non-printing chars
3906 \] end a sequence of non-printing chars
Jari Aalto726f6381996-08-26 18:22:31 +00003907*/
Jari Aaltod166f041997-06-05 14:59:13 +00003908#define PROMPT_GROWTH 48
Jari Aalto726f6381996-08-26 18:22:31 +00003909char *
3910decode_prompt_string (string)
3911 char *string;
3912{
Jari Aalto726f6381996-08-26 18:22:31 +00003913 WORD_LIST *list;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003914 char *result, *t;
3915 struct dstack save_dstack;
Jari Aaltof73dda02001-11-13 17:56:06 +00003916 int last_exit_value;
Jari Aalto726f6381996-08-26 18:22:31 +00003917#if defined (PROMPT_STRING_DECODE)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003918 int result_size, result_index;
3919 int c, n;
3920 char *temp, octal_string[4];
Jari Aalto7117c2d2002-07-17 14:10:11 +00003921 struct tm *tm;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003922 time_t the_time;
Jari Aalto7117c2d2002-07-17 14:10:11 +00003923 char timebuf[128];
3924 char *timefmt;
Jari Aalto726f6381996-08-26 18:22:31 +00003925
Jari Aaltof73dda02001-11-13 17:56:06 +00003926 result = (char *)xmalloc (result_size = PROMPT_GROWTH);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003927 result[result_index = 0] = 0;
3928 temp = (char *)NULL;
Jari Aalto726f6381996-08-26 18:22:31 +00003929
3930 while (c = *string++)
3931 {
3932 if (posixly_correct && c == '!')
3933 {
3934 if (*string == '!')
3935 {
3936 temp = savestring ("!");
3937 goto add_string;
3938 }
3939 else
3940 {
3941#if !defined (HISTORY)
3942 temp = savestring ("1");
3943#else /* HISTORY */
3944 temp = itos (history_number ());
3945#endif /* HISTORY */
3946 string--; /* add_string increments string again. */
3947 goto add_string;
3948 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003949 }
Jari Aalto726f6381996-08-26 18:22:31 +00003950 if (c == '\\')
3951 {
3952 c = *string;
3953
3954 switch (c)
3955 {
3956 case '0':
3957 case '1':
3958 case '2':
3959 case '3':
3960 case '4':
3961 case '5':
3962 case '6':
3963 case '7':
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003964 strncpy (octal_string, string, 3);
3965 octal_string[3] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00003966
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003967 n = read_octal (octal_string);
Jari Aaltof73dda02001-11-13 17:56:06 +00003968 temp = (char *)xmalloc (3);
Jari Aalto726f6381996-08-26 18:22:31 +00003969
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003970 if (n == CTLESC || n == CTLNUL)
3971 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003972 temp[0] = CTLESC;
3973 temp[1] = n;
3974 temp[2] = '\0';
3975 }
3976 else if (n == -1)
3977 {
3978 temp[0] = '\\';
3979 temp[1] = '\0';
3980 }
3981 else
3982 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003983 temp[0] = n;
3984 temp[1] = '\0';
3985 }
Jari Aalto726f6381996-08-26 18:22:31 +00003986
Jari Aalto28ef6c32001-04-06 19:14:31 +00003987 for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
3988 string++;
3989
Jari Aalto7117c2d2002-07-17 14:10:11 +00003990 c = 0; /* tested at add_string: */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003991 goto add_string;
Jari Aalto726f6381996-08-26 18:22:31 +00003992
Jari Aalto726f6381996-08-26 18:22:31 +00003993 case 'd':
Jari Aalto7117c2d2002-07-17 14:10:11 +00003994 case 't':
Jari Aaltoccc6cda1996-12-23 17:02:34 +00003995 case 'T':
3996 case '@':
Jari Aaltof73dda02001-11-13 17:56:06 +00003997 case 'A':
Jari Aalto726f6381996-08-26 18:22:31 +00003998 /* Make the current time/date into a string. */
Jari Aalto7117c2d2002-07-17 14:10:11 +00003999 (void) time (&the_time);
4000 tm = localtime (&the_time);
Jari Aalto726f6381996-08-26 18:22:31 +00004001
Jari Aalto7117c2d2002-07-17 14:10:11 +00004002 if (c == 'd')
4003 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
4004 else if (c == 't')
4005 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
4006 else if (c == 'T')
4007 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
4008 else if (c == '@')
4009 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
4010 else if (c == 'A')
4011 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
Jari Aalto726f6381996-08-26 18:22:31 +00004012
Jari Aaltob80f6442004-07-27 13:29:18 +00004013 if (n == 0)
4014 timebuf[0] = '\0';
4015 else
4016 timebuf[sizeof(timebuf) - 1] = '\0';
4017
Jari Aalto7117c2d2002-07-17 14:10:11 +00004018 temp = savestring (timebuf);
4019 goto add_string;
4020
4021 case 'D': /* strftime format */
4022 if (string[1] != '{') /* } */
4023 goto not_escape;
4024
4025 (void) time (&the_time);
4026 tm = localtime (&the_time);
4027 string += 2; /* skip { */
4028 timefmt = xmalloc (strlen (string) + 3);
4029 for (t = timefmt; *string && *string != '}'; )
4030 *t++ = *string++;
4031 *t = '\0';
4032 c = *string; /* tested at add_string */
4033 if (timefmt[0] == '\0')
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004034 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00004035 timefmt[0] = '%';
4036 timefmt[1] = 'X'; /* locale-specific current time */
4037 timefmt[2] = '\0';
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004038 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00004039 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
4040 free (timefmt);
Jari Aalto726f6381996-08-26 18:22:31 +00004041
Jari Aaltob80f6442004-07-27 13:29:18 +00004042 if (n == 0)
4043 timebuf[0] = '\0';
4044 else
4045 timebuf[sizeof(timebuf) - 1] = '\0';
4046
Jari Aalto7117c2d2002-07-17 14:10:11 +00004047 if (promptvars || posixly_correct)
4048 /* Make sure that expand_prompt_string is called with a
4049 second argument of Q_DOUBLE_QUOTES if we use this
4050 function here. */
4051 temp = sh_backslash_quote_for_double_quotes (timebuf);
4052 else
4053 temp = savestring (timebuf);
Jari Aaltocce855b1998-04-17 19:52:44 +00004054 goto add_string;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004055
Jari Aalto726f6381996-08-26 18:22:31 +00004056 case 'n':
Jari Aaltof73dda02001-11-13 17:56:06 +00004057 temp = (char *)xmalloc (3);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004058 temp[0] = no_line_editing ? '\n' : '\r';
4059 temp[1] = no_line_editing ? '\0' : '\n';
4060 temp[2] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00004061 goto add_string;
4062
4063 case 's':
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004064 temp = base_pathname (shell_name);
4065 temp = savestring (temp);
4066 goto add_string;
4067
4068 case 'v':
4069 case 'V':
Jari Aalto7117c2d2002-07-17 14:10:11 +00004070 temp = (char *)xmalloc (16);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004071 if (c == 'v')
4072 strcpy (temp, dist_version);
4073 else
4074 sprintf (temp, "%s.%d", dist_version, patch_level);
4075 goto add_string;
4076
Jari Aalto726f6381996-08-26 18:22:31 +00004077 case 'w':
4078 case 'W':
4079 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004080 /* Use the value of PWD because it is much more efficient. */
Jari Aaltob80f6442004-07-27 13:29:18 +00004081 char t_string[PATH_MAX], *t;
Jari Aaltoe8ce7751997-09-22 20:22:27 +00004082 int tlen;
Jari Aalto726f6381996-08-26 18:22:31 +00004083
4084 temp = get_string_value ("PWD");
4085
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004086 if (temp == 0)
4087 {
4088 if (getcwd (t_string, sizeof(t_string)) == 0)
4089 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00004090 t_string[0] = '.';
Jari Aaltoe8ce7751997-09-22 20:22:27 +00004091 tlen = 1;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004092 }
Jari Aaltoe8ce7751997-09-22 20:22:27 +00004093 else
4094 tlen = strlen (t_string);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004095 }
Jari Aalto726f6381996-08-26 18:22:31 +00004096 else
Jari Aaltoe8ce7751997-09-22 20:22:27 +00004097 {
4098 tlen = sizeof (t_string) - 1;
4099 strncpy (t_string, temp, tlen);
4100 }
4101 t_string[tlen] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00004102
Jari Aalto28ef6c32001-04-06 19:14:31 +00004103#define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
4104#define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
Jari Aaltob80f6442004-07-27 13:29:18 +00004105 /* Abbreviate \W as ~ if $PWD == $HOME */
4106 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, temp) == 0))
Jari Aalto726f6381996-08-26 18:22:31 +00004107 {
Jari Aalto28ef6c32001-04-06 19:14:31 +00004108 if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
4109 {
4110 t = strrchr (t_string, '/');
4111 if (t)
4112 strcpy (t_string, t + 1);
4113 }
Jari Aalto726f6381996-08-26 18:22:31 +00004114 }
Jari Aalto28ef6c32001-04-06 19:14:31 +00004115#undef ROOT_PATH
4116#undef DOUBLE_SLASH_ROOT
Jari Aalto726f6381996-08-26 18:22:31 +00004117 else
Jari Aaltoe8ce7751997-09-22 20:22:27 +00004118 /* polite_directory_format is guaranteed to return a string
4119 no longer than PATH_MAX - 1 characters. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004120 strcpy (t_string, polite_directory_format (t_string));
4121
4122 /* If we're going to be expanding the prompt string later,
4123 quote the directory name. */
4124 if (promptvars || posixly_correct)
Jari Aaltobb706242000-03-17 21:46:59 +00004125 /* Make sure that expand_prompt_string is called with a
Jari Aalto7117c2d2002-07-17 14:10:11 +00004126 second argument of Q_DOUBLE_QUOTES if we use this
Jari Aaltobb706242000-03-17 21:46:59 +00004127 function here. */
Jari Aalto28ef6c32001-04-06 19:14:31 +00004128 temp = sh_backslash_quote_for_double_quotes (t_string);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004129 else
4130 temp = savestring (t_string);
4131
Jari Aalto726f6381996-08-26 18:22:31 +00004132 goto add_string;
4133 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004134
Jari Aalto726f6381996-08-26 18:22:31 +00004135 case 'u':
Jari Aaltobb706242000-03-17 21:46:59 +00004136 if (current_user.user_name == 0)
4137 get_current_user_info ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004138 temp = savestring (current_user.user_name);
4139 goto add_string;
Jari Aalto726f6381996-08-26 18:22:31 +00004140
4141 case 'h':
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004142 case 'H':
4143 temp = savestring (current_host_name);
4144 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4145 *t = '\0';
4146 goto add_string;
Jari Aalto726f6381996-08-26 18:22:31 +00004147
4148 case '#':
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004149 temp = itos (current_command_number);
4150 goto add_string;
Jari Aalto726f6381996-08-26 18:22:31 +00004151
4152 case '!':
Jari Aalto726f6381996-08-26 18:22:31 +00004153#if !defined (HISTORY)
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004154 temp = savestring ("1");
Jari Aalto726f6381996-08-26 18:22:31 +00004155#else /* HISTORY */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004156 temp = itos (history_number ());
Jari Aalto726f6381996-08-26 18:22:31 +00004157#endif /* HISTORY */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004158 goto add_string;
Jari Aalto726f6381996-08-26 18:22:31 +00004159
4160 case '$':
Jari Aaltof73dda02001-11-13 17:56:06 +00004161 t = temp = (char *)xmalloc (3);
Jari Aaltob72432f1999-02-19 17:11:39 +00004162 if ((promptvars || posixly_correct) && (current_user.euid != 0))
4163 *t++ = '\\';
4164 *t++ = current_user.euid == 0 ? '#' : '$';
4165 *t = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00004166 goto add_string;
4167
Jari Aaltobb706242000-03-17 21:46:59 +00004168 case 'j':
4169 temp = itos (count_all_jobs ());
4170 goto add_string;
4171
4172 case 'l':
4173#if defined (HAVE_TTYNAME)
4174 temp = (char *)ttyname (fileno (stdin));
4175 t = temp ? base_pathname (temp) : "tty";
4176 temp = savestring (t);
4177#else
4178 temp = savestring ("tty");
4179#endif /* !HAVE_TTYNAME */
4180 goto add_string;
4181
Jari Aalto726f6381996-08-26 18:22:31 +00004182#if defined (READLINE)
4183 case '[':
4184 case ']':
Jari Aaltob80f6442004-07-27 13:29:18 +00004185 if (no_line_editing)
4186 {
4187 string++;
4188 break;
4189 }
Jari Aaltof73dda02001-11-13 17:56:06 +00004190 temp = (char *)xmalloc (3);
Jari Aalto726f6381996-08-26 18:22:31 +00004191 temp[0] = '\001';
4192 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4193 temp[2] = '\0';
4194 goto add_string;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004195#endif /* READLINE */
Jari Aalto726f6381996-08-26 18:22:31 +00004196
4197 case '\\':
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004198 case 'a':
4199 case 'e':
Jari Aalto7117c2d2002-07-17 14:10:11 +00004200 case 'r':
Jari Aaltof73dda02001-11-13 17:56:06 +00004201 temp = (char *)xmalloc (2);
Jari Aalto7117c2d2002-07-17 14:10:11 +00004202 if (c == 'a')
4203 temp[0] = '\07';
4204 else if (c == 'e')
4205 temp[0] = '\033';
4206 else if (c == 'r')
4207 temp[0] = '\r';
4208 else /* (c == '\\') */
4209 temp[0] = c;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004210 temp[1] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00004211 goto add_string;
4212
4213 default:
Jari Aalto7117c2d2002-07-17 14:10:11 +00004214not_escape:
Jari Aaltof73dda02001-11-13 17:56:06 +00004215 temp = (char *)xmalloc (3);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004216 temp[0] = '\\';
Jari Aalto726f6381996-08-26 18:22:31 +00004217 temp[1] = c;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004218 temp[2] = '\0';
Jari Aalto726f6381996-08-26 18:22:31 +00004219
4220 add_string:
4221 if (c)
4222 string++;
4223 result =
4224 sub_append_string (temp, result, &result_index, &result_size);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004225 temp = (char *)NULL; /* Freed in sub_append_string (). */
Jari Aalto726f6381996-08-26 18:22:31 +00004226 result[result_index] = '\0';
4227 break;
4228 }
4229 }
4230 else
4231 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004232 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
Jari Aalto726f6381996-08-26 18:22:31 +00004233 result[result_index++] = c;
4234 result[result_index] = '\0';
4235 }
4236 }
4237#else /* !PROMPT_STRING_DECODE */
4238 result = savestring (string);
4239#endif /* !PROMPT_STRING_DECODE */
4240
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004241 /* Save the delimiter stack and point `dstack' to temp space so any
4242 command substitutions in the prompt string won't result in screwing
4243 up the parser's quoting state. */
4244 save_dstack = dstack;
4245 dstack = temp_dstack;
4246 dstack.delimiter_depth = 0;
4247
Jari Aalto726f6381996-08-26 18:22:31 +00004248 /* Perform variable and parameter expansion and command substitution on
4249 the prompt string. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004250 if (promptvars || posixly_correct)
4251 {
Jari Aaltof73dda02001-11-13 17:56:06 +00004252 last_exit_value = last_command_exit_value;
Jari Aaltobb706242000-03-17 21:46:59 +00004253 list = expand_prompt_string (result, Q_DOUBLE_QUOTES);
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004254 free (result);
4255 result = string_list (list);
4256 dispose_words (list);
Jari Aaltof73dda02001-11-13 17:56:06 +00004257 last_command_exit_value = last_exit_value;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004258 }
4259 else
4260 {
4261 t = dequote_string (result);
4262 free (result);
4263 result = t;
4264 }
4265
4266 dstack = save_dstack;
Jari Aalto726f6381996-08-26 18:22:31 +00004267
4268 return (result);
4269}
4270
Jari Aalto7117c2d2002-07-17 14:10:11 +00004271/************************************************
4272 * *
4273 * ERROR HANDLING *
4274 * *
4275 ************************************************/
4276
Jari Aalto726f6381996-08-26 18:22:31 +00004277/* Report a syntax error, and restart the parser. Call here for fatal
4278 errors. */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004279int
Jari Aaltof73dda02001-11-13 17:56:06 +00004280yyerror (msg)
4281 const char *msg;
Jari Aalto726f6381996-08-26 18:22:31 +00004282{
4283 report_syntax_error ((char *)NULL);
4284 reset_parser ();
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004285 return (0);
Jari Aalto726f6381996-08-26 18:22:31 +00004286}
4287
Jari Aalto7117c2d2002-07-17 14:10:11 +00004288static char *
4289error_token_from_token (token)
4290 int token;
4291{
4292 char *t;
4293
4294 if (t = find_token_in_alist (token, word_token_alist, 0))
4295 return t;
4296
4297 if (t = find_token_in_alist (token, other_token_alist, 0))
4298 return t;
4299
4300 t = (char *)NULL;
4301 /* This stuff is dicy and needs closer inspection */
4302 switch (current_token)
4303 {
4304 case WORD:
4305 case ASSIGNMENT_WORD:
4306 if (yylval.word)
4307 t = savestring (yylval.word->word);
4308 break;
4309 case NUMBER:
4310 t = itos (yylval.number);
4311 break;
4312 case ARITH_CMD:
4313 if (yylval.word_list)
4314 t = string_list (yylval.word_list);
4315 break;
4316 case ARITH_FOR_EXPRS:
4317 if (yylval.word_list)
4318 t = string_list_internal (yylval.word_list, " ; ");
4319 break;
4320 case COND_CMD:
4321 t = (char *)NULL; /* punt */
4322 break;
4323 }
4324
4325 return t;
4326}
4327
4328static char *
4329error_token_from_text ()
4330{
4331 char *msg, *t;
4332 int token_end, i;
4333
4334 t = shell_input_line;
4335 i = shell_input_line_index;
4336 token_end = 0;
4337 msg = (char *)NULL;
4338
4339 if (i && t[i] == '\0')
4340 i--;
4341
4342 while (i && (whitespace (t[i]) || t[i] == '\n'))
4343 i--;
4344
4345 if (i)
4346 token_end = i + 1;
4347
4348 while (i && (member (t[i], " \n\t;|&") == 0))
4349 i--;
4350
4351 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4352 i++;
4353
4354 /* Return our idea of the offending token. */
4355 if (token_end || (i == 0 && token_end == 0))
4356 {
4357 if (token_end)
4358 msg = substring (t, i, token_end);
4359 else /* one-character token */
4360 {
4361 msg = (char *)xmalloc (2);
4362 msg[0] = t[i];
4363 msg[1] = '\0';
4364 }
4365 }
4366
4367 return (msg);
4368}
4369
4370static void
4371print_offending_line ()
4372{
4373 char *msg;
4374 int token_end;
4375
4376 msg = savestring (shell_input_line);
4377 token_end = strlen (msg);
4378 while (token_end && msg[token_end - 1] == '\n')
4379 msg[--token_end] = '\0';
4380
4381 parser_error (line_number, "`%s'", msg);
4382 free (msg);
4383}
4384
Jari Aalto726f6381996-08-26 18:22:31 +00004385/* Report a syntax error with line numbers, etc.
4386 Call here for recoverable errors. If you have a message to print,
4387 then place it in MESSAGE, otherwise pass NULL and this will figure
4388 out an appropriate message for you. */
4389static void
4390report_syntax_error (message)
4391 char *message;
4392{
Jari Aalto7117c2d2002-07-17 14:10:11 +00004393 char *msg;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004394
Jari Aalto726f6381996-08-26 18:22:31 +00004395 if (message)
4396 {
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004397 parser_error (line_number, "%s", message);
4398 if (interactive && EOF_Reached)
4399 EOF_Reached = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00004400 last_command_exit_value = EX_USAGE;
4401 return;
4402 }
4403
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004404 /* If the line of input we're reading is not null, try to find the
Jari Aalto7117c2d2002-07-17 14:10:11 +00004405 objectionable token. First, try to figure out what token the
4406 parser's complaining about by looking at current_token. */
4407 if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
4408 {
Jari Aaltob80f6442004-07-27 13:29:18 +00004409 parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
Jari Aalto7117c2d2002-07-17 14:10:11 +00004410 free (msg);
4411
4412 if (interactive == 0)
4413 print_offending_line ();
4414
4415 last_command_exit_value = EX_USAGE;
4416 return;
4417 }
4418
4419 /* If looking at the current token doesn't prove fruitful, try to find the
4420 offending token by analyzing the text of the input line near the current
4421 input line index and report what we find. */
Jari Aalto726f6381996-08-26 18:22:31 +00004422 if (shell_input_line && *shell_input_line)
4423 {
Jari Aalto7117c2d2002-07-17 14:10:11 +00004424 msg = error_token_from_text ();
4425 if (msg)
Jari Aalto726f6381996-08-26 18:22:31 +00004426 {
Jari Aaltob80f6442004-07-27 13:29:18 +00004427 parser_error (line_number, _("syntax error near `%s'"), msg);
Jari Aalto7117c2d2002-07-17 14:10:11 +00004428 free (msg);
Jari Aalto726f6381996-08-26 18:22:31 +00004429 }
4430
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004431 /* If not interactive, print the line containing the error. */
4432 if (interactive == 0)
Jari Aalto7117c2d2002-07-17 14:10:11 +00004433 print_offending_line ();
Jari Aalto726f6381996-08-26 18:22:31 +00004434 }
4435 else
4436 {
Jari Aaltob80f6442004-07-27 13:29:18 +00004437 msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004438 parser_error (line_number, "%s", msg);
4439 /* When the shell is interactive, this file uses EOF_Reached
4440 only for error reporting. Other mechanisms are used to
4441 decide whether or not to exit. */
4442 if (interactive && EOF_Reached)
4443 EOF_Reached = 0;
Jari Aalto726f6381996-08-26 18:22:31 +00004444 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00004445
Jari Aalto726f6381996-08-26 18:22:31 +00004446 last_command_exit_value = EX_USAGE;
4447}
4448
4449/* ??? Needed function. ??? We have to be able to discard the constructs
4450 created during parsing. In the case of error, we want to return
4451 allocated objects to the memory pool. In the case of no error, we want
4452 to throw away the information about where the allocated objects live.
Jari Aalto7117c2d2002-07-17 14:10:11 +00004453 (dispose_command () will actually free the command.) */
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004454static void
Jari Aalto726f6381996-08-26 18:22:31 +00004455discard_parser_constructs (error_p)
4456 int error_p;
4457{
4458}
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004459
Jari Aalto7117c2d2002-07-17 14:10:11 +00004460/************************************************
4461 * *
4462 * EOF HANDLING *
4463 * *
4464 ************************************************/
4465
Jari Aalto726f6381996-08-26 18:22:31 +00004466/* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4467
4468/* A flag denoting whether or not ignoreeof is set. */
4469int ignoreeof = 0;
4470
4471/* The number of times that we have encountered an EOF character without
4472 another character intervening. When this gets above the limit, the
4473 shell terminates. */
4474int eof_encountered = 0;
4475
4476/* The limit for eof_encountered. */
4477int eof_encountered_limit = 10;
4478
4479/* If we have EOF as the only input unit, this user wants to leave
4480 the shell. If the shell is not interactive, then just leave.
4481 Otherwise, if ignoreeof is set, and we haven't done this the
4482 required number of times in a row, print a message. */
4483static void
4484handle_eof_input_unit ()
4485{
4486 if (interactive)
4487 {
4488 /* shell.c may use this to decide whether or not to write out the
4489 history, among other things. We use it only for error reporting
4490 in this file. */
4491 if (EOF_Reached)
4492 EOF_Reached = 0;
4493
4494 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4495 if (ignoreeof)
4496 {
4497 if (eof_encountered < eof_encountered_limit)
4498 {
Jari Aaltob80f6442004-07-27 13:29:18 +00004499 fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
Jari Aalto726f6381996-08-26 18:22:31 +00004500 login_shell ? "logout" : "exit");
4501 eof_encountered++;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004502 /* Reset the parsing state. */
4503 last_read_token = current_token = '\n';
Jari Aalto726f6381996-08-26 18:22:31 +00004504 /* Reset the prompt string to be $PS1. */
4505 prompt_string_pointer = (char **)NULL;
4506 prompt_again ();
Jari Aalto726f6381996-08-26 18:22:31 +00004507 return;
Jari Aaltoccc6cda1996-12-23 17:02:34 +00004508 }
Jari Aalto726f6381996-08-26 18:22:31 +00004509 }
4510
4511 /* In this case EOF should exit the shell. Do it now. */
4512 reset_parser ();
4513 exit_builtin ((WORD_LIST *)NULL);
4514 }
4515 else
4516 {
4517 /* We don't write history files, etc., for non-interactive shells. */
4518 EOF_Reached = 1;
4519 }
4520}
Jari Aaltobb706242000-03-17 21:46:59 +00004521
Jari Aalto7117c2d2002-07-17 14:10:11 +00004522/************************************************
4523 * *
4524 * STRING PARSING FUNCTIONS *
4525 * *
4526 ************************************************/
4527
4528/* It's very important that these two functions treat the characters
4529 between ( and ) identically. */
4530
Jari Aaltobb706242000-03-17 21:46:59 +00004531static WORD_LIST parse_string_error;
4532
4533/* Take a string and run it through the shell parser, returning the
4534 resultant word list. Used by compound array assignment. */
4535WORD_LIST *
Jari Aaltob80f6442004-07-27 13:29:18 +00004536parse_string_to_word_list (s, flags, whom)
Jari Aaltof73dda02001-11-13 17:56:06 +00004537 char *s;
Jari Aaltob80f6442004-07-27 13:29:18 +00004538 int flags;
Jari Aaltof73dda02001-11-13 17:56:06 +00004539 const char *whom;
Jari Aaltobb706242000-03-17 21:46:59 +00004540{
4541 WORD_LIST *wl;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004542 int tok, orig_current_token, orig_line_number, orig_input_terminator;
Jari Aalto28ef6c32001-04-06 19:14:31 +00004543 int orig_line_count;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004544 int old_echo_input, old_expand_aliases;
Jari Aaltobb706242000-03-17 21:46:59 +00004545#if defined (HISTORY)
4546 int old_remember_on_history, old_history_expansion_inhibited;
4547#endif
4548
4549#if defined (HISTORY)
4550 old_remember_on_history = remember_on_history;
4551# if defined (BANG_HISTORY)
4552 old_history_expansion_inhibited = history_expansion_inhibited;
4553# endif
4554 bash_history_disable ();
4555#endif
4556
4557 orig_line_number = line_number;
Jari Aalto28ef6c32001-04-06 19:14:31 +00004558 orig_line_count = current_command_line_count;
Jari Aaltobb706242000-03-17 21:46:59 +00004559 orig_input_terminator = shell_input_line_terminator;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004560 old_echo_input = echo_input_at_read;
4561 old_expand_aliases = expand_aliases;
Jari Aaltobb706242000-03-17 21:46:59 +00004562
4563 push_stream (1);
Jari Aalto7117c2d2002-07-17 14:10:11 +00004564 last_read_token = WORD; /* WORD to allow reserved words here */
Jari Aalto28ef6c32001-04-06 19:14:31 +00004565 current_command_line_count = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004566 echo_input_at_read = expand_aliases = 0;
Jari Aaltobb706242000-03-17 21:46:59 +00004567
4568 with_input_from_string (s, whom);
4569 wl = (WORD_LIST *)NULL;
Jari Aaltob80f6442004-07-27 13:29:18 +00004570
4571 if (flags & 1)
4572 parser_state |= PST_COMPASSIGN;
4573
Jari Aaltobb706242000-03-17 21:46:59 +00004574 while ((tok = read_token (READ)) != yacc_EOF)
4575 {
4576 if (tok == '\n' && *bash_input.location.string == '\0')
4577 break;
Jari Aalto28ef6c32001-04-06 19:14:31 +00004578 if (tok == '\n') /* Allow newlines in compound assignments */
4579 continue;
Jari Aaltobb706242000-03-17 21:46:59 +00004580 if (tok != WORD && tok != ASSIGNMENT_WORD)
4581 {
4582 line_number = orig_line_number + line_number - 1;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004583 orig_current_token = current_token;
4584 current_token = tok;
Jari Aaltof73dda02001-11-13 17:56:06 +00004585 yyerror ((char *)NULL); /* does the right thing */
Jari Aalto7117c2d2002-07-17 14:10:11 +00004586 current_token = orig_current_token;
Jari Aaltobb706242000-03-17 21:46:59 +00004587 if (wl)
4588 dispose_words (wl);
4589 wl = &parse_string_error;
4590 break;
4591 }
4592 wl = make_word_list (yylval.word, wl);
4593 }
4594
4595 last_read_token = '\n';
4596 pop_stream ();
4597
4598#if defined (HISTORY)
4599 remember_on_history = old_remember_on_history;
4600# if defined (BANG_HISTORY)
4601 history_expansion_inhibited = old_history_expansion_inhibited;
4602# endif /* BANG_HISTORY */
4603#endif /* HISTORY */
4604
Jari Aalto7117c2d2002-07-17 14:10:11 +00004605 echo_input_at_read = old_echo_input;
4606 expand_aliases = old_expand_aliases;
4607
Jari Aalto28ef6c32001-04-06 19:14:31 +00004608 current_command_line_count = orig_line_count;
Jari Aaltobb706242000-03-17 21:46:59 +00004609 shell_input_line_terminator = orig_input_terminator;
4610
Jari Aaltob80f6442004-07-27 13:29:18 +00004611 if (flags & 1)
4612 parser_state &= ~PST_COMPASSIGN;
4613
Jari Aaltobb706242000-03-17 21:46:59 +00004614 if (wl == &parse_string_error)
4615 {
4616 last_command_exit_value = EXECUTION_FAILURE;
4617 if (interactive_shell == 0 && posixly_correct)
4618 jump_to_top_level (FORCE_EOF);
4619 else
4620 jump_to_top_level (DISCARD);
4621 }
4622
4623 return (REVERSE_LIST (wl, WORD_LIST *));
4624}
Jari Aalto7117c2d2002-07-17 14:10:11 +00004625
4626static char *
4627parse_compound_assignment (retlenp)
4628 int *retlenp;
4629{
4630 WORD_LIST *wl, *rl;
4631 int tok, orig_line_number, orig_token_size;
4632 char *saved_token, *ret;
4633
4634 saved_token = token;
4635 orig_token_size = token_buffer_size;
4636 orig_line_number = line_number;
4637
4638 last_read_token = WORD; /* WORD to allow reserved words here */
4639
4640 token = (char *)NULL;
4641 token_buffer_size = 0;
4642
4643 wl = (WORD_LIST *)NULL; /* ( */
Jari Aaltob80f6442004-07-27 13:29:18 +00004644 parser_state |= PST_COMPASSIGN;
4645
Jari Aalto7117c2d2002-07-17 14:10:11 +00004646 while ((tok = read_token (READ)) != ')')
4647 {
4648 if (tok == '\n') /* Allow newlines in compound assignments */
Jari Aaltob80f6442004-07-27 13:29:18 +00004649 {
4650 if (SHOULD_PROMPT ())
4651 prompt_again ();
4652 continue;
4653 }
Jari Aalto7117c2d2002-07-17 14:10:11 +00004654 if (tok != WORD && tok != ASSIGNMENT_WORD)
4655 {
4656 current_token = tok; /* for error reporting */
4657 if (tok == yacc_EOF) /* ( */
Jari Aaltob80f6442004-07-27 13:29:18 +00004658 parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
Jari Aalto7117c2d2002-07-17 14:10:11 +00004659 else
4660 yyerror ((char *)NULL); /* does the right thing */
4661 if (wl)
4662 dispose_words (wl);
4663 wl = &parse_string_error;
4664 break;
4665 }
4666 wl = make_word_list (yylval.word, wl);
4667 }
4668
4669 FREE (token);
4670 token = saved_token;
4671 token_buffer_size = orig_token_size;
4672
Jari Aaltob80f6442004-07-27 13:29:18 +00004673 parser_state &= ~PST_COMPASSIGN;
4674
Jari Aalto7117c2d2002-07-17 14:10:11 +00004675 if (wl == &parse_string_error)
4676 {
4677 last_command_exit_value = EXECUTION_FAILURE;
4678 last_read_token = '\n'; /* XXX */
4679 if (interactive_shell == 0 && posixly_correct)
4680 jump_to_top_level (FORCE_EOF);
4681 else
4682 jump_to_top_level (DISCARD);
4683 }
4684
4685 last_read_token = WORD;
4686 if (wl)
4687 {
4688 rl = REVERSE_LIST (wl, WORD_LIST *);
4689 ret = string_list (rl);
4690 dispose_words (rl);
4691 }
4692 else
4693 ret = (char *)NULL;
4694
4695 if (retlenp)
4696 *retlenp = (ret && *ret) ? strlen (ret) : 0;
4697 return ret;
4698}
4699
4700/************************************************
4701 * *
Jari Aaltob80f6442004-07-27 13:29:18 +00004702 * SAVING AND RESTORING PARTIAL PARSE STATE *
4703 * *
4704 ************************************************/
4705
4706sh_parser_state_t *
4707save_parser_state (ps)
4708 sh_parser_state_t *ps;
4709{
4710#if defined (ARRAY_VARS)
4711 SHELL_VAR *v;
4712#endif
4713
4714 if (ps == 0)
4715 ps = xmalloc (sizeof (sh_parser_state_t));
4716 if (ps == 0)
4717 return ((sh_parser_state_t *)NULL);
4718
4719 ps->parser_state = parser_state;
4720 ps->token_state = save_token_state ();
4721
4722 ps->input_line_terminator = shell_input_line_terminator;
4723 ps->eof_encountered = eof_encountered;
4724
4725 ps->current_command_line_count = current_command_line_count;
4726
4727#if defined (HISTORY)
4728 ps->remember_on_history = remember_on_history;
4729# if defined (BANG_HISTORY)
4730 ps->history_expansion_inhibited = history_expansion_inhibited;
4731# endif
4732#endif
4733
4734 ps->last_command_exit_value = last_command_exit_value;
4735#if defined (ARRAY_VARS)
4736 v = find_variable ("PIPESTATUS");
4737 if (v && array_p (v) && array_cell (v))
4738 ps->pipestatus = array_copy (array_cell (v));
4739 else
4740 ps->pipestatus = (ARRAY *)NULL;
4741#endif
4742
4743 ps->last_shell_builtin = last_shell_builtin;
4744 ps->this_shell_builtin = this_shell_builtin;
4745
4746 ps->expand_aliases = expand_aliases;
4747 ps->echo_input_at_read = echo_input_at_read;
4748
4749 return (ps);
4750}
4751
4752void
4753restore_parser_state (ps)
4754 sh_parser_state_t *ps;
4755{
4756#if defined (ARRAY_VARS)
4757 SHELL_VAR *v;
4758#endif
4759
4760 if (ps == 0)
4761 return;
4762
4763 parser_state = ps->parser_state;
4764 if (ps->token_state)
4765 {
4766 restore_token_state (ps->token_state);
4767 free (ps->token_state);
4768 }
4769
4770 shell_input_line_terminator = ps->input_line_terminator;
4771 eof_encountered = ps->eof_encountered;
4772
4773 current_command_line_count = ps->current_command_line_count;
4774
4775#if defined (HISTORY)
4776 remember_on_history = ps->remember_on_history;
4777# if defined (BANG_HISTORY)
4778 history_expansion_inhibited = ps->history_expansion_inhibited;
4779# endif
4780#endif
4781
4782 last_command_exit_value = ps->last_command_exit_value;
4783#if defined (ARRAY_VARS)
4784 v = find_variable ("PIPESTATUS");
4785 if (v && array_p (v) && array_cell (v))
4786 {
4787 array_dispose (array_cell (v));
4788 var_setarray (v, ps->pipestatus);
4789 }
4790#endif
4791
4792 last_shell_builtin = ps->last_shell_builtin;
4793 this_shell_builtin = ps->this_shell_builtin;
4794
4795 expand_aliases = ps->expand_aliases;
4796 echo_input_at_read = ps->echo_input_at_read;
4797}
4798
4799/************************************************
4800 * *
Jari Aalto7117c2d2002-07-17 14:10:11 +00004801 * MULTIBYTE CHARACTER HANDLING *
4802 * *
4803 ************************************************/
4804
4805#if defined (HANDLE_MULTIBYTE)
4806static void
4807set_line_mbstate ()
4808{
Jari Aaltob80f6442004-07-27 13:29:18 +00004809 int i, previ, len, c;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004810 mbstate_t mbs, prevs;
4811 size_t mbclen;
4812
4813 if (shell_input_line == NULL)
4814 return;
4815 len = strlen (shell_input_line); /* XXX - shell_input_line_len ? */
4816 FREE (shell_input_line_property);
4817 shell_input_line_property = (char *)xmalloc (len + 1);
4818
4819 memset (&prevs, '\0', sizeof (mbstate_t));
4820 for (i = previ = 0; i < len; i++)
4821 {
4822 mbs = prevs;
4823
Jari Aaltob80f6442004-07-27 13:29:18 +00004824 c = shell_input_line[i];
4825 if (c == EOF)
Jari Aalto7117c2d2002-07-17 14:10:11 +00004826 {
4827 int j;
4828 for (j = i; j < len; j++)
4829 shell_input_line_property[j] = 1;
4830 break;
4831 }
4832
4833 mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
4834 if (mbclen == 1 || mbclen == (size_t)-1)
4835 {
4836 mbclen = 1;
4837 previ = i + 1;
4838 }
4839 else if (mbclen == (size_t)-2)
4840 mbclen = 0;
4841 else if (mbclen > 1)
4842 {
4843 mbclen = 0;
4844 previ = i + 1;
4845 prevs = mbs;
4846 }
4847 else
4848 {
Jari Aaltob80f6442004-07-27 13:29:18 +00004849 /* XXX - what to do if mbrlen returns 0? (null wide character) */
4850 int j;
4851 for (j = i; j < len; j++)
4852 shell_input_line_property[j] = 1;
4853 break;
Jari Aalto7117c2d2002-07-17 14:10:11 +00004854 }
4855
4856 shell_input_line_property[i] = mbclen;
4857 }
4858}
4859#endif /* HANDLE_MULTIBYTE */