source: trunk/essentials/app-shells/bash/parse.y@ 3235

Last change on this file since 3235 was 3235, checked in by bird, 18 years ago

Applied bash-3.1-gentoo.patch (gentoo).

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