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