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