]> git.ipfire.org Git - thirdparty/bash.git/blob - parse.y
commit bash-20060119 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 ch = shell_getc (qc != '\'' && pass_next_character == 0);
2746
2747 if (ch == EOF)
2748 {
2749 free (ret);
2750 parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close);
2751 EOF_Reached = 1; /* XXX */
2752 return (&matched_pair_error);
2753 }
2754
2755 /* Possible reprompting. */
2756 if (ch == '\n' && SHOULD_PROMPT ())
2757 prompt_again ();
2758
2759 if (in_comment)
2760 {
2761 /* Add this character. */
2762 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
2763 ret[retind++] = ch;
2764
2765 if (ch == '\n')
2766 in_comment = 0;
2767
2768 continue;
2769 }
2770 /* Not exactly right yet */
2771 else if MBTEST(check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind - 1])))
2772 in_comment = 1;
2773
2774 if (pass_next_character) /* last char was backslash */
2775 {
2776 pass_next_character = 0;
2777 if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
2778 {
2779 if (retind > 0) retind--; /* swallow previously-added backslash */
2780 continue;
2781 }
2782
2783 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2784 if MBTEST(ch == CTLESC || ch == CTLNUL)
2785 ret[retind++] = CTLESC;
2786 ret[retind++] = ch;
2787 continue;
2788 }
2789 else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
2790 {
2791 RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
2792 ret[retind++] = CTLESC;
2793 ret[retind++] = ch;
2794 continue;
2795 }
2796 else if MBTEST(ch == close) /* ending delimiter */
2797 count--;
2798 /* handle nested ${...} specially. */
2799 else if MBTEST(open != close && was_dollar && open == '{' && ch == open) /* } */
2800 count++;
2801 else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
2802 count++;
2803
2804 /* Add this character. */
2805 RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
2806 ret[retind++] = ch;
2807
2808 if (open == '\'') /* '' inside grouping construct */
2809 {
2810 if MBTEST((flags & P_ALLOWESC) && ch == '\\')
2811 pass_next_character++;
2812 continue;
2813 }
2814
2815 if MBTEST(ch == '\\') /* backslashes */
2816 pass_next_character++;
2817
2818 if (open != close) /* a grouping construct */
2819 {
2820 if MBTEST(shellquote (ch))
2821 {
2822 /* '', ``, or "" inside $(...) or other grouping construct. */
2823 push_delimiter (dstack, ch);
2824 if MBTEST(was_dollar && ch == '\'') /* $'...' inside group */
2825 nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags);
2826 else
2827 nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags);
2828 pop_delimiter (dstack);
2829 if (nestret == &matched_pair_error)
2830 {
2831 free (ret);
2832 return &matched_pair_error;
2833 }
2834 if MBTEST(was_dollar && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0))
2835 {
2836 /* Translate $'...' here. */
2837 ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen);
2838 xfree (nestret);
2839
2840 if ((rflags & P_DQUOTE) == 0)
2841 {
2842 nestret = sh_single_quote (ttrans);
2843 free (ttrans);
2844 nestlen = strlen (nestret);
2845 }
2846 else
2847 {
2848 nestret = ttrans;
2849 nestlen = ttranslen;
2850 }
2851 retind -= 2; /* back up before the $' */
2852 }
2853 else if MBTEST(was_dollar && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0))
2854 {
2855 /* Locale expand $"..." here. */
2856 ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen);
2857 xfree (nestret);
2858
2859 nestret = sh_mkdoublequoted (ttrans, ttranslen, 0);
2860 free (ttrans);
2861 nestlen = ttranslen + 2;
2862 retind -= 2; /* back up before the $" */
2863 }
2864
2865 if (nestlen)
2866 {
2867 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2868 strcpy (ret + retind, nestret);
2869 retind += nestlen;
2870 }
2871 FREE (nestret);
2872 }
2873 }
2874 /* Parse an old-style command substitution within double quotes as a
2875 single word. */
2876 /* XXX - sh and ksh93 don't do this - XXX */
2877 else if MBTEST(open == '"' && ch == '`')
2878 {
2879 nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags);
2880 add_nestret:
2881 if (nestret == &matched_pair_error)
2882 {
2883 free (ret);
2884 return &matched_pair_error;
2885 }
2886 if (nestlen)
2887 {
2888 RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64);
2889 strcpy (ret + retind, nestret);
2890 retind += nestlen;
2891 }
2892 FREE (nestret);
2893 }
2894 else if MBTEST(qc == '`' && (ch == '"' || ch == '\'') && in_comment == 0)
2895 {
2896 /* Add P_ALLOWESC so backslash quotes the next character and
2897 shell_getc does the right thing with \<newline>. We do this for
2898 a measure of backwards compatibility -- it's not strictly the
2899 right POSIX thing. */
2900 nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags|P_ALLOWESC);
2901 goto add_nestret;
2902 }
2903 else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
2904 /* check for $(), $[], or ${} inside quoted string. */
2905 {
2906 if (open == ch) /* undo previous increment */
2907 count--;
2908 if (ch == '(') /* ) */
2909 nestret = parse_matched_pair (0, '(', ')', &nestlen, rflags & ~P_DQUOTE);
2910 else if (ch == '{') /* } */
2911 nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|rflags);
2912 else if (ch == '[') /* ] */
2913 nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags);
2914
2915 goto add_nestret;
2916 }
2917 was_dollar = MBTEST(ch == '$');
2918 }
2919
2920 ret[retind] = '\0';
2921 if (lenp)
2922 *lenp = retind;
2923 return ret;
2924 }
2925
2926 #if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND)
2927 /* Parse a double-paren construct. It can be either an arithmetic
2928 command, an arithmetic `for' command, or a nested subshell. Returns
2929 the parsed token, -1 on error, or -2 if we didn't do anything and
2930 should just go on. */
2931 static int
2932 parse_dparen (c)
2933 int c;
2934 {
2935 int cmdtyp, len, sline;
2936 char *wval, *wv2;
2937 WORD_DESC *wd;
2938
2939 #if defined (ARITH_FOR_COMMAND)
2940 if (last_read_token == FOR)
2941 {
2942 arith_for_lineno = line_number;
2943 cmdtyp = parse_arith_cmd (&wval, 0);
2944 if (cmdtyp == 1)
2945 {
2946 wd = alloc_word_desc ();
2947 wd->word = wval;
2948 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2949 return (ARITH_FOR_EXPRS);
2950 }
2951 else
2952 return -1; /* ERROR */
2953 }
2954 #endif
2955
2956 #if defined (DPAREN_ARITHMETIC)
2957 if (reserved_word_acceptable (last_read_token))
2958 {
2959 sline = line_number;
2960
2961 cmdtyp = parse_arith_cmd (&wval, 0);
2962 if (cmdtyp == 1) /* arithmetic command */
2963 {
2964 wd = alloc_word_desc ();
2965 wd->word = wval;
2966 wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE;
2967 yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
2968 return (ARITH_CMD);
2969 }
2970 else if (cmdtyp == 0) /* nested subshell */
2971 {
2972 push_string (wval, 0, (alias_t *)NULL);
2973 if ((parser_state & PST_CASEPAT) == 0)
2974 parser_state |= PST_SUBSHELL;
2975 return (c);
2976 }
2977 else /* ERROR */
2978 return -1;
2979 }
2980 #endif
2981
2982 return -2; /* XXX */
2983 }
2984
2985 /* We've seen a `(('. Look for the matching `))'. If we get it, return 1.
2986 If not, assume it's a nested subshell for backwards compatibility and
2987 return 0. In any case, put the characters we've consumed into a locally-
2988 allocated buffer and make *ep point to that buffer. Return -1 on an
2989 error, for example EOF. */
2990 static int
2991 parse_arith_cmd (ep, adddq)
2992 char **ep;
2993 int adddq;
2994 {
2995 int exp_lineno, rval, c;
2996 char *ttok, *tokstr;
2997 int ttoklen;
2998
2999 exp_lineno = line_number;
3000 ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0);
3001 rval = 1;
3002 if (ttok == &matched_pair_error)
3003 return -1;
3004 /* Check that the next character is the closing right paren. If
3005 not, this is a syntax error. ( */
3006 c = shell_getc (0);
3007 if MBTEST(c != ')')
3008 rval = 0;
3009
3010 tokstr = (char *)xmalloc (ttoklen + 4);
3011
3012 /* if ADDDQ != 0 then (( ... )) -> "..." */
3013 if (rval == 1 && adddq) /* arith cmd, add double quotes */
3014 {
3015 tokstr[0] = '"';
3016 strncpy (tokstr + 1, ttok, ttoklen - 1);
3017 tokstr[ttoklen] = '"';
3018 tokstr[ttoklen+1] = '\0';
3019 }
3020 else if (rval == 1) /* arith cmd, don't add double quotes */
3021 {
3022 strncpy (tokstr, ttok, ttoklen - 1);
3023 tokstr[ttoklen-1] = '\0';
3024 }
3025 else /* nested subshell */
3026 {
3027 tokstr[0] = '(';
3028 strncpy (tokstr + 1, ttok, ttoklen - 1);
3029 tokstr[ttoklen] = ')';
3030 tokstr[ttoklen+1] = c;
3031 tokstr[ttoklen+2] = '\0';
3032 }
3033
3034 *ep = tokstr;
3035 FREE (ttok);
3036 return rval;
3037 }
3038 #endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */
3039
3040 #if defined (COND_COMMAND)
3041 static void
3042 cond_error ()
3043 {
3044 char *etext;
3045
3046 if (EOF_Reached && cond_token != COND_ERROR) /* [[ */
3047 parser_error (cond_lineno, _("unexpected EOF while looking for `]]'"));
3048 else if (cond_token != COND_ERROR)
3049 {
3050 if (etext = error_token_from_token (cond_token))
3051 {
3052 parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext);
3053 free (etext);
3054 }
3055 else
3056 parser_error (cond_lineno, _("syntax error in conditional expression"));
3057 }
3058 }
3059
3060 static COND_COM *
3061 cond_expr ()
3062 {
3063 return (cond_or ());
3064 }
3065
3066 static COND_COM *
3067 cond_or ()
3068 {
3069 COND_COM *l, *r;
3070
3071 l = cond_and ();
3072 if (cond_token == OR_OR)
3073 {
3074 r = cond_or ();
3075 l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r);
3076 }
3077 return l;
3078 }
3079
3080 static COND_COM *
3081 cond_and ()
3082 {
3083 COND_COM *l, *r;
3084
3085 l = cond_term ();
3086 if (cond_token == AND_AND)
3087 {
3088 r = cond_and ();
3089 l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r);
3090 }
3091 return l;
3092 }
3093
3094 static int
3095 cond_skip_newlines ()
3096 {
3097 while ((cond_token = read_token (READ)) == '\n')
3098 {
3099 if (SHOULD_PROMPT ())
3100 prompt_again ();
3101 }
3102 return (cond_token);
3103 }
3104
3105 #define COND_RETURN_ERROR() \
3106 do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0)
3107
3108 static COND_COM *
3109 cond_term ()
3110 {
3111 WORD_DESC *op;
3112 COND_COM *term, *tleft, *tright;
3113 int tok, lineno;
3114 char *etext;
3115
3116 /* Read a token. It can be a left paren, a `!', a unary operator, or a
3117 word that should be the first argument of a binary operator. Start by
3118 skipping newlines, since this is a compound command. */
3119 tok = cond_skip_newlines ();
3120 lineno = line_number;
3121 if (tok == COND_END)
3122 {
3123 COND_RETURN_ERROR ();
3124 }
3125 else if (tok == '(')
3126 {
3127 term = cond_expr ();
3128 if (cond_token != ')')
3129 {
3130 if (term)
3131 dispose_cond_node (term); /* ( */
3132 if (etext = error_token_from_token (cond_token))
3133 {
3134 parser_error (lineno, _("unexpected token `%s', expected `)'"), etext);
3135 free (etext);
3136 }
3137 else
3138 parser_error (lineno, _("expected `)'"));
3139 COND_RETURN_ERROR ();
3140 }
3141 term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL);
3142 (void)cond_skip_newlines ();
3143 }
3144 else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0')))
3145 {
3146 if (tok == WORD)
3147 dispose_word (yylval.word); /* not needed */
3148 term = cond_term ();
3149 if (term)
3150 term->flags |= CMD_INVERT_RETURN;
3151 }
3152 else if (tok == WORD && test_unop (yylval.word->word))
3153 {
3154 op = yylval.word;
3155 tok = read_token (READ);
3156 if (tok == WORD)
3157 {
3158 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3159 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3160 }
3161 else
3162 {
3163 dispose_word (op);
3164 if (etext = error_token_from_token (tok))
3165 {
3166 parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext);
3167 free (etext);
3168 }
3169 else
3170 parser_error (line_number, _("unexpected argument to conditional unary operator"));
3171 COND_RETURN_ERROR ();
3172 }
3173
3174 (void)cond_skip_newlines ();
3175 }
3176 else if (tok == WORD) /* left argument to binary operator */
3177 {
3178 /* lhs */
3179 tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3180
3181 /* binop */
3182 tok = read_token (READ);
3183 if (tok == WORD && test_binop (yylval.word->word))
3184 op = yylval.word;
3185 #if defined (COND_REGEXP)
3186 else if (tok == WORD && STREQ (yylval.word->word,"=~"))
3187 op = yylval.word;
3188 #endif
3189 else if (tok == '<' || tok == '>')
3190 op = make_word_from_token (tok); /* ( */
3191 /* There should be a check before blindly accepting the `)' that we have
3192 seen the opening `('. */
3193 else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')')
3194 {
3195 /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like
3196 the test command. Similarly for [[ x && expr ]] or
3197 [[ x || expr ]] or [[ (x) ]]. */
3198 op = make_word ("-n");
3199 term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL);
3200 cond_token = tok;
3201 return (term);
3202 }
3203 else
3204 {
3205 if (etext = error_token_from_token (tok))
3206 {
3207 parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext);
3208 free (etext);
3209 }
3210 else
3211 parser_error (line_number, _("conditional binary operator expected"));
3212 dispose_cond_node (tleft);
3213 COND_RETURN_ERROR ();
3214 }
3215
3216 /* rhs */
3217 tok = read_token (READ);
3218 if (tok == WORD)
3219 {
3220 tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL);
3221 term = make_cond_node (COND_BINARY, op, tleft, tright);
3222 }
3223 else
3224 {
3225 if (etext = error_token_from_token (tok))
3226 {
3227 parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext);
3228 free (etext);
3229 }
3230 else
3231 parser_error (line_number, _("unexpected argument to conditional binary operator"));
3232 dispose_cond_node (tleft);
3233 dispose_word (op);
3234 COND_RETURN_ERROR ();
3235 }
3236
3237 (void)cond_skip_newlines ();
3238 }
3239 else
3240 {
3241 if (tok < 256)
3242 parser_error (line_number, _("unexpected token `%c' in conditional command"), tok);
3243 else if (etext = error_token_from_token (tok))
3244 {
3245 parser_error (line_number, _("unexpected token `%s' in conditional command"), etext);
3246 free (etext);
3247 }
3248 else
3249 parser_error (line_number, _("unexpected token %d in conditional command"), tok);
3250 COND_RETURN_ERROR ();
3251 }
3252 return (term);
3253 }
3254
3255 /* This is kind of bogus -- we slip a mini recursive-descent parser in
3256 here to handle the conditional statement syntax. */
3257 static COMMAND *
3258 parse_cond_command ()
3259 {
3260 COND_COM *cexp;
3261
3262 cexp = cond_expr ();
3263 return (make_cond_command (cexp));
3264 }
3265 #endif
3266
3267 #if defined (ARRAY_VARS)
3268 /* When this is called, it's guaranteed that we don't care about anything
3269 in t beyond i. We do save and restore the chars, though. */
3270 static int
3271 token_is_assignment (t, i)
3272 char *t;
3273 int i;
3274 {
3275 unsigned char c, c1;
3276 int r;
3277
3278 c = t[i]; c1 = t[i+1];
3279 t[i] = '='; t[i+1] = '\0';
3280 r = assignment (t, (parser_state & PST_COMPASSIGN) != 0);
3281 t[i] = c; t[i+1] = c1;
3282 return r;
3283 }
3284
3285 /* XXX - possible changes here for `+=' */
3286 static int
3287 token_is_ident (t, i)
3288 char *t;
3289 int i;
3290 {
3291 unsigned char c;
3292 int r;
3293
3294 c = t[i];
3295 t[i] = '\0';
3296 r = legal_identifier (t);
3297 t[i] = c;
3298 return r;
3299 }
3300 #endif
3301
3302 static int
3303 read_token_word (character)
3304 int character;
3305 {
3306 /* The value for YYLVAL when a WORD is read. */
3307 WORD_DESC *the_word;
3308
3309 /* Index into the token that we are building. */
3310 int token_index;
3311
3312 /* ALL_DIGITS becomes zero when we see a non-digit. */
3313 int all_digit_token;
3314
3315 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
3316 int dollar_present;
3317
3318 /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound
3319 assignment. */
3320 int compound_assignment;
3321
3322 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
3323 int quoted;
3324
3325 /* Non-zero means to ignore the value of the next character, and just
3326 to add it no matter what. */
3327 int pass_next_character;
3328
3329 /* The current delimiting character. */
3330 int cd;
3331 int result, peek_char;
3332 char *ttok, *ttrans;
3333 int ttoklen, ttranslen;
3334 intmax_t lvalue;
3335
3336 if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE)
3337 token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE);
3338
3339 token_index = 0;
3340 all_digit_token = DIGIT (character);
3341 dollar_present = quoted = pass_next_character = compound_assignment = 0;
3342
3343 for (;;)
3344 {
3345 if (character == EOF)
3346 goto got_token;
3347
3348 if (pass_next_character)
3349 {
3350 pass_next_character = 0;
3351 goto got_character;
3352 }
3353
3354 cd = current_delimiter (dstack);
3355
3356 /* Handle backslashes. Quote lots of things when not inside of
3357 double-quotes, quote some things inside of double-quotes. */
3358 if MBTEST(character == '\\')
3359 {
3360 peek_char = shell_getc (0);
3361
3362 /* Backslash-newline is ignored in all cases except
3363 when quoted with single quotes. */
3364 if (peek_char == '\n')
3365 {
3366 character = '\n';
3367 goto next_character;
3368 }
3369 else
3370 {
3371 shell_ungetc (peek_char);
3372
3373 /* If the next character is to be quoted, note it now. */
3374 if (cd == 0 || cd == '`' ||
3375 (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE)))
3376 pass_next_character++;
3377
3378 quoted = 1;
3379 goto got_character;
3380 }
3381 }
3382
3383 /* Parse a matched pair of quote characters. */
3384 if MBTEST(shellquote (character))
3385 {
3386 push_delimiter (dstack, character);
3387 ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0);
3388 pop_delimiter (dstack);
3389 if (ttok == &matched_pair_error)
3390 return -1; /* Bail immediately. */
3391 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3392 token_buffer_size, TOKEN_DEFAULT_GROW_SIZE);
3393 token[token_index++] = character;
3394 strcpy (token + token_index, ttok);
3395 token_index += ttoklen;
3396 all_digit_token = 0;
3397 quoted = 1;
3398 dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
3399 FREE (ttok);
3400 goto next_character;
3401 }
3402
3403 #ifdef EXTENDED_GLOB
3404 /* Parse a ksh-style extended pattern matching specification. */
3405 if (extended_glob && PATTERN_CHAR (character))
3406 {
3407 peek_char = shell_getc (1);
3408 if MBTEST(peek_char == '(') /* ) */
3409 {
3410 push_delimiter (dstack, peek_char);
3411 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0);
3412 pop_delimiter (dstack);
3413 if (ttok == &matched_pair_error)
3414 return -1; /* Bail immediately. */
3415 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3416 token_buffer_size,
3417 TOKEN_DEFAULT_GROW_SIZE);
3418 token[token_index++] = character;
3419 token[token_index++] = peek_char;
3420 strcpy (token + token_index, ttok);
3421 token_index += ttoklen;
3422 FREE (ttok);
3423 dollar_present = all_digit_token = 0;
3424 goto next_character;
3425 }
3426 else
3427 shell_ungetc (peek_char);
3428 }
3429 #endif /* EXTENDED_GLOB */
3430
3431 /* If the delimiter character is not single quote, parse some of
3432 the shell expansions that must be read as a single word. */
3433 if (shellexp (character))
3434 {
3435 peek_char = shell_getc (1);
3436 /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */
3437 if MBTEST(peek_char == '(' || \
3438 ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */
3439 {
3440 if (peek_char == '{') /* } */
3441 ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE);
3442 else if (peek_char == '(') /* ) */
3443 {
3444 /* XXX - push and pop the `(' as a delimiter for use by
3445 the command-oriented-history code. This way newlines
3446 appearing in the $(...) string get added to the
3447 history literally rather than causing a possibly-
3448 incorrect `;' to be added. ) */
3449 push_delimiter (dstack, peek_char);
3450 ttok = parse_matched_pair (cd, '(', ')', &ttoklen, P_COMMAND);
3451 pop_delimiter (dstack);
3452 }
3453 else
3454 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3455 if (ttok == &matched_pair_error)
3456 return -1; /* Bail immediately. */
3457 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3458 token_buffer_size,
3459 TOKEN_DEFAULT_GROW_SIZE);
3460 token[token_index++] = character;
3461 token[token_index++] = peek_char;
3462 strcpy (token + token_index, ttok);
3463 token_index += ttoklen;
3464 FREE (ttok);
3465 dollar_present = 1;
3466 all_digit_token = 0;
3467 goto next_character;
3468 }
3469 /* This handles $'...' and $"..." new-style quoted strings. */
3470 else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"'))
3471 {
3472 int first_line;
3473
3474 first_line = line_number;
3475 push_delimiter (dstack, peek_char);
3476 ttok = parse_matched_pair (peek_char, peek_char, peek_char,
3477 &ttoklen,
3478 (peek_char == '\'') ? P_ALLOWESC : 0);
3479 pop_delimiter (dstack);
3480 if (ttok == &matched_pair_error)
3481 return -1;
3482 if (peek_char == '\'')
3483 {
3484 ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen);
3485 free (ttok);
3486
3487 /* Insert the single quotes and correctly quote any
3488 embedded single quotes (allowed because P_ALLOWESC was
3489 passed to parse_matched_pair). */
3490 ttok = sh_single_quote (ttrans);
3491 free (ttrans);
3492 ttranslen = strlen (ttok);
3493 ttrans = ttok;
3494 }
3495 else
3496 {
3497 /* Try to locale-expand the converted string. */
3498 ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
3499 free (ttok);
3500
3501 /* Add the double quotes back */
3502 ttok = sh_mkdoublequoted (ttrans, ttranslen, 0);
3503 free (ttrans);
3504 ttranslen += 2;
3505 ttrans = ttok;
3506 }
3507
3508 RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 2,
3509 token_buffer_size,
3510 TOKEN_DEFAULT_GROW_SIZE);
3511 strcpy (token + token_index, ttrans);
3512 token_index += ttranslen;
3513 FREE (ttrans);
3514 quoted = 1;
3515 all_digit_token = 0;
3516 goto next_character;
3517 }
3518 /* This could eventually be extended to recognize all of the
3519 shell's single-character parameter expansions, and set flags.*/
3520 else if MBTEST(character == '$' && peek_char == '$')
3521 {
3522 ttok = (char *)xmalloc (3);
3523 ttok[0] = ttok[1] = '$';
3524 ttok[2] = '\0';
3525 RESIZE_MALLOCED_BUFFER (token, token_index, 3,
3526 token_buffer_size,
3527 TOKEN_DEFAULT_GROW_SIZE);
3528 strcpy (token + token_index, ttok);
3529 token_index += 2;
3530 dollar_present = 1;
3531 all_digit_token = 0;
3532 FREE (ttok);
3533 goto next_character;
3534 }
3535 else
3536 shell_ungetc (peek_char);
3537 }
3538
3539 #if defined (ARRAY_VARS)
3540 /* Identify possible array subscript assignment; match [...] */
3541 else if MBTEST(character == '[' && token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) /* ] */
3542 {
3543 ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
3544 if (ttok == &matched_pair_error)
3545 return -1; /* Bail immediately. */
3546 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
3547 token_buffer_size,
3548 TOKEN_DEFAULT_GROW_SIZE);
3549 token[token_index++] = character;
3550 strcpy (token + token_index, ttok);
3551 token_index += ttoklen;
3552 FREE (ttok);
3553 all_digit_token = 0;
3554 goto next_character;
3555 }
3556 /* Identify possible compound array variable assignment. */
3557 else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index))
3558 {
3559 peek_char = shell_getc (1);
3560 if MBTEST(peek_char == '(') /* ) */
3561 {
3562 ttok = parse_compound_assignment (&ttoklen);
3563
3564 RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4,
3565 token_buffer_size,
3566 TOKEN_DEFAULT_GROW_SIZE);
3567
3568 token[token_index++] = '=';
3569 token[token_index++] = '(';
3570 if (ttok)
3571 {
3572 strcpy (token + token_index, ttok);
3573 token_index += ttoklen;
3574 }
3575 token[token_index++] = ')';
3576 FREE (ttok);
3577 all_digit_token = 0;
3578 compound_assignment = 1;
3579 #if 0
3580 goto next_character;
3581 #else
3582 goto got_token; /* ksh93 seems to do this */
3583 #endif
3584 }
3585 else
3586 shell_ungetc (peek_char);
3587 }
3588 #endif
3589
3590 /* When not parsing a multi-character word construct, shell meta-
3591 characters break words. */
3592 if MBTEST(shellbreak (character))
3593 {
3594 shell_ungetc (character);
3595 goto got_token;
3596 }
3597
3598 got_character:
3599
3600 all_digit_token &= DIGIT (character);
3601 dollar_present |= character == '$';
3602
3603 if (character == CTLESC || character == CTLNUL)
3604 token[token_index++] = CTLESC;
3605
3606 token[token_index++] = character;
3607
3608 RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size,
3609 TOKEN_DEFAULT_GROW_SIZE);
3610
3611 next_character:
3612 if (character == '\n' && SHOULD_PROMPT ())
3613 prompt_again ();
3614
3615 /* We want to remove quoted newlines (that is, a \<newline> pair)
3616 unless we are within single quotes or pass_next_character is
3617 set (the shell equivalent of literal-next). */
3618 cd = current_delimiter (dstack);
3619 character = shell_getc (cd != '\'' && pass_next_character == 0);
3620 } /* end for (;;) */
3621
3622 got_token:
3623
3624 token[token_index] = '\0';
3625
3626 /* Check to see what thing we should return. If the last_read_token
3627 is a `<', or a `&', or the character which ended this token is
3628 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
3629 Otherwise, it is just a word, and should be returned as such. */
3630 if MBTEST(all_digit_token && (character == '<' || character == '>' || \
3631 last_read_token == LESS_AND || \
3632 last_read_token == GREATER_AND))
3633 {
3634 if (legal_number (token, &lvalue) && (int)lvalue == lvalue)
3635 yylval.number = lvalue;
3636 else
3637 yylval.number = -1;
3638 return (NUMBER);
3639 }
3640
3641 /* Check for special case tokens. */
3642 result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1;
3643 if (result >= 0)
3644 return result;
3645
3646 #if defined (ALIAS)
3647 /* Posix.2 does not allow reserved words to be aliased, so check for all
3648 of them, including special cases, before expanding the current token
3649 as an alias. */
3650 if MBTEST(posixly_correct)
3651 CHECK_FOR_RESERVED_WORD (token);
3652
3653 /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting
3654 inhibits alias expansion. */
3655 if (expand_aliases && quoted == 0)
3656 {
3657 result = alias_expand_token (token);
3658 if (result == RE_READ_TOKEN)
3659 return (RE_READ_TOKEN);
3660 else if (result == NO_EXPANSION)
3661 parser_state &= ~PST_ALEXPNEXT;
3662 }
3663
3664 /* If not in Posix.2 mode, check for reserved words after alias
3665 expansion. */
3666 if MBTEST(posixly_correct == 0)
3667 #endif
3668 CHECK_FOR_RESERVED_WORD (token);
3669
3670 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
3671 the_word->word = (char *)xmalloc (1 + token_index);
3672 the_word->flags = 0;
3673 strcpy (the_word->word, token);
3674 if (dollar_present)
3675 the_word->flags |= W_HASDOLLAR;
3676 if (quoted)
3677 the_word->flags |= W_QUOTED;
3678 if (compound_assignment)
3679 the_word->flags |= W_COMPASSIGN;
3680 /* A word is an assignment if it appears at the beginning of a
3681 simple command, or after another assignment word. This is
3682 context-dependent, so it cannot be handled in the grammar. */
3683 if (assignment (token, (parser_state & PST_COMPASSIGN) != 0))
3684 {
3685 the_word->flags |= W_ASSIGNMENT;
3686 /* Don't perform word splitting on assignment statements. */
3687 if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0)
3688 the_word->flags |= W_NOSPLIT;
3689 }
3690
3691 if (command_token_position (last_read_token))
3692 {
3693 struct builtin *b;
3694 b = builtin_address_internal (token, 0);
3695 if (b && (b->flags & ASSIGNMENT_BUILTIN))
3696 parser_state |= PST_ASSIGNOK;
3697 else if (STREQ (token, "eval") || STREQ (token, "let"))
3698 parser_state |= PST_ASSIGNOK;
3699 }
3700
3701 yylval.word = the_word;
3702
3703 result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT))
3704 ? ASSIGNMENT_WORD : WORD;
3705
3706 switch (last_read_token)
3707 {
3708 case FUNCTION:
3709 parser_state |= PST_ALLOWOPNBRC;
3710 function_dstart = line_number;
3711 break;
3712 case CASE:
3713 case SELECT:
3714 case FOR:
3715 if (word_top < MAX_CASE_NEST)
3716 word_top++;
3717 word_lineno[word_top] = line_number;
3718 break;
3719 }
3720
3721 return (result);
3722 }
3723
3724 /* Return 1 if TOKSYM is a token that after being read would allow
3725 a reserved word to be seen, else 0. */
3726 static int
3727 reserved_word_acceptable (toksym)
3728 int toksym;
3729 {
3730 switch (toksym)
3731 {
3732 case '\n':
3733 case ';':
3734 case '(':
3735 case ')':
3736 case '|':
3737 case '&':
3738 case '{':
3739 case '}': /* XXX */
3740 case AND_AND:
3741 case BANG:
3742 case DO:
3743 case DONE:
3744 case ELIF:
3745 case ELSE:
3746 case ESAC:
3747 case FI:
3748 case IF:
3749 case OR_OR:
3750 case SEMI_SEMI:
3751 case THEN:
3752 case TIME:
3753 case TIMEOPT:
3754 case UNTIL:
3755 case WHILE:
3756 case 0:
3757 return 1;
3758 default:
3759 return 0;
3760 }
3761 }
3762
3763 /* Return the index of TOKEN in the alist of reserved words, or -1 if
3764 TOKEN is not a shell reserved word. */
3765 int
3766 find_reserved_word (tokstr)
3767 char *tokstr;
3768 {
3769 int i;
3770 for (i = 0; word_token_alist[i].word; i++)
3771 if (STREQ (tokstr, word_token_alist[i].word))
3772 return i;
3773 return -1;
3774 }
3775
3776 #if 0
3777 #if defined (READLINE)
3778 /* Called after each time readline is called. This insures that whatever
3779 the new prompt string is gets propagated to readline's local prompt
3780 variable. */
3781 static void
3782 reset_readline_prompt ()
3783 {
3784 char *temp_prompt;
3785
3786 if (prompt_string_pointer)
3787 {
3788 temp_prompt = (*prompt_string_pointer)
3789 ? decode_prompt_string (*prompt_string_pointer)
3790 : (char *)NULL;
3791
3792 if (temp_prompt == 0)
3793 {
3794 temp_prompt = (char *)xmalloc (1);
3795 temp_prompt[0] = '\0';
3796 }
3797
3798 FREE (current_readline_prompt);
3799 current_readline_prompt = temp_prompt;
3800 }
3801 }
3802 #endif /* READLINE */
3803 #endif /* 0 */
3804
3805 #if defined (HISTORY)
3806 /* A list of tokens which can be followed by newlines, but not by
3807 semi-colons. When concatenating multiple lines of history, the
3808 newline separator for such tokens is replaced with a space. */
3809 static int no_semi_successors[] = {
3810 '\n', '{', '(', ')', ';', '&', '|',
3811 CASE, DO, ELSE, IF, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR, IN,
3812 0
3813 };
3814
3815 /* If we are not within a delimited expression, try to be smart
3816 about which separators can be semi-colons and which must be
3817 newlines. Returns the string that should be added into the
3818 history entry. */
3819 char *
3820 history_delimiting_chars ()
3821 {
3822 register int i;
3823
3824 if (dstack.delimiter_depth != 0)
3825 return ("\n");
3826
3827 /* First, handle some special cases. */
3828 /*(*/
3829 /* If we just read `()', assume it's a function definition, and don't
3830 add a semicolon. If the token before the `)' was not `(', and we're
3831 not in the midst of parsing a case statement, assume it's a
3832 parenthesized command and add the semicolon. */
3833 /*)(*/
3834 if (token_before_that == ')')
3835 {
3836 if (two_tokens_ago == '(') /*)*/ /* function def */
3837 return " ";
3838 /* This does not work for subshells inside case statement
3839 command lists. It's a suboptimal solution. */
3840 else if (parser_state & PST_CASESTMT) /* case statement pattern */
3841 return " ";
3842 else
3843 return "; "; /* (...) subshell */
3844 }
3845 else if (token_before_that == WORD && two_tokens_ago == FUNCTION)
3846 return " "; /* function def using `function name' without `()' */
3847
3848 else if (token_before_that == WORD && two_tokens_ago == FOR)
3849 {
3850 /* Tricky. `for i\nin ...' should not have a semicolon, but
3851 `for i\ndo ...' should. We do what we can. */
3852 for (i = shell_input_line_index; whitespace(shell_input_line[i]); i++)
3853 ;
3854 if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n')
3855 return " ";
3856 return ";";
3857 }
3858 else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT))
3859 return " ";
3860
3861 for (i = 0; no_semi_successors[i]; i++)
3862 {
3863 if (token_before_that == no_semi_successors[i])
3864 return (" ");
3865 }
3866
3867 return ("; ");
3868 }
3869 #endif /* HISTORY */
3870
3871 /* Issue a prompt, or prepare to issue a prompt when the next character
3872 is read. */
3873 static void
3874 prompt_again ()
3875 {
3876 char *temp_prompt;
3877
3878 if (interactive == 0 || expanding_alias()) /* XXX */
3879 return;
3880
3881 ps1_prompt = get_string_value ("PS1");
3882 ps2_prompt = get_string_value ("PS2");
3883
3884 if (!prompt_string_pointer)
3885 prompt_string_pointer = &ps1_prompt;
3886
3887 temp_prompt = *prompt_string_pointer
3888 ? decode_prompt_string (*prompt_string_pointer)
3889 : (char *)NULL;
3890
3891 if (temp_prompt == 0)
3892 {
3893 temp_prompt = (char *)xmalloc (1);
3894 temp_prompt[0] = '\0';
3895 }
3896
3897 current_prompt_string = *prompt_string_pointer;
3898 prompt_string_pointer = &ps2_prompt;
3899
3900 #if defined (READLINE)
3901 if (!no_line_editing)
3902 {
3903 FREE (current_readline_prompt);
3904 current_readline_prompt = temp_prompt;
3905 }
3906 else
3907 #endif /* READLINE */
3908 {
3909 FREE (current_decoded_prompt);
3910 current_decoded_prompt = temp_prompt;
3911 }
3912 }
3913
3914 int
3915 get_current_prompt_level ()
3916 {
3917 return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1);
3918 }
3919
3920 void
3921 set_current_prompt_level (x)
3922 int x;
3923 {
3924 prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt;
3925 current_prompt_string = *prompt_string_pointer;
3926 }
3927
3928 static void
3929 print_prompt ()
3930 {
3931 fprintf (stderr, "%s", current_decoded_prompt);
3932 fflush (stderr);
3933 }
3934
3935 /* Return a string which will be printed as a prompt. The string
3936 may contain special characters which are decoded as follows:
3937
3938 \a bell (ascii 07)
3939 \d the date in Day Mon Date format
3940 \e escape (ascii 033)
3941 \h the hostname up to the first `.'
3942 \H the hostname
3943 \j the number of active jobs
3944 \l the basename of the shell's tty device name
3945 \n CRLF
3946 \r CR
3947 \s the name of the shell
3948 \t the time in 24-hour hh:mm:ss format
3949 \T the time in 12-hour hh:mm:ss format
3950 \@ the time in 12-hour hh:mm am/pm format
3951 \A the time in 24-hour hh:mm format
3952 \D{fmt} the result of passing FMT to strftime(3)
3953 \u your username
3954 \v the version of bash (e.g., 2.00)
3955 \V the release of bash, version + patchlevel (e.g., 2.00.0)
3956 \w the current working directory
3957 \W the last element of $PWD
3958 \! the history number of this command
3959 \# the command number of this command
3960 \$ a $ or a # if you are root
3961 \nnn character code nnn in octal
3962 \\ a backslash
3963 \[ begin a sequence of non-printing chars
3964 \] end a sequence of non-printing chars
3965 */
3966 #define PROMPT_GROWTH 48
3967 char *
3968 decode_prompt_string (string)
3969 char *string;
3970 {
3971 WORD_LIST *list;
3972 char *result, *t;
3973 struct dstack save_dstack;
3974 int last_exit_value;
3975 #if defined (PROMPT_STRING_DECODE)
3976 int result_size, result_index;
3977 int c, n;
3978 char *temp, octal_string[4];
3979 struct tm *tm;
3980 time_t the_time;
3981 char timebuf[128];
3982 char *timefmt;
3983
3984 result = (char *)xmalloc (result_size = PROMPT_GROWTH);
3985 result[result_index = 0] = 0;
3986 temp = (char *)NULL;
3987
3988 while (c = *string++)
3989 {
3990 if (posixly_correct && c == '!')
3991 {
3992 if (*string == '!')
3993 {
3994 temp = savestring ("!");
3995 goto add_string;
3996 }
3997 else
3998 {
3999 #if !defined (HISTORY)
4000 temp = savestring ("1");
4001 #else /* HISTORY */
4002 temp = itos (history_number ());
4003 #endif /* HISTORY */
4004 string--; /* add_string increments string again. */
4005 goto add_string;
4006 }
4007 }
4008 if (c == '\\')
4009 {
4010 c = *string;
4011
4012 switch (c)
4013 {
4014 case '0':
4015 case '1':
4016 case '2':
4017 case '3':
4018 case '4':
4019 case '5':
4020 case '6':
4021 case '7':
4022 strncpy (octal_string, string, 3);
4023 octal_string[3] = '\0';
4024
4025 n = read_octal (octal_string);
4026 temp = (char *)xmalloc (3);
4027
4028 if (n == CTLESC || n == CTLNUL)
4029 {
4030 temp[0] = CTLESC;
4031 temp[1] = n;
4032 temp[2] = '\0';
4033 }
4034 else if (n == -1)
4035 {
4036 temp[0] = '\\';
4037 temp[1] = '\0';
4038 }
4039 else
4040 {
4041 temp[0] = n;
4042 temp[1] = '\0';
4043 }
4044
4045 for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++)
4046 string++;
4047
4048 c = 0; /* tested at add_string: */
4049 goto add_string;
4050
4051 case 'd':
4052 case 't':
4053 case 'T':
4054 case '@':
4055 case 'A':
4056 /* Make the current time/date into a string. */
4057 (void) time (&the_time);
4058 tm = localtime (&the_time);
4059
4060 if (c == 'd')
4061 n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm);
4062 else if (c == 't')
4063 n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm);
4064 else if (c == 'T')
4065 n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm);
4066 else if (c == '@')
4067 n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm);
4068 else if (c == 'A')
4069 n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm);
4070
4071 if (n == 0)
4072 timebuf[0] = '\0';
4073 else
4074 timebuf[sizeof(timebuf) - 1] = '\0';
4075
4076 temp = savestring (timebuf);
4077 goto add_string;
4078
4079 case 'D': /* strftime format */
4080 if (string[1] != '{') /* } */
4081 goto not_escape;
4082
4083 (void) time (&the_time);
4084 tm = localtime (&the_time);
4085 string += 2; /* skip { */
4086 timefmt = xmalloc (strlen (string) + 3);
4087 for (t = timefmt; *string && *string != '}'; )
4088 *t++ = *string++;
4089 *t = '\0';
4090 c = *string; /* tested at add_string */
4091 if (timefmt[0] == '\0')
4092 {
4093 timefmt[0] = '%';
4094 timefmt[1] = 'X'; /* locale-specific current time */
4095 timefmt[2] = '\0';
4096 }
4097 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
4098 free (timefmt);
4099
4100 if (n == 0)
4101 timebuf[0] = '\0';
4102 else
4103 timebuf[sizeof(timebuf) - 1] = '\0';
4104
4105 if (promptvars || posixly_correct)
4106 /* Make sure that expand_prompt_string is called with a
4107 second argument of Q_DOUBLE_QUOTES if we use this
4108 function here. */
4109 temp = sh_backslash_quote_for_double_quotes (timebuf);
4110 else
4111 temp = savestring (timebuf);
4112 goto add_string;
4113
4114 case 'n':
4115 temp = (char *)xmalloc (3);
4116 temp[0] = no_line_editing ? '\n' : '\r';
4117 temp[1] = no_line_editing ? '\0' : '\n';
4118 temp[2] = '\0';
4119 goto add_string;
4120
4121 case 's':
4122 temp = base_pathname (shell_name);
4123 temp = savestring (temp);
4124 goto add_string;
4125
4126 case 'v':
4127 case 'V':
4128 temp = (char *)xmalloc (16);
4129 if (c == 'v')
4130 strcpy (temp, dist_version);
4131 else
4132 sprintf (temp, "%s.%d", dist_version, patch_level);
4133 goto add_string;
4134
4135 case 'w':
4136 case 'W':
4137 {
4138 /* Use the value of PWD because it is much more efficient. */
4139 char t_string[PATH_MAX], *t;
4140 int tlen;
4141
4142 temp = get_string_value ("PWD");
4143
4144 if (temp == 0)
4145 {
4146 if (getcwd (t_string, sizeof(t_string)) == 0)
4147 {
4148 t_string[0] = '.';
4149 tlen = 1;
4150 }
4151 else
4152 tlen = strlen (t_string);
4153 }
4154 else
4155 {
4156 tlen = sizeof (t_string) - 1;
4157 strncpy (t_string, temp, tlen);
4158 }
4159 t_string[tlen] = '\0';
4160
4161 #define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0)
4162 #define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0)
4163 /* Abbreviate \W as ~ if $PWD == $HOME */
4164 if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0))
4165 {
4166 if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0)
4167 {
4168 t = strrchr (t_string, '/');
4169 if (t)
4170 strcpy (t_string, t + 1);
4171 }
4172 }
4173 #undef ROOT_PATH
4174 #undef DOUBLE_SLASH_ROOT
4175 else
4176 /* polite_directory_format is guaranteed to return a string
4177 no longer than PATH_MAX - 1 characters. */
4178 strcpy (t_string, polite_directory_format (t_string));
4179
4180 /* If we're going to be expanding the prompt string later,
4181 quote the directory name. */
4182 if (promptvars || posixly_correct)
4183 /* Make sure that expand_prompt_string is called with a
4184 second argument of Q_DOUBLE_QUOTES if we use this
4185 function here. */
4186 temp = sh_backslash_quote_for_double_quotes (t_string);
4187 else
4188 temp = savestring (t_string);
4189
4190 goto add_string;
4191 }
4192
4193 case 'u':
4194 if (current_user.user_name == 0)
4195 get_current_user_info ();
4196 temp = savestring (current_user.user_name);
4197 goto add_string;
4198
4199 case 'h':
4200 case 'H':
4201 temp = savestring (current_host_name);
4202 if (c == 'h' && (t = (char *)strchr (temp, '.')))
4203 *t = '\0';
4204 goto add_string;
4205
4206 case '#':
4207 temp = itos (current_command_number);
4208 goto add_string;
4209
4210 case '!':
4211 #if !defined (HISTORY)
4212 temp = savestring ("1");
4213 #else /* HISTORY */
4214 temp = itos (history_number ());
4215 #endif /* HISTORY */
4216 goto add_string;
4217
4218 case '$':
4219 t = temp = (char *)xmalloc (3);
4220 if ((promptvars || posixly_correct) && (current_user.euid != 0))
4221 *t++ = '\\';
4222 *t++ = current_user.euid == 0 ? '#' : '$';
4223 *t = '\0';
4224 goto add_string;
4225
4226 case 'j':
4227 temp = itos (count_all_jobs ());
4228 goto add_string;
4229
4230 case 'l':
4231 #if defined (HAVE_TTYNAME)
4232 temp = (char *)ttyname (fileno (stdin));
4233 t = temp ? base_pathname (temp) : "tty";
4234 temp = savestring (t);
4235 #else
4236 temp = savestring ("tty");
4237 #endif /* !HAVE_TTYNAME */
4238 goto add_string;
4239
4240 #if defined (READLINE)
4241 case '[':
4242 case ']':
4243 if (no_line_editing)
4244 {
4245 string++;
4246 break;
4247 }
4248 temp = (char *)xmalloc (3);
4249 temp[0] = CTLESC;
4250 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
4251 temp[2] = '\0';
4252 goto add_string;
4253 #endif /* READLINE */
4254
4255 case '\\':
4256 case 'a':
4257 case 'e':
4258 case 'r':
4259 temp = (char *)xmalloc (2);
4260 if (c == 'a')
4261 temp[0] = '\07';
4262 else if (c == 'e')
4263 temp[0] = '\033';
4264 else if (c == 'r')
4265 temp[0] = '\r';
4266 else /* (c == '\\') */
4267 temp[0] = c;
4268 temp[1] = '\0';
4269 goto add_string;
4270
4271 default:
4272 not_escape:
4273 temp = (char *)xmalloc (3);
4274 temp[0] = '\\';
4275 temp[1] = c;
4276 temp[2] = '\0';
4277
4278 add_string:
4279 if (c)
4280 string++;
4281 result =
4282 sub_append_string (temp, result, &result_index, &result_size);
4283 temp = (char *)NULL; /* Freed in sub_append_string (). */
4284 result[result_index] = '\0';
4285 break;
4286 }
4287 }
4288 else
4289 {
4290 RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH);
4291 result[result_index++] = c;
4292 result[result_index] = '\0';
4293 }
4294 }
4295 #else /* !PROMPT_STRING_DECODE */
4296 result = savestring (string);
4297 #endif /* !PROMPT_STRING_DECODE */
4298
4299 /* Save the delimiter stack and point `dstack' to temp space so any
4300 command substitutions in the prompt string won't result in screwing
4301 up the parser's quoting state. */
4302 save_dstack = dstack;
4303 dstack = temp_dstack;
4304 dstack.delimiter_depth = 0;
4305
4306 /* Perform variable and parameter expansion and command substitution on
4307 the prompt string. */
4308 if (promptvars || posixly_correct)
4309 {
4310 last_exit_value = last_command_exit_value;
4311 list = expand_prompt_string (result, Q_DOUBLE_QUOTES);
4312 free (result);
4313 result = string_list (list);
4314 dispose_words (list);
4315 last_command_exit_value = last_exit_value;
4316 }
4317 else
4318 {
4319 t = dequote_string (result);
4320 free (result);
4321 result = t;
4322 }
4323
4324 dstack = save_dstack;
4325
4326 return (result);
4327 }
4328
4329 /************************************************
4330 * *
4331 * ERROR HANDLING *
4332 * *
4333 ************************************************/
4334
4335 /* Report a syntax error, and restart the parser. Call here for fatal
4336 errors. */
4337 int
4338 yyerror (msg)
4339 const char *msg;
4340 {
4341 report_syntax_error ((char *)NULL);
4342 reset_parser ();
4343 return (0);
4344 }
4345
4346 static char *
4347 error_token_from_token (token)
4348 int token;
4349 {
4350 char *t;
4351
4352 if (t = find_token_in_alist (token, word_token_alist, 0))
4353 return t;
4354
4355 if (t = find_token_in_alist (token, other_token_alist, 0))
4356 return t;
4357
4358 t = (char *)NULL;
4359 /* This stuff is dicy and needs closer inspection */
4360 switch (current_token)
4361 {
4362 case WORD:
4363 case ASSIGNMENT_WORD:
4364 if (yylval.word)
4365 t = savestring (yylval.word->word);
4366 break;
4367 case NUMBER:
4368 t = itos (yylval.number);
4369 break;
4370 case ARITH_CMD:
4371 if (yylval.word_list)
4372 t = string_list (yylval.word_list);
4373 break;
4374 case ARITH_FOR_EXPRS:
4375 if (yylval.word_list)
4376 t = string_list_internal (yylval.word_list, " ; ");
4377 break;
4378 case COND_CMD:
4379 t = (char *)NULL; /* punt */
4380 break;
4381 }
4382
4383 return t;
4384 }
4385
4386 static char *
4387 error_token_from_text ()
4388 {
4389 char *msg, *t;
4390 int token_end, i;
4391
4392 t = shell_input_line;
4393 i = shell_input_line_index;
4394 token_end = 0;
4395 msg = (char *)NULL;
4396
4397 if (i && t[i] == '\0')
4398 i--;
4399
4400 while (i && (whitespace (t[i]) || t[i] == '\n'))
4401 i--;
4402
4403 if (i)
4404 token_end = i + 1;
4405
4406 while (i && (member (t[i], " \n\t;|&") == 0))
4407 i--;
4408
4409 while (i != token_end && (whitespace (t[i]) || t[i] == '\n'))
4410 i++;
4411
4412 /* Return our idea of the offending token. */
4413 if (token_end || (i == 0 && token_end == 0))
4414 {
4415 if (token_end)
4416 msg = substring (t, i, token_end);
4417 else /* one-character token */
4418 {
4419 msg = (char *)xmalloc (2);
4420 msg[0] = t[i];
4421 msg[1] = '\0';
4422 }
4423 }
4424
4425 return (msg);
4426 }
4427
4428 static void
4429 print_offending_line ()
4430 {
4431 char *msg;
4432 int token_end;
4433
4434 msg = savestring (shell_input_line);
4435 token_end = strlen (msg);
4436 while (token_end && msg[token_end - 1] == '\n')
4437 msg[--token_end] = '\0';
4438
4439 parser_error (line_number, "`%s'", msg);
4440 free (msg);
4441 }
4442
4443 /* Report a syntax error with line numbers, etc.
4444 Call here for recoverable errors. If you have a message to print,
4445 then place it in MESSAGE, otherwise pass NULL and this will figure
4446 out an appropriate message for you. */
4447 static void
4448 report_syntax_error (message)
4449 char *message;
4450 {
4451 char *msg;
4452
4453 if (message)
4454 {
4455 parser_error (line_number, "%s", message);
4456 if (interactive && EOF_Reached)
4457 EOF_Reached = 0;
4458 last_command_exit_value = EX_USAGE;
4459 return;
4460 }
4461
4462 /* If the line of input we're reading is not null, try to find the
4463 objectionable token. First, try to figure out what token the
4464 parser's complaining about by looking at current_token. */
4465 if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token)))
4466 {
4467 parser_error (line_number, _("syntax error near unexpected token `%s'"), msg);
4468 free (msg);
4469
4470 if (interactive == 0)
4471 print_offending_line ();
4472
4473 last_command_exit_value = EX_USAGE;
4474 return;
4475 }
4476
4477 /* If looking at the current token doesn't prove fruitful, try to find the
4478 offending token by analyzing the text of the input line near the current
4479 input line index and report what we find. */
4480 if (shell_input_line && *shell_input_line)
4481 {
4482 msg = error_token_from_text ();
4483 if (msg)
4484 {
4485 parser_error (line_number, _("syntax error near `%s'"), msg);
4486 free (msg);
4487 }
4488
4489 /* If not interactive, print the line containing the error. */
4490 if (interactive == 0)
4491 print_offending_line ();
4492 }
4493 else
4494 {
4495 msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error");
4496 parser_error (line_number, "%s", msg);
4497 /* When the shell is interactive, this file uses EOF_Reached
4498 only for error reporting. Other mechanisms are used to
4499 decide whether or not to exit. */
4500 if (interactive && EOF_Reached)
4501 EOF_Reached = 0;
4502 }
4503
4504 last_command_exit_value = EX_USAGE;
4505 }
4506
4507 /* ??? Needed function. ??? We have to be able to discard the constructs
4508 created during parsing. In the case of error, we want to return
4509 allocated objects to the memory pool. In the case of no error, we want
4510 to throw away the information about where the allocated objects live.
4511 (dispose_command () will actually free the command.) */
4512 static void
4513 discard_parser_constructs (error_p)
4514 int error_p;
4515 {
4516 }
4517
4518 /************************************************
4519 * *
4520 * EOF HANDLING *
4521 * *
4522 ************************************************/
4523
4524 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
4525
4526 /* A flag denoting whether or not ignoreeof is set. */
4527 int ignoreeof = 0;
4528
4529 /* The number of times that we have encountered an EOF character without
4530 another character intervening. When this gets above the limit, the
4531 shell terminates. */
4532 int eof_encountered = 0;
4533
4534 /* The limit for eof_encountered. */
4535 int eof_encountered_limit = 10;
4536
4537 /* If we have EOF as the only input unit, this user wants to leave
4538 the shell. If the shell is not interactive, then just leave.
4539 Otherwise, if ignoreeof is set, and we haven't done this the
4540 required number of times in a row, print a message. */
4541 static void
4542 handle_eof_input_unit ()
4543 {
4544 if (interactive)
4545 {
4546 /* shell.c may use this to decide whether or not to write out the
4547 history, among other things. We use it only for error reporting
4548 in this file. */
4549 if (EOF_Reached)
4550 EOF_Reached = 0;
4551
4552 /* If the user wants to "ignore" eof, then let her do so, kind of. */
4553 if (ignoreeof)
4554 {
4555 if (eof_encountered < eof_encountered_limit)
4556 {
4557 fprintf (stderr, _("Use \"%s\" to leave the shell.\n"),
4558 login_shell ? "logout" : "exit");
4559 eof_encountered++;
4560 /* Reset the parsing state. */
4561 last_read_token = current_token = '\n';
4562 /* Reset the prompt string to be $PS1. */
4563 prompt_string_pointer = (char **)NULL;
4564 prompt_again ();
4565 return;
4566 }
4567 }
4568
4569 /* In this case EOF should exit the shell. Do it now. */
4570 reset_parser ();
4571 exit_builtin ((WORD_LIST *)NULL);
4572 }
4573 else
4574 {
4575 /* We don't write history files, etc., for non-interactive shells. */
4576 EOF_Reached = 1;
4577 }
4578 }
4579
4580 /************************************************
4581 * *
4582 * STRING PARSING FUNCTIONS *
4583 * *
4584 ************************************************/
4585
4586 /* It's very important that these two functions treat the characters
4587 between ( and ) identically. */
4588
4589 static WORD_LIST parse_string_error;
4590
4591 /* Take a string and run it through the shell parser, returning the
4592 resultant word list. Used by compound array assignment. */
4593 WORD_LIST *
4594 parse_string_to_word_list (s, flags, whom)
4595 char *s;
4596 int flags;
4597 const char *whom;
4598 {
4599 WORD_LIST *wl;
4600 int tok, orig_current_token, orig_line_number, orig_input_terminator;
4601 int orig_line_count;
4602 int old_echo_input, old_expand_aliases;
4603 #if defined (HISTORY)
4604 int old_remember_on_history, old_history_expansion_inhibited;
4605 #endif
4606
4607 #if defined (HISTORY)
4608 old_remember_on_history = remember_on_history;
4609 # if defined (BANG_HISTORY)
4610 old_history_expansion_inhibited = history_expansion_inhibited;
4611 # endif
4612 bash_history_disable ();
4613 #endif
4614
4615 orig_line_number = line_number;
4616 orig_line_count = current_command_line_count;
4617 orig_input_terminator = shell_input_line_terminator;
4618 old_echo_input = echo_input_at_read;
4619 old_expand_aliases = expand_aliases;
4620
4621 push_stream (1);
4622 last_read_token = WORD; /* WORD to allow reserved words here */
4623 current_command_line_count = 0;
4624 echo_input_at_read = expand_aliases = 0;
4625
4626 with_input_from_string (s, whom);
4627 wl = (WORD_LIST *)NULL;
4628
4629 if (flags & 1)
4630 parser_state |= PST_COMPASSIGN;
4631
4632 while ((tok = read_token (READ)) != yacc_EOF)
4633 {
4634 if (tok == '\n' && *bash_input.location.string == '\0')
4635 break;
4636 if (tok == '\n') /* Allow newlines in compound assignments */
4637 continue;
4638 if (tok != WORD && tok != ASSIGNMENT_WORD)
4639 {
4640 line_number = orig_line_number + line_number - 1;
4641 orig_current_token = current_token;
4642 current_token = tok;
4643 yyerror (NULL); /* does the right thing */
4644 current_token = orig_current_token;
4645 if (wl)
4646 dispose_words (wl);
4647 wl = &parse_string_error;
4648 break;
4649 }
4650 wl = make_word_list (yylval.word, wl);
4651 }
4652
4653 last_read_token = '\n';
4654 pop_stream ();
4655
4656 #if defined (HISTORY)
4657 remember_on_history = old_remember_on_history;
4658 # if defined (BANG_HISTORY)
4659 history_expansion_inhibited = old_history_expansion_inhibited;
4660 # endif /* BANG_HISTORY */
4661 #endif /* HISTORY */
4662
4663 echo_input_at_read = old_echo_input;
4664 expand_aliases = old_expand_aliases;
4665
4666 current_command_line_count = orig_line_count;
4667 shell_input_line_terminator = orig_input_terminator;
4668
4669 if (flags & 1)
4670 parser_state &= ~PST_COMPASSIGN;
4671
4672 if (wl == &parse_string_error)
4673 {
4674 last_command_exit_value = EXECUTION_FAILURE;
4675 if (interactive_shell == 0 && posixly_correct)
4676 jump_to_top_level (FORCE_EOF);
4677 else
4678 jump_to_top_level (DISCARD);
4679 }
4680
4681 return (REVERSE_LIST (wl, WORD_LIST *));
4682 }
4683
4684 static char *
4685 parse_compound_assignment (retlenp)
4686 int *retlenp;
4687 {
4688 WORD_LIST *wl, *rl;
4689 int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
4690 char *saved_token, *ret;
4691
4692 saved_token = token;
4693 orig_token_size = token_buffer_size;
4694 orig_line_number = line_number;
4695 orig_last_token = last_read_token;
4696
4697 last_read_token = WORD; /* WORD to allow reserved words here */
4698
4699 token = (char *)NULL;
4700 token_buffer_size = 0;
4701
4702 assignok = parser_state&PST_ASSIGNOK; /* XXX */
4703
4704 wl = (WORD_LIST *)NULL; /* ( */
4705 parser_state |= PST_COMPASSIGN;
4706
4707 while ((tok = read_token (READ)) != ')')
4708 {
4709 if (tok == '\n') /* Allow newlines in compound assignments */
4710 {
4711 if (SHOULD_PROMPT ())
4712 prompt_again ();
4713 continue;
4714 }
4715 if (tok != WORD && tok != ASSIGNMENT_WORD)
4716 {
4717 current_token = tok; /* for error reporting */
4718 if (tok == yacc_EOF) /* ( */
4719 parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'"));
4720 else
4721 yyerror(NULL); /* does the right thing */
4722 if (wl)
4723 dispose_words (wl);
4724 wl = &parse_string_error;
4725 break;
4726 }
4727 wl = make_word_list (yylval.word, wl);
4728 }
4729
4730 FREE (token);
4731 token = saved_token;
4732 token_buffer_size = orig_token_size;
4733
4734 parser_state &= ~PST_COMPASSIGN;
4735
4736 if (wl == &parse_string_error)
4737 {
4738 last_command_exit_value = EXECUTION_FAILURE;
4739 last_read_token = '\n'; /* XXX */
4740 if (interactive_shell == 0 && posixly_correct)
4741 jump_to_top_level (FORCE_EOF);
4742 else
4743 jump_to_top_level (DISCARD);
4744 }
4745
4746 last_read_token = orig_last_token; /* XXX - was WORD? */
4747
4748 if (wl)
4749 {
4750 rl = REVERSE_LIST (wl, WORD_LIST *);
4751 ret = string_list (rl);
4752 dispose_words (rl);
4753 }
4754 else
4755 ret = (char *)NULL;
4756
4757 if (retlenp)
4758 *retlenp = (ret && *ret) ? strlen (ret) : 0;
4759
4760 if (assignok)
4761 parser_state |= PST_ASSIGNOK;
4762
4763 return ret;
4764 }
4765
4766 /************************************************
4767 * *
4768 * SAVING AND RESTORING PARTIAL PARSE STATE *
4769 * *
4770 ************************************************/
4771
4772 sh_parser_state_t *
4773 save_parser_state (ps)
4774 sh_parser_state_t *ps;
4775 {
4776 #if defined (ARRAY_VARS)
4777 SHELL_VAR *v;
4778 #endif
4779
4780 if (ps == 0)
4781 ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t));
4782 if (ps == 0)
4783 return ((sh_parser_state_t *)NULL);
4784
4785 ps->parser_state = parser_state;
4786 ps->token_state = save_token_state ();
4787
4788 ps->input_line_terminator = shell_input_line_terminator;
4789 ps->eof_encountered = eof_encountered;
4790
4791 ps->current_command_line_count = current_command_line_count;
4792
4793 #if defined (HISTORY)
4794 ps->remember_on_history = remember_on_history;
4795 # if defined (BANG_HISTORY)
4796 ps->history_expansion_inhibited = history_expansion_inhibited;
4797 # endif
4798 #endif
4799
4800 ps->last_command_exit_value = last_command_exit_value;
4801 #if defined (ARRAY_VARS)
4802 v = find_variable ("PIPESTATUS");
4803 if (v && array_p (v) && array_cell (v))
4804 ps->pipestatus = array_copy (array_cell (v));
4805 else
4806 ps->pipestatus = (ARRAY *)NULL;
4807 #endif
4808
4809 ps->last_shell_builtin = last_shell_builtin;
4810 ps->this_shell_builtin = this_shell_builtin;
4811
4812 ps->expand_aliases = expand_aliases;
4813 ps->echo_input_at_read = echo_input_at_read;
4814
4815 return (ps);
4816 }
4817
4818 void
4819 restore_parser_state (ps)
4820 sh_parser_state_t *ps;
4821 {
4822 #if defined (ARRAY_VARS)
4823 SHELL_VAR *v;
4824 #endif
4825
4826 if (ps == 0)
4827 return;
4828
4829 parser_state = ps->parser_state;
4830 if (ps->token_state)
4831 {
4832 restore_token_state (ps->token_state);
4833 free (ps->token_state);
4834 }
4835
4836 shell_input_line_terminator = ps->input_line_terminator;
4837 eof_encountered = ps->eof_encountered;
4838
4839 current_command_line_count = ps->current_command_line_count;
4840
4841 #if defined (HISTORY)
4842 remember_on_history = ps->remember_on_history;
4843 # if defined (BANG_HISTORY)
4844 history_expansion_inhibited = ps->history_expansion_inhibited;
4845 # endif
4846 #endif
4847
4848 last_command_exit_value = ps->last_command_exit_value;
4849 #if defined (ARRAY_VARS)
4850 v = find_variable ("PIPESTATUS");
4851 if (v && array_p (v) && array_cell (v))
4852 {
4853 array_dispose (array_cell (v));
4854 var_setarray (v, ps->pipestatus);
4855 }
4856 #endif
4857
4858 last_shell_builtin = ps->last_shell_builtin;
4859 this_shell_builtin = ps->this_shell_builtin;
4860
4861 expand_aliases = ps->expand_aliases;
4862 echo_input_at_read = ps->echo_input_at_read;
4863 }
4864
4865 /************************************************
4866 * *
4867 * MULTIBYTE CHARACTER HANDLING *
4868 * *
4869 ************************************************/
4870
4871 #if defined (HANDLE_MULTIBYTE)
4872 static void
4873 set_line_mbstate ()
4874 {
4875 int i, previ, len, c;
4876 mbstate_t mbs, prevs;
4877 size_t mbclen;
4878
4879 if (shell_input_line == NULL)
4880 return;
4881 len = strlen (shell_input_line); /* XXX - shell_input_line_len ? */
4882 FREE (shell_input_line_property);
4883 shell_input_line_property = (char *)xmalloc (len + 1);
4884
4885 memset (&prevs, '\0', sizeof (mbstate_t));
4886 for (i = previ = 0; i < len; i++)
4887 {
4888 mbs = prevs;
4889
4890 c = shell_input_line[i];
4891 if (c == EOF)
4892 {
4893 int j;
4894 for (j = i; j < len; j++)
4895 shell_input_line_property[j] = 1;
4896 break;
4897 }
4898
4899 mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs);
4900 if (mbclen == 1 || mbclen == (size_t)-1)
4901 {
4902 mbclen = 1;
4903 previ = i + 1;
4904 }
4905 else if (mbclen == (size_t)-2)
4906 mbclen = 0;
4907 else if (mbclen > 1)
4908 {
4909 mbclen = 0;
4910 previ = i + 1;
4911 prevs = mbs;
4912 }
4913 else
4914 {
4915 /* XXX - what to do if mbrlen returns 0? (null wide character) */
4916 int j;
4917 for (j = i; j < len; j++)
4918 shell_input_line_property[j] = 1;
4919 break;
4920 }
4921
4922 shell_input_line_property[i] = mbclen;
4923 }
4924 }
4925 #endif /* HANDLE_MULTIBYTE */