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