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