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