1 /* Yacc grammar for bash. */
2
3 /* Copyright (C) 1989 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 %{
22 #include <stdio.h>
23 #include "bashtypes.h"
24 #include <signal.h>
25 #include "bashansi.h"
26 #include "shell.h"
27 #include "flags.h"
28 #include "input.h"
29
30 #if defined (READLINE)
31 # include <readline/readline.h>
32 #endif /* READLINE */
33
34 #if defined (HISTORY)
35 # include "bashhist.h"
36 # include <readline/history.h>
37 #endif /* HISTORY */
38
39 #if defined (JOB_CONTROL)
40 # include "jobs.h"
41 #endif /* JOB_CONTROL */
42
43 #if defined (ALIAS)
44 # include "alias.h"
45 #endif /* ALIAS */
46
47 #if defined (PROMPT_STRING_DECODE)
48 #include <sys/param.h>
49 #include <time.h>
50 #include "maxpath.h"
51 #endif /* PROMPT_STRING_DECODE */
52
53 #define YYDEBUG 1
54 extern int eof_encountered;
55 extern int no_line_editing;
56 extern int current_command_number;
57 extern int interactive, interactive_shell, login_shell;
58 extern int posixly_correct;
59 extern int last_command_exit_value;
60 extern int interrupt_immediately;
61 extern char *shell_name, *current_host_name;
62 extern Function *last_shell_builtin, *this_shell_builtin;
63 #if defined (READLINE)
64 extern int bash_readline_initialized;
65 #endif
66 #if defined (BUFFERED_INPUT)
67 extern int bash_input_fd_changed;
68 #endif
69
70 /* **************************************************************** */
71 /* */
72 /* "Forward" declarations */
73 /* */
74 /* **************************************************************** */
75
76 /* This is kind of sickening. In order to let these variables be seen by
77 all the functions that need them, I am forced to place their declarations
78 far away from the place where they should logically be found. */
79
80 static int reserved_word_acceptable ();
81 static int read_token ();
82
83 static void report_syntax_error ();
84 static void handle_eof_input_unit ();
85 static void prompt_again ();
86 static void reset_readline_prompt ();
87 static void print_prompt ();
88
89 /* PROMPT_STRING_POINTER points to one of these, never to an actual string. */
90 char *ps1_prompt, *ps2_prompt;
91
92 /* Handle on the current prompt string. Indirectly points through
93 ps1_ or ps2_prompt. */
94 char **prompt_string_pointer = (char **)NULL;
95 char *current_prompt_string;
96
97 /* The decoded prompt string. Used if READLINE is not defined or if
98 editing is turned off. Analogous to current_readline_prompt. */
99 static char *current_decoded_prompt;
100
101 /* The number of lines read from input while creating the current command. */
102 int current_command_line_count = 0;
103
104 /* Variables to manage the task of reading here documents, because we need to
105 defer the reading until after a complete command has been collected. */
106 static REDIRECT *redir_stack[10];
107 int need_here_doc = 0;
108
109 /* Where shell input comes from. History expansion is performed on each
110 line when the shell is interactive. */
111 static char *shell_input_line = (char *)NULL;
112 static int shell_input_line_index = 0;
113 static int shell_input_line_size = 0; /* Amount allocated for shell_input_line. */
114 static int shell_input_line_len = 0; /* strlen (shell_input_line) */
115
116 /* Either zero or EOF. */
117 static int shell_input_line_terminator = 0;
118
119 static REDIRECTEE redir;
120 %}
121
122 %union {
123 WORD_DESC *word; /* the word that we read. */
124 int number; /* the number that we read. */
125 WORD_LIST *word_list;
126 COMMAND *command;
127 REDIRECT *redirect;
128 ELEMENT element;
129 PATTERN_LIST *pattern;
130 }
131
132 /* Reserved words. Members of the first group are only recognized
133 in the case that they are preceded by a list_terminator. Members
134 of the second group are recognized only under special circumstances. */
135 %token IF THEN ELSE ELIF FI CASE ESAC FOR SELECT WHILE UNTIL DO DONE FUNCTION
136 %token IN BANG
137
138 /* More general tokens. yylex () knows how to make these. */
139 %token <word> WORD ASSIGNMENT_WORD
140 %token <number> NUMBER
141 %token AND_AND OR_OR GREATER_GREATER LESS_LESS LESS_AND
142 %token GREATER_AND SEMI_SEMI LESS_LESS_MINUS AND_GREATER LESS_GREATER
143 %token GREATER_BAR
144
145 /* The types that the various syntactical units return. */
146
147 %type <command> inputunit command pipeline
148 %type <command> list list0 list1 simple_list simple_list1
149 %type <command> simple_command shell_command_1 shell_command select_command
150 %type <command> group_command function_def if_command elif_clause subshell
151 %type <redirect> redirection redirections
152 %type <element> simple_command_element
153 %type <word_list> words pattern
154 %type <pattern> pattern_list case_clause_sequence case_clause_1 pattern_list_1
155
156 %start inputunit
157
158 %left '&' ';' '\n' yacc_EOF
159 %left AND_AND OR_OR
160 %right '|'
161 %%
162
163 inputunit: simple_list '\n'
164 {
165 /* Case of regular command. Discard the error
166 safety net,and return the command just parsed. */
167 global_command = $1;
168 eof_encountered = 0;
169 discard_parser_constructs (0);
170 YYACCEPT;
171 }
172 | '\n'
173 {
174 /* Case of regular command, but not a very
175 interesting one. Return a NULL command. */
176 global_command = (COMMAND *)NULL;
177 YYACCEPT;
178 }
179 |
180 error '\n'
181 {
182 /* Error during parsing. Return NULL command. */
183 global_command = (COMMAND *)NULL;
184 eof_encountered = 0;
185 discard_parser_constructs (1);
186 if (interactive)
187 {
188 YYACCEPT;
189 }
190 else
191 {
192 YYABORT;
193 }
194 }
195 | yacc_EOF
196 {
197 /* Case of EOF seen by itself. Do ignoreeof or
198 not. */
199 global_command = (COMMAND *)NULL;
200 handle_eof_input_unit ();
201 YYACCEPT;
202 }
203 ;
204
205 words:
206 { $$ = (WORD_LIST *)NULL; }
207 | words WORD
208 { $$ = make_word_list ($2, $1); }
209 ;
210
211 redirection: '>' WORD
212 {
213 redir.filename = $2;
214 $$ = make_redirection (1, r_output_direction, redir);
215 }
216 | '<' WORD
217 {
218 redir.filename = $2;
219 $$ = make_redirection (0, r_input_direction, redir);
220 }
221 | NUMBER '>' WORD
222 {
223 redir.filename = $3;
224 $$ = make_redirection ($1, r_output_direction, redir);
225 }
226 | NUMBER '<' WORD
227 {
228 redir.filename = $3;
229 $$ = make_redirection ($1, r_input_direction, redir);
230 }
231 | GREATER_GREATER WORD
232 {
233 redir.filename = $2;
234 $$ = make_redirection (1, r_appending_to, redir);
235 }
236 | NUMBER GREATER_GREATER WORD
237 {
238 redir.filename = $3;
239 $$ = make_redirection ($1, r_appending_to, redir);
240 }
241 | LESS_LESS WORD
242 {
243 redir.filename = $2;
244 $$ = make_redirection (0, r_reading_until, redir);
245 redir_stack[need_here_doc++] = $$;
246 }
247 | NUMBER LESS_LESS WORD
248 {
249 redir.filename = $3;
250 $$ = make_redirection ($1, r_reading_until, redir);
251 redir_stack[need_here_doc++] = $$;
252 }
253 | LESS_AND NUMBER
254 {
255 redir.dest = $2;
256 $$ = make_redirection (0, r_duplicating_input, redir);
257 }
258 | NUMBER LESS_AND NUMBER
259 {
260 redir.dest = $3;
261 $$ = make_redirection ($1, r_duplicating_input, redir);
262 }
263 | GREATER_AND NUMBER
264 {
265 redir.dest = $2;
266 $$ = make_redirection (1, r_duplicating_output, redir);
267 }
268 | NUMBER GREATER_AND NUMBER
269 {
270 redir.dest = $3;
271 $$ = make_redirection ($1, r_duplicating_output, redir);
272 }
273 | LESS_AND WORD
274 {
275 redir.filename = $2;
276 $$ = make_redirection (0, r_duplicating_input_word, redir);
277 }
278 | NUMBER LESS_AND WORD
279 {
280 redir.filename = $3;
281 $$ = make_redirection ($1, r_duplicating_input_word, redir);
282 }
283 | GREATER_AND WORD
284 {
285 redir.filename = $2;
286 $$ = make_redirection (1, r_duplicating_output_word, redir);
287 }
288 | NUMBER GREATER_AND WORD
289 {
290 redir.filename = $3;
291 $$ = make_redirection ($1, r_duplicating_output_word, redir);
292 }
293 | LESS_LESS_MINUS WORD
294 {
295 redir.filename = $2;
296 $$ = make_redirection
297 (0, r_deblank_reading_until, redir);
298 redir_stack[need_here_doc++] = $$;
299 }
300 | NUMBER LESS_LESS_MINUS WORD
301 {
302 redir.filename = $3;
303 $$ = make_redirection
304 ($1, r_deblank_reading_until, redir);
305 redir_stack[need_here_doc++] = $$;
306 }
307 | GREATER_AND '-'
308 {
309 redir.dest = 0L;
310 $$ = make_redirection (1, r_close_this, redir);
311 }
312 | NUMBER GREATER_AND '-'
313 {
314 redir.dest = 0L;
315 $$ = make_redirection ($1, r_close_this, redir);
316 }
317 | LESS_AND '-'
318 {
319 redir.dest = 0L;
320 $$ = make_redirection (0, r_close_this, redir);
321 }
322 | NUMBER LESS_AND '-'
323 {
324 redir.dest = 0L;
325 $$ = make_redirection ($1, r_close_this, redir);
326 }
327 | AND_GREATER WORD
328 {
329 redir.filename = $2;
330 $$ = make_redirection (1, r_err_and_out, redir);
331 }
332 | NUMBER LESS_GREATER WORD
333 {
334 redir.filename = $3;
335 $$ = make_redirection ($1, r_input_output, redir);
336 }
337 | LESS_GREATER WORD
338 {
339 REDIRECT *t1, *t2;
340
341 redir.filename = $2;
342 if (posixly_correct)
343 $$ = make_redirection (0, r_input_output, redir);
344 else
345 {
346 t1 = make_redirection (0, r_input_direction, redir);
347 redir.filename = copy_word ($2);
348 t2 = make_redirection (1, r_output_direction, redir);
349 t1->next = t2;
350 $$ = t1;
351 }
352 }
353 | GREATER_BAR WORD
354 {
355 redir.filename = $2;
356 $$ = make_redirection (1, r_output_force, redir);
357 }
358 | NUMBER GREATER_BAR WORD
359 {
360 redir.filename = $3;
361 $$ = make_redirection ($1, r_output_force, redir);
362 }
363 ;
364
365 simple_command_element: WORD
366 { $$.word = $1; $$.redirect = 0; }
367 | ASSIGNMENT_WORD
368 { $$.word = $1; $$.redirect = 0; }
369 | redirection
370 { $$.redirect = $1; $$.word = 0; }
371 ;
372
373 redirections: redirection
374 {
375 $$ = $1;
376 }
377 | redirections redirection
378 {
379 register REDIRECT *t = $1;
380
381 while (t->next)
382 t = t->next;
383 t->next = $2;
384 $$ = $1;
385 }
386 ;
387
388 simple_command: simple_command_element
389 { $$ = make_simple_command ($1, (COMMAND *)NULL); }
390 | simple_command simple_command_element
391 { $$ = make_simple_command ($2, $1); }
392 ;
393
394 command: simple_command
395 { $$ = clean_simple_command ($1); }
396 | shell_command
397 { $$ = $1; }
398 ;
399
400 shell_command: shell_command_1
401 { $$ = $1; }
402 | shell_command_1 redirections
403 {
404 if ($1->redirects)
405 {
406 register REDIRECT *t;
407 for (t = $1->redirects; t->next; t = t->next)
408 ;
409 t->next = $2;
410 }
411 else
412 $1->redirects = $2;
413 $$ = $1;
414 }
415 ;
416
417 shell_command_1: FOR WORD newlines DO list DONE
418 { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5); }
419 | FOR WORD newlines '{' list '}'
420 { $$ = make_for_command ($2, add_string_to_list ("$@", (WORD_LIST *)NULL), $5); }
421 | FOR WORD ';' newlines DO list DONE
422 { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6); }
423 | FOR WORD ';' newlines '{' list '}'
424 { $$ = make_for_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6); }
425 | FOR WORD newlines IN words list_terminator newlines DO list DONE
426 { $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9); }
427 | FOR WORD newlines IN words list_terminator newlines '{' list '}'
428 { $$ = make_for_command ($2, REVERSE_LIST ($5, WORD_LIST *), $9); }
429
430 | CASE WORD newlines IN newlines ESAC
431 { $$ = make_case_command ($2, (PATTERN_LIST *)NULL); }
432 | CASE WORD newlines IN case_clause_sequence newlines ESAC
433 { $$ = make_case_command ($2, $5); }
434 | CASE WORD newlines IN case_clause_1 ESAC
435 { $$ = make_case_command ($2, $5); }
436 | WHILE list DO list DONE
437 { $$ = make_while_command ($2, $4); }
438 | UNTIL list DO list DONE
439 { $$ = make_until_command ($2, $4); }
440 | select_command
441 { $$ = $1; }
442 | if_command
443 { $$ = $1; }
444 | subshell
445 { $$ = $1; }
446 | group_command
447 { $$ = $1; }
448 | function_def
449 { $$ = $1; }
450 ;
451
452 select_command: SELECT WORD newlines DO list DONE
453 {
454 #if defined (SELECT_COMMAND)
455 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $5);
456 #endif
457 }
458 | SELECT WORD newlines '{' list '}'
459 {
460 #if defined (SELECT_COMMAND)
461 $$ = make_select_command ($2, add_string_to_list ("$@", (WORD_LIST *)NULL), $5);
462 #endif
463 }
464 | SELECT WORD ';' newlines DO list DONE
465 {
466 #if defined (SELECT_COMMAND)
467 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6);
468 #endif
469 }
470 | SELECT WORD ';' newlines '{' list '}'
471 {
472 #if defined (SELECT_COMMAND)
473 $$ = make_select_command ($2, add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), $6);
474 #endif
475 }
476 | SELECT WORD newlines IN words list_terminator newlines DO list DONE
477 {
478 #if defined (SELECT_COMMAND)
479 $$ = make_select_command ($2, (WORD_LIST *)reverse_list ($5), $9);
480 #endif
481 }
482 | SELECT WORD newlines IN words list_terminator newlines '{' list '}'
483 {
484 #if defined (SELECT_COMMAND)
485 $$ = make_select_command ($2, (WORD_LIST *)reverse_list ($5), $9);
486 #endif
487 }
488 ;
489
490 function_def: WORD '(' ')' newlines group_command
491 { $$ = make_function_def ($1, $5); }
492
493 | WORD '(' ')' newlines group_command redirections
494 { $5->redirects = $6; $$ = make_function_def ($1, $5); }
495
496 | FUNCTION WORD '(' ')' newlines group_command
497 { $$ = make_function_def ($2, $6); }
498
499 | FUNCTION WORD '(' ')' newlines group_command redirections
500 { $6->redirects = $7; $$ = make_function_def ($2, $6); }
501
502 | FUNCTION WORD newlines group_command
503 { $$ = make_function_def ($2, $4); }
504
505 | FUNCTION WORD newlines group_command redirections
506 { $4->redirects = $5; $$ = make_function_def ($2, $4); }
507 ;
508
509 subshell: '(' list ')'
510 { $2->flags |= CMD_WANT_SUBSHELL; $$ = $2; }
511 ;
512
513 if_command: IF list THEN list FI
514 { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
515 | IF list THEN list ELSE list FI
516 { $$ = make_if_command ($2, $4, $6); }
517 | IF list THEN list elif_clause FI
518 { $$ = make_if_command ($2, $4, $5); }
519 ;
520
521
522 group_command: '{' list '}'
523 { $$ = make_group_command ($2); }
524 ;
525
526 elif_clause: ELIF list THEN list
527 { $$ = make_if_command ($2, $4, (COMMAND *)NULL); }
528 | ELIF list THEN list ELSE list
529 { $$ = make_if_command ($2, $4, $6); }
530 | ELIF list THEN list elif_clause
531 { $$ = make_if_command ($2, $4, $5); }
532 ;
533
534 case_clause_1: pattern_list_1
535 | case_clause_sequence pattern_list_1
536 { $2->next = $1; $$ = $2; }
537 ;
538
539 pattern_list_1: newlines pattern ')' list
540 { $$ = make_pattern_list ($2, $4); }
541 | newlines pattern ')' newlines
542 { $$ = make_pattern_list ($2, (COMMAND *)NULL); }
543 | newlines '(' pattern ')' list
544 { $$ = make_pattern_list ($3, $5); }
545 | newlines '(' pattern ')' newlines
546 { $$ = make_pattern_list ($3, (COMMAND *)NULL); }
547 ;
548
549 case_clause_sequence: pattern_list
550 | case_clause_sequence pattern_list
551 { $2->next = $1; $$ = $2; }
552 ;
553
554 pattern_list: newlines pattern ')' list SEMI_SEMI
555 { $$ = make_pattern_list ($2, $4); }
556 | newlines pattern ')' newlines SEMI_SEMI
557 { $$ = make_pattern_list ($2, (COMMAND *)NULL); }
558 | newlines '(' pattern ')' list SEMI_SEMI
559 { $$ = make_pattern_list ($3, $5); }
560 | newlines '(' pattern ')' newlines SEMI_SEMI
561 { $$ = make_pattern_list ($3, (COMMAND *)NULL); }
562 ;
563
564 pattern: WORD
565 { $$ = make_word_list ($1, (WORD_LIST *)NULL); }
566 | pattern '|' WORD
567 { $$ = make_word_list ($3, $1); }
568 ;
569
570 /* A list allows leading or trailing newlines and
571 newlines as operators (equivalent to semicolons).
572 It must end with a newline or semicolon.
573 Lists are used within commands such as if, for, while. */
574
575 list: newlines list0
576 {
577 $$ = $2;
578 if (need_here_doc)
579 gather_here_documents ();
580 }
581 ;
582
583 list0: list1
584 | list1 '\n' newlines
585 | list1 '&' newlines
586 {
587 if ($1->type == cm_connection)
588 $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
589 else
590 $$ = command_connect ($1, (COMMAND *)NULL, '&');
591 }
592 | list1 ';' newlines
593
594 ;
595
596 list1: list1 AND_AND newlines list1
597 { $$ = command_connect ($1, $4, AND_AND); }
598 | list1 OR_OR newlines list1
599 { $$ = command_connect ($1, $4, OR_OR); }
600 | list1 '&' newlines list1
601 {
602 if ($1->type == cm_connection)
603 $$ = connect_async_list ($1, $4, '&');
604 else
605 $$ = command_connect ($1, $4, '&');
606 }
607 | list1 ';' newlines list1
608 { $$ = command_connect ($1, $4, ';'); }
609 | list1 '\n' newlines list1
610 { $$ = command_connect ($1, $4, ';'); }
611 | pipeline
612 { $$ = $1; }
613 | BANG pipeline
614 {
615 $2->flags |= CMD_INVERT_RETURN;
616 $$ = $2;
617 }
618 ;
619
620 list_terminator:'\n'
621 | ';'
622 | yacc_EOF
623 ;
624
625 newlines:
626 | newlines '\n'
627 ;
628
629 /* A simple_list is a list that contains no significant newlines
630 and no leading or trailing newlines. Newlines are allowed
631 only following operators, where they are not significant.
632
633 This is what an inputunit consists of. */
634
635 simple_list: simple_list1
636 {
637 $$ = $1;
638 if (need_here_doc)
639 gather_here_documents ();
640 }
641 | simple_list1 '&'
642 {
643 if ($1->type == cm_connection)
644 $$ = connect_async_list ($1, (COMMAND *)NULL, '&');
645 else
646 $$ = command_connect ($1, (COMMAND *)NULL, '&');
647 if (need_here_doc)
648 gather_here_documents ();
649 }
650 | simple_list1 ';'
651 {
652 $$ = $1;
653 if (need_here_doc)
654 gather_here_documents ();
655 }
656 ;
657
658 simple_list1: simple_list1 AND_AND newlines simple_list1
659 { $$ = command_connect ($1, $4, AND_AND); }
660 | simple_list1 OR_OR newlines simple_list1
661 { $$ = command_connect ($1, $4, OR_OR); }
662 | simple_list1 '&' simple_list1
663 {
664 if ($1->type == cm_connection)
665 $$ = connect_async_list ($1, $3, '&');
666 else
667 $$ = command_connect ($1, $3, '&');
668 }
669 | simple_list1 ';' simple_list1
670 { $$ = command_connect ($1, $3, ';'); }
671 | pipeline
672 { $$ = $1; }
673 | BANG pipeline
674 {
675 $2->flags |= CMD_INVERT_RETURN;
676 $$ = $2;
677 }
678 ;
679
680 pipeline:
681 pipeline '|' newlines pipeline
682 { $$ = command_connect ($1, $4, '|'); }
683 | command
684 { $$ = $1; }
685 ;
686 %%
687
688 /* Initial size to allocate for tokens, and the
689 amount to grow them by. */
690 #define TOKEN_DEFAULT_GROW_SIZE 512
691
692 /* The token currently being read. */
693 static int current_token = 0;
694
695 /* The last read token, or NULL. read_token () uses this for context
696 checking. */
697 static int last_read_token = 0;
698
699 /* The token read prior to last_read_token. */
700 static int token_before_that = 0;
701
702 /* If non-zero, it is the token that we want read_token to return
703 regardless of what text is (or isn't) present to be read. This
704 is reset by read_token. */
705 static int token_to_read = 0;
706
707 /* Global var is non-zero when end of file has been reached. */
708 int EOF_Reached = 0;
709
710 /* yy_getc () returns the next available character from input or EOF.
711 yy_ungetc (c) makes `c' the next character to read.
712 init_yy_io (get, unget, type, location) makes the function GET the
713 installed function for getting the next character, makes UNGET the
714 installed function for un-getting a character, sets the type of stream
715 (either string or file) from TYPE, and makes LOCATION point to where
716 the input is coming from. */
717
718 /* Unconditionally returns end-of-file. */
return_EOF()719 return_EOF ()
720 {
721 return (EOF);
722 }
723
724 /* Variable containing the current get and unget functions.
725 See ./input.h for a clearer description. */
726 BASH_INPUT bash_input;
727
728 /* Set all of the fields in BASH_INPUT to NULL. */
729 void
initialize_bash_input()730 initialize_bash_input ()
731 {
732 bash_input.type = 0;
733 bash_input.name = (char *)NULL;
734 bash_input.location.file = (FILE *)NULL;
735 bash_input.location.string = (char *)NULL;
736 bash_input.getter = (Function *)NULL;
737 bash_input.ungetter = (Function *)NULL;
738 }
739
740 /* Set the contents of the current bash input stream from
741 GET, UNGET, TYPE, NAME, and LOCATION. */
742 void
init_yy_io(get,unget,type,name,location)743 init_yy_io (get, unget, type, name, location)
744 Function *get, *unget;
745 int type;
746 char *name;
747 INPUT_STREAM location;
748 {
749 bash_input.type = type;
750 FREE (bash_input.name);
751
752 if (name)
753 bash_input.name = savestring (name);
754 else
755 bash_input.name = (char *)NULL;
756
757 #if defined (CRAY)
758 memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location));
759 #else
760 bash_input.location = location;
761 #endif
762 bash_input.getter = get;
763 bash_input.ungetter = unget;
764 }
765
766 /* Call this to get the next character of input. */
yy_getc()767 yy_getc ()
768 {
769 return (*(bash_input.getter)) ();
770 }
771
772 /* Call this to unget C. That is, to make C the next character
773 to be read. */
yy_ungetc(c)774 yy_ungetc (c)
775 int c;
776 {
777 return (*(bash_input.ungetter)) (c);
778 }
779
780 #if defined (BUFFERED_INPUT)
781 int
input_file_descriptor()782 input_file_descriptor ()
783 {
784 switch (bash_input.type)
785 {
786 case st_stream:
787 return (fileno (bash_input.location.file));
788 case st_bstream:
789 return (bash_input.location.buffered_fd);
790 default:
791 return (fileno (stdin));
792 }
793 }
794 #endif /* BUFFERED_INPUT */
795
796 /* **************************************************************** */
797 /* */
798 /* Let input be read from readline (). */
799 /* */
800 /* **************************************************************** */
801
802 #if defined (READLINE)
803 char *current_readline_prompt = (char *)NULL;
804 char *current_readline_line = (char *)NULL;
805 int current_readline_line_index = 0;
806
807 static int
yy_readline_get()808 yy_readline_get ()
809 {
810 if (!current_readline_line)
811 {
812 SigHandler *old_sigint;
813 int line_len;
814
815 if (!bash_readline_initialized)
816 initialize_readline ();
817
818 #if defined (JOB_CONTROL)
819 if (job_control)
820 give_terminal_to (shell_pgrp);
821 #endif /* JOB_CONTROL */
822
823 if (signal_is_ignored (SIGINT) == 0)
824 {
825 old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
826 interrupt_immediately++;
827 }
828
829 if (!current_readline_prompt)
830 current_readline_line = readline ("");
831 else
832 current_readline_line = readline (current_readline_prompt);
833
834 if (signal_is_ignored (SIGINT) == 0)
835 {
836 interrupt_immediately--;
837 set_signal_handler (SIGINT, old_sigint);
838 }
839
840 /* Reset the prompt to whatever is in the decoded value of
841 prompt_string_pointer. */
842 reset_readline_prompt ();
843
844 current_readline_line_index = 0;
845
846 if (!current_readline_line)
847 return (EOF);
848
849 line_len = strlen (current_readline_line);
850 current_readline_line = xrealloc (current_readline_line, 2 + line_len);
851 current_readline_line[line_len++] = '\n';
852 current_readline_line[line_len] = '\0';
853 }
854
855 if (!current_readline_line[current_readline_line_index])
856 {
857 free (current_readline_line);
858 current_readline_line = (char *)NULL;
859 return (yy_readline_get ());
860 }
861 else
862 {
863 int c = (unsigned char)current_readline_line[current_readline_line_index++];
864 return (c);
865 }
866 }
867
868 static int
yy_readline_unget(c)869 yy_readline_unget (c)
870 {
871 if (current_readline_line_index && current_readline_line)
872 current_readline_line[--current_readline_line_index] = c;
873 return (c);
874 }
875
876 void
with_input_from_stdin()877 with_input_from_stdin ()
878 {
879 INPUT_STREAM location;
880
881 if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0)
882 {
883 location.string = current_readline_line;
884 init_yy_io (yy_readline_get, yy_readline_unget,
885 st_stdin, "readline stdin", location);
886 }
887 }
888
889 #else /* !READLINE */
890
891 void
with_input_from_stdin()892 with_input_from_stdin ()
893 {
894 with_input_from_stream (stdin, "stdin");
895 }
896 #endif /* !READLINE */
897
898 /* **************************************************************** */
899 /* */
900 /* Let input come from STRING. STRING is zero terminated. */
901 /* */
902 /* **************************************************************** */
903
904 static int
yy_string_get()905 yy_string_get ()
906 {
907 register unsigned char *string;
908 register int c;
909
910 string = bash_input.location.string;
911 c = EOF;
912
913 /* If the string doesn't exist, or is empty, EOF found. */
914 if (string && *string)
915 {
916 c = *string++;
917 bash_input.location.string = string;
918 }
919 return (c);
920 }
921
922 static int
yy_string_unget(c)923 yy_string_unget (c)
924 int c;
925 {
926 *(--bash_input.location.string) = c;
927 return (c);
928 }
929
930 void
with_input_from_string(string,name)931 with_input_from_string (string, name)
932 char *string;
933 char *name;
934 {
935 INPUT_STREAM location;
936
937 location.string = string;
938
939 init_yy_io (yy_string_get, yy_string_unget, st_string, name, location);
940 }
941
942 /* **************************************************************** */
943 /* */
944 /* Let input come from STREAM. */
945 /* */
946 /* **************************************************************** */
947
948 static int
yy_stream_get()949 yy_stream_get ()
950 {
951 int result = EOF;
952
953 if (bash_input.location.file)
954 #if defined (NO_READ_RESTART_ON_SIGNAL)
955 result = (unsigned char)getc_with_restart (bash_input.location.file);
956 #else
957 result = (unsigned char)getc (bash_input.location.file);
958 #endif /* !NO_READ_RESTART_ON_SIGNAL */
959 return (result);
960 }
961
962 static int
yy_stream_unget(c)963 yy_stream_unget (c)
964 int c;
965 {
966 #if defined (NO_READ_RESTART_ON_SIGNAL)
967 return (ungetc_with_restart (c, bash_input.location.file));
968 #else
969 return (ungetc (c, bash_input.location.file));
970 #endif
971 }
972
973 void
with_input_from_stream(stream,name)974 with_input_from_stream (stream, name)
975 FILE *stream;
976 char *name;
977 {
978 INPUT_STREAM location;
979
980 location.file = stream;
981 init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location);
982 }
983
984 typedef struct stream_saver {
985 struct stream_saver *next;
986 BASH_INPUT bash_input;
987 int line;
988 #if defined (BUFFERED_INPUT)
989 BUFFERED_STREAM *bstream;
990 #endif /* BUFFERED_INPUT */
991 } STREAM_SAVER;
992
993 /* The globally known line number. */
994 int line_number = 0;
995
996 STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL;
997
push_stream()998 push_stream ()
999 {
1000 STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER));
1001
1002 xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT));
1003
1004 #if defined (BUFFERED_INPUT)
1005 saver->bstream = (BUFFERED_STREAM *)NULL;
1006 /* If we have a buffered stream, clear out buffers[fd]. */
1007 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1008 {
1009 saver->bstream = buffers[bash_input.location.buffered_fd];
1010 buffers[bash_input.location.buffered_fd] = (BUFFERED_STREAM *)NULL;
1011 }
1012 #endif /* BUFFERED_INPUT */
1013
1014 saver->line = line_number;
1015 bash_input.name = (char *)NULL;
1016 saver->next = stream_list;
1017 stream_list = saver;
1018 EOF_Reached = line_number = 0;
1019 }
1020
pop_stream()1021 pop_stream ()
1022 {
1023 int temp;
1024
1025 if (!stream_list)
1026 EOF_Reached = 1;
1027 else
1028 {
1029 STREAM_SAVER *saver = stream_list;
1030
1031 EOF_Reached = 0;
1032 stream_list = stream_list->next;
1033
1034 init_yy_io (saver->bash_input.getter,
1035 saver->bash_input.ungetter,
1036 saver->bash_input.type,
1037 saver->bash_input.name,
1038 saver->bash_input.location);
1039
1040 #if defined (BUFFERED_INPUT)
1041 /* If we have a buffered stream, restore buffers[fd]. */
1042 /* If the input file descriptor was changed while this was on the
1043 save stack, update the buffered fd to the new file descriptor and
1044 re-establish the buffer <-> bash_input fd correspondence. */
1045 if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0)
1046 {
1047 if (bash_input_fd_changed)
1048 {
1049 bash_input_fd_changed = 0;
1050 if (default_buffered_input >= 0)
1051 {
1052 bash_input.location.buffered_fd = default_buffered_input;
1053 saver->bstream->b_fd = default_buffered_input;
1054 }
1055 }
1056 buffers[bash_input.location.buffered_fd] = saver->bstream;
1057 }
1058 #endif /* BUFFERED_INPUT */
1059
1060 line_number = saver->line;
1061
1062 FREE (saver->bash_input.name);
1063 free (saver);
1064 }
1065 }
1066
1067 /* Return 1 if a stream of type TYPE is saved on the stack. */
1068 int
stream_on_stack(type)1069 stream_on_stack (type)
1070 int type;
1071 {
1072 register STREAM_SAVER *s;
1073
1074 for (s = stream_list; s; s = s->next)
1075 if (s->bash_input.type == type)
1076 return 1;
1077 return 0;
1078 }
1079
1080
1081 /*
1082 * This is used to inhibit alias expansion and reserved word recognition
1083 * inside case statement pattern lists. A `case statement pattern list'
1084 * is:
1085 * everything between the `in' in a `case word in' and the next ')'
1086 * or `esac'
1087 * everything between a `;;' and the next `)' or `esac'
1088 */
1089 static int in_case_pattern_list = 0;
1090
1091 #if defined (ALIAS)
1092 /*
1093 * Pseudo-global variables used in implementing token-wise alias expansion.
1094 */
1095
1096 static int expand_next_token = 0;
1097
1098 /*
1099 * Pushing and popping strings. This works together with shell_getc to
1100 * implement alias expansion on a per-token basis.
1101 */
1102
1103 typedef struct string_saver {
1104 struct string_saver *next;
1105 int expand_alias; /* Value to set expand_alias to when string is popped. */
1106 char *saved_line;
1107 int saved_line_size, saved_line_index, saved_line_terminator;
1108 } STRING_SAVER;
1109
1110 STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL;
1111
1112 static void save_expansion ();
1113
1114 /*
1115 * Push the current shell_input_line onto a stack of such lines and make S
1116 * the current input. Used when expanding aliases. EXPAND is used to set
1117 * the value of expand_next_token when the string is popped, so that the
1118 * word after the alias in the original line is handled correctly when the
1119 * alias expands to multiple words. TOKEN is the token that was expanded
1120 * into S; it is saved and used to prevent infinite recursive expansion.
1121 */
1122 static void
push_string(s,expand,token)1123 push_string (s, expand, token)
1124 char *s;
1125 int expand;
1126 char *token;
1127 {
1128 STRING_SAVER *temp = (STRING_SAVER *) xmalloc (sizeof (STRING_SAVER));
1129
1130 temp->expand_alias = expand;
1131 temp->saved_line = shell_input_line;
1132 temp->saved_line_size = shell_input_line_size;
1133 temp->saved_line_index = shell_input_line_index;
1134 temp->saved_line_terminator = shell_input_line_terminator;
1135 temp->next = pushed_string_list;
1136 pushed_string_list = temp;
1137
1138 save_expansion (token);
1139
1140 shell_input_line = s;
1141 shell_input_line_size = strlen (s);
1142 shell_input_line_index = 0;
1143 shell_input_line_terminator = '\0';
1144 expand_next_token = 0;
1145 }
1146
1147 /*
1148 * Make the top of the pushed_string stack be the current shell input.
1149 * Only called when there is something on the stack. Called from shell_getc
1150 * when it thinks it has consumed the string generated by an alias expansion
1151 * and needs to return to the original input line.
1152 */
1153 static void
pop_string()1154 pop_string ()
1155 {
1156 STRING_SAVER *t;
1157
1158 FREE (shell_input_line);
1159 shell_input_line = pushed_string_list->saved_line;
1160 shell_input_line_index = pushed_string_list->saved_line_index;
1161 shell_input_line_size = pushed_string_list->saved_line_size;
1162 shell_input_line_terminator = pushed_string_list->saved_line_terminator;
1163 expand_next_token = pushed_string_list->expand_alias;
1164
1165 t = pushed_string_list;
1166 pushed_string_list = pushed_string_list->next;
1167 free((char *)t);
1168 }
1169
1170 static void
free_string_list()1171 free_string_list ()
1172 {
1173 register STRING_SAVER *t = pushed_string_list, *t1;
1174
1175 while (t)
1176 {
1177 t1 = t->next;
1178 FREE (t->saved_line);
1179 free ((char *)t);
1180 t = t1;
1181 }
1182 pushed_string_list = (STRING_SAVER *)NULL;
1183 }
1184
1185 /* This is a stack to save the values of all tokens for which alias
1186 expansion has been performed during the current call to read_token ().
1187 It is used to prevent alias expansion loops:
1188
1189 alias foo=bar
1190 alias bar=baz
1191 alias baz=foo
1192
1193 Ideally this would be taken care of by push and pop string, but because
1194 of when strings are popped the stack will not contain the correct
1195 strings to test against. (The popping is done in shell_getc, so that when
1196 the current string is exhausted, shell_getc can simply pop that string off
1197 the stack, restore the previous string, and continue with the character
1198 following the token whose expansion was originally pushed on the stack.)
1199
1200 What we really want is a record of all tokens that have been expanded for
1201 aliases during the `current' call to read_token(). This does that, at the
1202 cost of being somewhat special-purpose (OK, OK vile and unclean). */
1203
1204 typedef struct _exp_saver {
1205 struct _exp_saver *next;
1206 char *saved_token;
1207 } EXPANSION_SAVER;
1208
1209 EXPANSION_SAVER *expanded_token_stack = (EXPANSION_SAVER *)NULL;
1210
1211 static void
save_expansion(s)1212 save_expansion (s)
1213 char *s;
1214 {
1215 EXPANSION_SAVER *t;
1216
1217 t = (EXPANSION_SAVER *) xmalloc (sizeof (EXPANSION_SAVER));
1218 t->saved_token = savestring (s);
1219 t->next = expanded_token_stack;
1220 expanded_token_stack = t;
1221 }
1222
1223 /* Return 1 if TOKEN has already been expanded in the current `stack' of
1224 expansions. If it has been expanded already, it will appear as the value
1225 of saved_token for some entry in the stack of expansions created for the
1226 current token being expanded. */
1227 static int
token_has_been_expanded(token)1228 token_has_been_expanded (token)
1229 char *token;
1230 {
1231 register EXPANSION_SAVER *t = expanded_token_stack;
1232
1233 while (t)
1234 {
1235 if (STREQ (token, t->saved_token))
1236 return (1);
1237 t = t->next;
1238 }
1239 return (0);
1240 }
1241
1242 static void
free_expansion_stack()1243 free_expansion_stack ()
1244 {
1245 register EXPANSION_SAVER *t = expanded_token_stack, *t1;
1246
1247 while (t)
1248 {
1249 t1 = t->next;
1250 free (t->saved_token);
1251 free (t);
1252 t = t1;
1253 }
1254 expanded_token_stack = (EXPANSION_SAVER *)NULL;
1255 }
1256
1257 #endif /* ALIAS */
1258
1259 /* Return a line of text, taken from wherever yylex () reads input.
1260 If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE
1261 is non-zero, we remove unquoted \<newline> pairs. This is used by
1262 read_secondary_line to read here documents. */
1263 static char *
read_a_line(remove_quoted_newline)1264 read_a_line (remove_quoted_newline)
1265 int remove_quoted_newline;
1266 {
1267 static char *line_buffer = (char *)NULL;
1268 static int buffer_size = 0;
1269 int indx = 0, c, peekc, pass_next;
1270
1271 pass_next = 0;
1272 while (1)
1273 {
1274 c = yy_getc ();
1275
1276 /* Allow immediate exit if interrupted during input. */
1277 QUIT;
1278
1279 if (c == 0)
1280 continue;
1281
1282 /* If there is no more input, then we return NULL. */
1283 if (c == EOF)
1284 {
1285 if (indx == 0)
1286 return ((char *)NULL);
1287 c = '\n';
1288 }
1289
1290 /* `+2' in case the final character in the buffer is a newline. */
1291 if (indx + 2 > buffer_size)
1292 if (!buffer_size)
1293 line_buffer = xmalloc (buffer_size = 128);
1294 else
1295 line_buffer = xrealloc (line_buffer, buffer_size += 128);
1296
1297 /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a
1298 here document with an unquoted delimiter. In this case,
1299 the line will be expanded as if it were in double quotes.
1300 We allow a backslash to escape the next character, but we
1301 need to treat the backslash specially only if a backslash
1302 quoting a backslash-newline pair appears in the line. */
1303 if (pass_next)
1304 {
1305 line_buffer[indx++] = c;
1306 pass_next = 0;
1307 }
1308 else if (c == '\\' && remove_quoted_newline)
1309 {
1310 peekc = yy_getc ();
1311 if (peekc == '\n')
1312 continue; /* Make the unquoted \<newline> pair disappear. */
1313 else
1314 {
1315 yy_ungetc (peekc);
1316 pass_next = 1;
1317 line_buffer[indx++] = c; /* Preserve the backslash. */
1318 }
1319 }
1320 else
1321 line_buffer[indx++] = c;
1322
1323 if (c == '\n')
1324 {
1325 line_buffer[indx] = '\0';
1326 return (line_buffer);
1327 }
1328 }
1329 }
1330
1331 /* Return a line as in read_a_line (), but insure that the prompt is
1332 the secondary prompt. This is used to read the lines of a here
1333 document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove
1334 newlines quoted with backslashes while reading the line. It is
1335 non-zero unless the delimiter of the here document was quoted. */
1336 char *
read_secondary_line(remove_quoted_newline)1337 read_secondary_line (remove_quoted_newline)
1338 int remove_quoted_newline;
1339 {
1340 prompt_string_pointer = &ps2_prompt;
1341 prompt_again ();
1342 return (read_a_line (remove_quoted_newline));
1343 }
1344
1345
1346 /* **************************************************************** */
1347 /* */
1348 /* YYLEX () */
1349 /* */
1350 /* **************************************************************** */
1351
1352 /* Reserved words. These are only recognized as the first word of a
1353 command. */
1354 STRING_INT_ALIST word_token_alist[] = {
1355 { "if", IF },
1356 { "then", THEN },
1357 { "else", ELSE },
1358 { "elif", ELIF },
1359 { "fi", FI },
1360 { "case", CASE },
1361 { "esac", ESAC },
1362 { "for", FOR },
1363 #if defined (SELECT_COMMAND)
1364 { "select", SELECT },
1365 #endif
1366 { "while", WHILE },
1367 { "until", UNTIL },
1368 { "do", DO },
1369 { "done", DONE },
1370 { "in", IN },
1371 { "function", FUNCTION },
1372 { "{", '{' },
1373 { "}", '}' },
1374 { "!", BANG },
1375 { (char *)NULL, 0}
1376 };
1377
1378 /* Return the next shell input character. This always reads characters
1379 from shell_input_line; when that line is exhausted, it is time to
1380 read the next line. This is called by read_token when the shell is
1381 processing normal command input. */
1382 static int
shell_getc(remove_quoted_newline)1383 shell_getc (remove_quoted_newline)
1384 int remove_quoted_newline;
1385 {
1386 int c;
1387
1388 QUIT;
1389
1390 #if defined (ALIAS)
1391 /* If shell_input_line[shell_input_line_index] == 0, but there is
1392 something on the pushed list of strings, then we don't want to go
1393 off and get another line. We let the code down below handle it. */
1394
1395 if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) &&
1396 (pushed_string_list == (STRING_SAVER *)NULL)))
1397 #else /* !ALIAS */
1398 if (!shell_input_line || !shell_input_line[shell_input_line_index])
1399 #endif /* !ALIAS */
1400 {
1401 register int i, l;
1402
1403 restart_read_next_line:
1404
1405 line_number++;
1406
1407 restart_read:
1408
1409 /* Allow immediate exit if interrupted during input. */
1410 QUIT;
1411
1412 i = 0;
1413 shell_input_line_terminator = 0;
1414
1415 #if defined (JOB_CONTROL)
1416 /* This can cause a problem when reading a command as the result
1417 of a trap, when the trap is called from flush_child. This call
1418 had better not cause jobs to disappear from the job table in
1419 that case, or we will have big trouble. */
1420 notify_and_cleanup ();
1421 #else /* !JOB_CONTROL */
1422 cleanup_dead_jobs ();
1423 #endif /* !JOB_CONTROL */
1424
1425 #if defined (READLINE)
1426 if (interactive && bash_input.type != st_string && no_line_editing)
1427 #else
1428 if (interactive && bash_input.type != st_string)
1429 #endif
1430 print_prompt ();
1431
1432 if (bash_input.type == st_stream)
1433 clearerr (stdin);
1434
1435 while (c = yy_getc ())
1436 {
1437 /* Allow immediate exit if interrupted during input. */
1438 QUIT;
1439
1440 if (i + 2 > shell_input_line_size)
1441 shell_input_line =
1442 xrealloc (shell_input_line, shell_input_line_size += 256);
1443
1444 if (c == EOF)
1445 {
1446 if (bash_input.type == st_stream)
1447 clearerr (stdin);
1448
1449 if (!i)
1450 shell_input_line_terminator = EOF;
1451
1452 shell_input_line[i] = '\0';
1453 break;
1454 }
1455
1456 shell_input_line[i++] = c;
1457
1458 if (c == '\n')
1459 {
1460 shell_input_line[--i] = '\0';
1461 current_command_line_count++;
1462 break;
1463 }
1464 }
1465 shell_input_line_index = 0;
1466 shell_input_line_len = i; /* == strlen (shell_input_line) */
1467
1468 #if defined (HISTORY)
1469 if (interactive && shell_input_line && shell_input_line[0])
1470 {
1471 char *expansions;
1472
1473 expansions = pre_process_line (shell_input_line, 1, 1);
1474
1475 free (shell_input_line);
1476 shell_input_line = expansions;
1477 shell_input_line_len = shell_input_line ?
1478 strlen (shell_input_line) :
1479 0;
1480 if (!shell_input_line_len)
1481 current_command_line_count--;
1482
1483 /* We have to force the xrealloc below because we don't know the
1484 true allocated size of shell_input_line anymore. */
1485 shell_input_line_size = shell_input_line_len;
1486 }
1487 #endif /* HISTORY */
1488
1489 if (shell_input_line)
1490 {
1491 /* Lines that signify the end of the shell's input should not be
1492 echoed. */
1493 if (echo_input_at_read && (shell_input_line[0] ||
1494 shell_input_line_terminator != EOF))
1495 fprintf (stderr, "%s\n", shell_input_line);
1496 }
1497 else
1498 {
1499 shell_input_line_size = 0;
1500 prompt_string_pointer = ¤t_prompt_string;
1501 prompt_again ();
1502 goto restart_read;
1503 }
1504
1505 /* Add the newline to the end of this string, iff the string does
1506 not already end in an EOF character. */
1507 if (shell_input_line_terminator != EOF)
1508 {
1509 l = shell_input_line_len; /* was a call to strlen */
1510
1511 if (l + 3 > shell_input_line_size)
1512 shell_input_line = xrealloc (shell_input_line,
1513 1 + (shell_input_line_size += 2));
1514
1515 shell_input_line[l] = '\n';
1516 shell_input_line[l + 1] = '\0';
1517 }
1518 }
1519
1520 c = shell_input_line[shell_input_line_index];
1521
1522 if (c)
1523 shell_input_line_index++;
1524
1525 if (c == '\\' && remove_quoted_newline &&
1526 shell_input_line[shell_input_line_index] == '\n')
1527 {
1528 prompt_again ();
1529 goto restart_read_next_line;
1530 }
1531
1532 #if defined (ALIAS)
1533 /* If C is NULL, we have reached the end of the current input string. If
1534 pushed_string_list is non-empty, it's time to pop to the previous string
1535 because we have fully consumed the result of the last alias expansion.
1536 Do it transparently; just return the next character of the string popped
1537 to. */
1538 if (!c && (pushed_string_list != (STRING_SAVER *)NULL))
1539 {
1540 pop_string ();
1541 c = shell_input_line[shell_input_line_index];
1542 if (c)
1543 shell_input_line_index++;
1544 }
1545 #endif /* ALIAS */
1546
1547 if (!c && shell_input_line_terminator == EOF)
1548 {
1549 if (shell_input_line_index != 0)
1550 return ('\n');
1551 else
1552 return (EOF);
1553 }
1554
1555 return ((unsigned char)c);
1556 }
1557
1558 /* Put C back into the input for the shell. */
1559 static void
shell_ungetc(c)1560 shell_ungetc (c)
1561 int c;
1562 {
1563 if (shell_input_line && shell_input_line_index)
1564 shell_input_line[--shell_input_line_index] = c;
1565 }
1566
1567 /* Discard input until CHARACTER is seen. */
1568 static void
discard_until(character)1569 discard_until (character)
1570 int character;
1571 {
1572 int c;
1573
1574 while ((c = shell_getc (0)) != EOF && c != character)
1575 ;
1576
1577 if (c != EOF)
1578 shell_ungetc (c);
1579 }
1580
1581 /* Place to remember the token. We try to keep the buffer
1582 at a reasonable size, but it can grow. */
1583 static char *token = (char *)NULL;
1584
1585 /* Current size of the token buffer. */
1586 static int token_buffer_size = 0;
1587
1588 void
execute_prompt_command(command)1589 execute_prompt_command (command)
1590 char *command;
1591 {
1592 Function *temp_last, *temp_this;
1593 char *last_lastarg;
1594 int temp_exit_value, temp_eof_encountered;
1595
1596 temp_last = last_shell_builtin;
1597 temp_this = this_shell_builtin;
1598 temp_exit_value = last_command_exit_value;
1599 temp_eof_encountered = eof_encountered;
1600 last_lastarg = get_string_value ("_");
1601 if (last_lastarg)
1602 last_lastarg = savestring (last_lastarg);
1603
1604 parse_and_execute (savestring (command), "PROMPT_COMMAND", 0);
1605
1606 last_shell_builtin = temp_last;
1607 this_shell_builtin = temp_this;
1608 last_command_exit_value = temp_exit_value;
1609 eof_encountered = temp_eof_encountered;
1610
1611 bind_variable ("_", last_lastarg);
1612 FREE (last_lastarg);
1613
1614 if (token_to_read == '\n')
1615 token_to_read = 0;
1616 }
1617
1618 /* Command to read_token () explaining what we want it to do. */
1619 #define READ 0
1620 #define RESET 1
1621 #define prompt_is_ps1 \
1622 (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt)
1623
1624 /* Function for yyparse to call. yylex keeps track of
1625 the last two tokens read, and calls read_token. */
1626
yylex()1627 yylex ()
1628 {
1629 if (interactive && (!current_token || current_token == '\n'))
1630 {
1631 /* Before we print a prompt, we might have to check mailboxes.
1632 We do this only if it is time to do so. Notice that only here
1633 is the mail alarm reset; nothing takes place in check_mail ()
1634 except the checking of mail. Please don't change this. */
1635 if (prompt_is_ps1 && time_to_check_mail ())
1636 {
1637 check_mail ();
1638 reset_mail_timer ();
1639 }
1640
1641 /* Avoid printing a prompt if we're not going to read anything, e.g.
1642 after resetting the parser with read_token (RESET). */
1643 if (token_to_read == 0 && interactive)
1644 prompt_again ();
1645 }
1646
1647 token_before_that = last_read_token;
1648 last_read_token = current_token;
1649 current_token = read_token (READ);
1650 return (current_token);
1651 }
1652
1653 /* Called from shell.c when Control-C is typed at top level. Or
1654 by the error rule at top level. */
reset_parser()1655 reset_parser ()
1656 {
1657 read_token (RESET);
1658 }
1659
1660 /* When non-zero, we have read the required tokens
1661 which allow ESAC to be the next one read. */
1662 static int allow_esac_as_next = 0;
1663
1664 /* When non-zero, accept single '{' as a token itself. */
1665 static int allow_open_brace = 0;
1666
1667 /* DELIMITERS is a stack of the nested delimiters that we have
1668 encountered so far. */
1669 static char *delimiters = (char *)NULL;
1670
1671 /* Offset into the stack of delimiters. */
1672 int delimiter_depth = 0;
1673
1674 /* How many slots are allocated to DELIMITERS. */
1675 static int delimiter_space = 0;
1676
1677 void
gather_here_documents()1678 gather_here_documents ()
1679 {
1680 int r = 0;
1681 while (need_here_doc)
1682 {
1683 make_here_document (redir_stack[r++]);
1684 need_here_doc--;
1685 }
1686 }
1687
1688 /* Macro for accessing the top delimiter on the stack. Returns the
1689 delimiter or zero if none. */
1690 #define current_delimiter() \
1691 (delimiter_depth ? delimiters[delimiter_depth - 1] : 0)
1692
1693 #define push_delimiter(character) \
1694 do \
1695 { \
1696 if (delimiter_depth + 2 > delimiter_space) \
1697 delimiters = xrealloc \
1698 (delimiters, (delimiter_space += 10) * sizeof (char)); \
1699 delimiters[delimiter_depth] = character; \
1700 delimiter_depth++; \
1701 } \
1702 while (0)
1703
1704 /* When non-zero, an open-brace used to create a group is awaiting a close
1705 brace partner. */
1706 static int open_brace_awaiting_satisfaction = 0;
1707
1708 #define command_token_position(token) \
1709 (((token) == ASSIGNMENT_WORD) || \
1710 ((token) != SEMI_SEMI && reserved_word_acceptable(token)))
1711
1712 #define assignment_acceptable(token) command_token_position(token) && \
1713 (in_case_pattern_list == 0)
1714
1715 /* Check to see if TOKEN is a reserved word and return the token
1716 value if it is. */
1717 #define CHECK_FOR_RESERVED_WORD(tok) \
1718 do { \
1719 if (!dollar_present && !quoted && \
1720 reserved_word_acceptable (last_read_token)) \
1721 { \
1722 int i; \
1723 for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \
1724 if (STREQ (tok, word_token_alist[i].word)) \
1725 { \
1726 if (in_case_pattern_list && (word_token_alist[i].token != ESAC)) \
1727 break; \
1728 \
1729 if (word_token_alist[i].token == ESAC) \
1730 in_case_pattern_list = 0; \
1731 \
1732 if (word_token_alist[i].token == '{') \
1733 open_brace_awaiting_satisfaction++; \
1734 \
1735 if (word_token_alist[i].token == '}' && open_brace_awaiting_satisfaction) \
1736 open_brace_awaiting_satisfaction--; \
1737 \
1738 return (word_token_alist[i].token); \
1739 } \
1740 } \
1741 } while (0)
1742
1743 /* Read the next token. Command can be READ (normal operation) or
1744 RESET (to normalize state). */
1745 static int
read_token(command)1746 read_token (command)
1747 int command;
1748 {
1749 int character; /* Current character. */
1750 int peek_char; /* Temporary look-ahead character. */
1751 int result; /* The thing to return. */
1752 WORD_DESC *the_word; /* The value for YYLVAL when a WORD is read. */
1753
1754 if (token_buffer_size < TOKEN_DEFAULT_GROW_SIZE)
1755 {
1756 FREE (token);
1757 token = xmalloc (token_buffer_size = TOKEN_DEFAULT_GROW_SIZE);
1758 }
1759
1760 if (command == RESET)
1761 {
1762 delimiter_depth = 0; /* No delimiters found so far. */
1763 open_brace_awaiting_satisfaction = 0;
1764 in_case_pattern_list = 0;
1765
1766 #if defined (ALIAS)
1767 if (pushed_string_list)
1768 {
1769 free_string_list ();
1770 pushed_string_list = (STRING_SAVER *)NULL;
1771 }
1772
1773 if (expanded_token_stack)
1774 {
1775 free_expansion_stack ();
1776 expanded_token_stack = (EXPANSION_SAVER *)NULL;
1777 }
1778
1779 expand_next_token = 0;
1780 #endif /* ALIAS */
1781
1782 if (shell_input_line)
1783 {
1784 free (shell_input_line);
1785 shell_input_line = (char *)NULL;
1786 shell_input_line_size = shell_input_line_index = 0;
1787 }
1788 last_read_token = '\n';
1789 token_to_read = '\n';
1790 return ('\n');
1791 }
1792
1793 if (token_to_read)
1794 {
1795 int rt = token_to_read;
1796 token_to_read = 0;
1797 return (rt);
1798 }
1799
1800 #if defined (ALIAS)
1801 /* If we hit read_token () and there are no saved strings on the
1802 pushed_string_list, then we are no longer currently expanding a
1803 token. This can't be done in pop_stream, because pop_stream
1804 may pop the stream before the current token has finished being
1805 completely expanded (consider what happens when we alias foo to foo,
1806 and then try to expand it). */
1807 if (!pushed_string_list && expanded_token_stack)
1808 {
1809 free_expansion_stack ();
1810 expanded_token_stack = (EXPANSION_SAVER *)NULL;
1811 }
1812
1813 /* This is a place to jump back to once we have successfully expanded a
1814 token with an alias and pushed the string with push_string () */
1815 re_read_token:
1816
1817 #endif /* ALIAS */
1818
1819 /* Read a single word from input. Start by skipping blanks. */
1820 while ((character = shell_getc (1)) != EOF && whitespace (character));
1821
1822 if (character == EOF)
1823 {
1824 EOF_Reached = 1;
1825 return (yacc_EOF);
1826 }
1827
1828 if (character == '#' && (!interactive || interactive_comments))
1829 {
1830 /* A comment. Discard until EOL or EOF, and then return a newline. */
1831 discard_until ('\n');
1832 shell_getc (0);
1833
1834 /* If we're about to return an unquoted newline, we can go and collect
1835 the text of any pending here documents. */
1836 if (need_here_doc)
1837 gather_here_documents ();
1838
1839 #if defined (ALIAS)
1840 expand_next_token = 0;
1841 #endif /* ALIAS */
1842
1843 return ('\n');
1844 }
1845
1846 if (character == '\n')
1847 {
1848 /* If we're about to return an unquoted newline, we can go and collect
1849 the text of any pending here document. */
1850 if (need_here_doc)
1851 gather_here_documents ();
1852
1853 #if defined (ALIAS)
1854 expand_next_token = 0;
1855 #endif /* ALIAS */
1856
1857 return (character);
1858 }
1859
1860 if (member (character, "()<>;&|"))
1861 {
1862 #if defined (ALIAS)
1863 /* Turn off alias tokenization iff this character sequence would
1864 not leave us ready to read a command. */
1865 if (character == '<' || character == '>')
1866 expand_next_token = 0;
1867 #endif /* ALIAS */
1868
1869 /* Please note that the shell does not allow whitespace to
1870 appear in between tokens which are character pairs, such as
1871 "<<" or ">>". I believe this is the correct behaviour. */
1872 if (character == (peek_char = shell_getc (1)))
1873 {
1874 switch (character)
1875 {
1876 /* If '<' then we could be at "<<" or at "<<-". We have to
1877 look ahead one more character. */
1878 case '<':
1879 peek_char = shell_getc (1);
1880 if (peek_char == '-')
1881 return (LESS_LESS_MINUS);
1882 else
1883 {
1884 shell_ungetc (peek_char);
1885 return (LESS_LESS);
1886 }
1887
1888 case '>':
1889 return (GREATER_GREATER);
1890
1891 case ';':
1892 in_case_pattern_list = 1;
1893 #if defined (ALIAS)
1894 expand_next_token = 0;
1895 #endif /* ALIAS */
1896 return (SEMI_SEMI);
1897
1898 case '&':
1899 return (AND_AND);
1900
1901 case '|':
1902 return (OR_OR);
1903 }
1904 }
1905 else
1906 {
1907 if (peek_char == '&')
1908 {
1909 switch (character)
1910 {
1911 case '<': return (LESS_AND);
1912 case '>': return (GREATER_AND);
1913 }
1914 }
1915 if (character == '<' && peek_char == '>')
1916 return (LESS_GREATER);
1917 if (character == '>' && peek_char == '|')
1918 return (GREATER_BAR);
1919 if (peek_char == '>' && character == '&')
1920 return (AND_GREATER);
1921 }
1922 shell_ungetc (peek_char);
1923
1924 /* If we look like we are reading the start of a function
1925 definition, then let the reader know about it so that
1926 we will do the right thing with `{'. */
1927 if (character == ')' &&
1928 last_read_token == '(' && token_before_that == WORD)
1929 {
1930 allow_open_brace = 1;
1931 #if defined (ALIAS)
1932 expand_next_token = 0;
1933 #endif /* ALIAS */
1934 }
1935
1936 if (in_case_pattern_list && (character == ')'))
1937 in_case_pattern_list = 0;
1938
1939 #if defined (PROCESS_SUBSTITUTION)
1940 /* Check for the constructs which introduce process substitution.
1941 Shells running in `posix mode' don't do process substitution. */
1942 if (posixly_correct ||
1943 (((character == '>' || character == '<') && peek_char == '(') == 0))
1944 #endif /* PROCESS_SUBSTITUTION */
1945 return (character);
1946 }
1947
1948 /* Hack <&- (close stdin) case. */
1949 if (character == '-')
1950 {
1951 switch (last_read_token)
1952 {
1953 case LESS_AND:
1954 case GREATER_AND:
1955 return (character);
1956 }
1957 }
1958
1959 /* Okay, if we got this far, we have to read a word. Read one,
1960 and then check it against the known ones. */
1961 {
1962 /* Index into the token that we are building. */
1963 int token_index = 0;
1964
1965 /* ALL_DIGITS becomes zero when we see a non-digit. */
1966 int all_digits = digit (character);
1967
1968 /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */
1969 int dollar_present = 0;
1970
1971 /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */
1972 int quoted = 0;
1973
1974 /* Non-zero means to ignore the value of the next character, and just
1975 to add it no matter what. */
1976 int pass_next_character = 0;
1977
1978 /* Non-zero means parsing a dollar-paren construct. It is the count of
1979 un-quoted closes we need to see. */
1980 int dollar_paren_level = 0;
1981
1982 /* Non-zero means parsing a dollar-bracket construct ($[...]). It is
1983 the count of un-quoted `]' characters we need to see. */
1984 int dollar_bracket_level = 0;
1985
1986 /* Non-zero means parsing a `${' construct. It is the count of
1987 un-quoted `}' we need to see. */
1988 int dollar_brace_level = 0;
1989
1990 /* A level variable for parsing '${ ... }' constructs inside of double
1991 quotes. */
1992 int delimited_brace_level = 0;
1993
1994 /* A boolean variable denoting whether or not we are currently parsing
1995 a double-quoted string embedded in a $( ) or ${ } construct. */
1996 int embedded_quoted_string = 0;
1997
1998 /* Another level variable. This one is for dollar_parens inside of
1999 double-quotes. */
2000 int delimited_paren_level = 0;
2001
2002 /* The current delimiting character. */
2003 int cd;
2004
2005 for (;;)
2006 {
2007 if (character == EOF)
2008 goto got_token;
2009
2010 if (pass_next_character)
2011 {
2012 pass_next_character = 0;
2013 goto got_character;
2014 }
2015
2016 cd = current_delimiter ();
2017
2018 if (cd && character == '\\' && cd != '\'')
2019 {
2020 peek_char = shell_getc (0);
2021 if (peek_char != '\\')
2022 shell_ungetc (peek_char);
2023 else
2024 {
2025 token[token_index++] = character;
2026 goto got_character;
2027 }
2028 }
2029
2030 /* Handle backslashes. Quote lots of things when not inside of
2031 double-quotes, quote some things inside of double-quotes. */
2032
2033 if (character == '\\' && (!delimiter_depth || cd != '\''))
2034 {
2035 peek_char = shell_getc (0);
2036
2037 /* Backslash-newline is ignored in all cases excepting
2038 when quoted with single quotes. */
2039 if (peek_char == '\n')
2040 {
2041 character = '\n';
2042 goto next_character;
2043 }
2044 else
2045 {
2046 shell_ungetc (peek_char);
2047
2048 /* If the next character is to be quoted, do it now. */
2049 if (!cd || cd == '`' ||
2050 (cd == '"' && member (peek_char, slashify_in_quotes)))
2051 {
2052 pass_next_character++;
2053 quoted = 1;
2054 goto got_character;
2055 }
2056 }
2057 }
2058
2059 /* This is a hack, in its present form. If a backquote substitution
2060 appears within double quotes, everything within the backquotes
2061 should be read as part of a single word. Jesus. Now I see why
2062 Korn introduced the $() form. */
2063 if (delimiter_depth && (cd == '"') && (character == '`'))
2064 {
2065 push_delimiter (character);
2066 goto got_character;
2067 }
2068
2069 cd = current_delimiter (); /* XXX - may not need */
2070 if (delimiter_depth)
2071 {
2072 if (character == cd)
2073 {
2074 /* If we see a double quote while parsing a double-quoted
2075 $( ) or ${ }, and we have not seen ) or }, respectively,
2076 note that we are in the middle of reading an embedded
2077 quoted string. */
2078 if ((delimited_paren_level || delimited_brace_level) &&
2079 (character == '"'))
2080 {
2081 embedded_quoted_string = !embedded_quoted_string;
2082 goto got_character;
2083 }
2084
2085 delimiter_depth--;
2086 goto got_character;
2087 }
2088 }
2089
2090 if (cd != '\'')
2091 {
2092 #if defined (PROCESS_SUBSTITUTION)
2093 if (character == '$' || character == '<' || character == '>')
2094 #else
2095 if (character == '$')
2096 #endif /* !PROCESS_SUBSTITUTION */
2097 {
2098 /* If we're in the middle of parsing a $( ) or ${ }
2099 construct with an embedded quoted string, don't
2100 bother looking at this character any further. */
2101 if (embedded_quoted_string)
2102 goto got_character;
2103
2104 peek_char = shell_getc (1);
2105 shell_ungetc (peek_char);
2106 if (peek_char == '(')
2107 {
2108 if (!delimiter_depth)
2109 dollar_paren_level++;
2110 else
2111 delimited_paren_level++;
2112
2113 pass_next_character++;
2114 goto got_character;
2115 }
2116 else if (peek_char == '[' && character == '$')
2117 {
2118 if (!delimiter_depth)
2119 dollar_bracket_level++;
2120
2121 pass_next_character++;
2122 goto got_character;
2123 }
2124 /* This handles ${...} constructs. */
2125 else if (peek_char == '{' && character == '$')
2126 {
2127 if (!delimiter_depth)
2128 dollar_brace_level++;
2129 else
2130 delimited_brace_level++;
2131
2132 pass_next_character++;
2133 goto got_character;
2134 }
2135 }
2136
2137 /* If we are parsing a $() or $[] construct, we need to balance
2138 parens and brackets inside the construct. This whole function
2139 could use a rewrite. */
2140 if (character == '(' && !embedded_quoted_string)
2141 {
2142 if (delimiter_depth && delimited_paren_level)
2143 delimited_paren_level++;
2144
2145 if (!delimiter_depth && dollar_paren_level)
2146 dollar_paren_level++;
2147 }
2148
2149 if (character == '[')
2150 {
2151 if (!delimiter_depth && dollar_bracket_level)
2152 dollar_bracket_level++;
2153 }
2154
2155 if (character == '{' && !embedded_quoted_string)
2156 {
2157 if (delimiter_depth && delimited_brace_level)
2158 delimited_brace_level++;
2159
2160 if (!delimiter_depth && dollar_brace_level)
2161 dollar_brace_level++;
2162 }
2163
2164 /* This code needs to take into account whether we are inside a
2165 case statement pattern list, and whether this paren is supposed
2166 to terminate it (hey, it could happen). It's not as simple
2167 as just using in_case_pattern_list, because we're not parsing
2168 anything while we're reading a $( ) construct. Maybe we
2169 should move that whole mess into the yacc parser. */
2170 if (character == ')' && !embedded_quoted_string)
2171 {
2172 if (delimiter_depth && delimited_paren_level)
2173 delimited_paren_level--;
2174
2175 if (!delimiter_depth && dollar_paren_level)
2176 {
2177 dollar_paren_level--;
2178 goto got_character;
2179 }
2180 }
2181
2182 if (character == ']')
2183 {
2184 if (!delimiter_depth && dollar_bracket_level)
2185 {
2186 dollar_bracket_level--;
2187 goto got_character;
2188 }
2189 }
2190
2191 if (character == '}' && !embedded_quoted_string)
2192 {
2193 if (delimiter_depth && delimited_brace_level)
2194 delimited_brace_level--;
2195
2196 if (!delimiter_depth && dollar_brace_level)
2197 {
2198 dollar_brace_level--;
2199 goto got_character;
2200 }
2201 }
2202 }
2203
2204 if (!dollar_paren_level && !dollar_bracket_level &&
2205 !dollar_brace_level && !delimiter_depth &&
2206 member (character, " \t\n;&()|<>"))
2207 {
2208 shell_ungetc (character);
2209 goto got_token;
2210 }
2211
2212 if (!delimiter_depth)
2213 {
2214 if (character == '"' || character == '`' || character == '\'')
2215 {
2216 push_delimiter (character);
2217
2218 quoted = 1;
2219 goto got_character;
2220 }
2221 }
2222
2223 if (all_digits)
2224 all_digits = digit (character);
2225 if (character == '$')
2226 dollar_present = 1;
2227
2228 got_character:
2229
2230 if (character == CTLESC || character == CTLNUL)
2231 token[token_index++] = CTLESC;
2232
2233 token[token_index++] = character;
2234
2235 if (token_index == (token_buffer_size - 1))
2236 {
2237 token_buffer_size += TOKEN_DEFAULT_GROW_SIZE;
2238 token = xrealloc (token, token_buffer_size);
2239 }
2240 next_character:
2241 if (character == '\n' && interactive && bash_input.type != st_string)
2242 prompt_again ();
2243
2244 /* We want to remove quoted newlines (that is, a \<newline> pair)
2245 unless we are within single quotes or pass_next_character is
2246 set (the shell equivalent of literal-next). */
2247 character = shell_getc
2248 ((current_delimiter () != '\'') && (!pass_next_character));
2249 }
2250
2251 got_token:
2252
2253 token[token_index] = '\0';
2254
2255 if ((delimiter_depth || dollar_paren_level || dollar_bracket_level) &&
2256 character == EOF)
2257 {
2258 char reporter = '\0';
2259
2260 if (!delimiter_depth)
2261 {
2262 if (dollar_paren_level)
2263 reporter = ')';
2264 else if (dollar_bracket_level)
2265 reporter = ']';
2266 }
2267
2268 if (!reporter)
2269 reporter = current_delimiter ();
2270
2271 report_error ("unexpected EOF while looking for `%c'", reporter);
2272 return (-1);
2273 }
2274
2275 if (all_digits)
2276 {
2277 /* Check to see what thing we should return. If the last_read_token
2278 is a `<', or a `&', or the character which ended this token is
2279 a '>' or '<', then, and ONLY then, is this input token a NUMBER.
2280 Otherwise, it is just a word, and should be returned as such. */
2281
2282 if (character == '<' || character == '>' ||
2283 last_read_token == LESS_AND || last_read_token == GREATER_AND)
2284 {
2285 yylval.number = atoi (token);
2286 return (NUMBER);
2287 }
2288 }
2289
2290 /* Handle special case. IN is recognized if the last token
2291 was WORD and the token before that was FOR or CASE. */
2292 if ((last_read_token == WORD) &&
2293 #if defined (SELECT_COMMAND)
2294 ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) &&
2295 #else
2296 ((token_before_that == FOR) || (token_before_that == CASE)) &&
2297 #endif
2298 (token[0] == 'i' && token[1] == 'n' && !token[2]))
2299 {
2300 if (token_before_that == CASE)
2301 {
2302 in_case_pattern_list = 1;
2303 allow_esac_as_next++;
2304 }
2305 return (IN);
2306 }
2307
2308 /* Ditto for DO in the FOR case. */
2309 #if defined (SELECT_COMMAND)
2310 if ((last_read_token == WORD) && ((token_before_that == FOR) || (token_before_that == SELECT)) &&
2311 #else
2312 if ((last_read_token == WORD) && (token_before_that == FOR) &&
2313 #endif
2314 (token[0] == 'd' && token[1] == 'o' && !token[2]))
2315 return (DO);
2316
2317 /* Ditto for ESAC in the CASE case.
2318 Specifically, this handles "case word in esac", which is a legal
2319 construct, certainly because someone will pass an empty arg to the
2320 case construct, and we don't want it to barf. Of course, we should
2321 insist that the case construct has at least one pattern in it, but
2322 the designers disagree. */
2323 if (allow_esac_as_next)
2324 {
2325 allow_esac_as_next--;
2326 if (STREQ (token, "esac"))
2327 {
2328 in_case_pattern_list = 0;
2329 return (ESAC);
2330 }
2331 }
2332
2333 /* Ditto for `{' in the FUNCTION case. */
2334 if (allow_open_brace)
2335 {
2336 allow_open_brace = 0;
2337 if (token[0] == '{' && !token[1])
2338 {
2339 open_brace_awaiting_satisfaction++;
2340 return ('{');
2341 }
2342 }
2343
2344 if (posixly_correct)
2345 CHECK_FOR_RESERVED_WORD (token);
2346
2347 #if defined (ALIAS)
2348 /* OK, we have a token. Let's try to alias expand it, if (and only if)
2349 it's eligible.
2350
2351 It is eligible for expansion if the shell is in interactive mode, and
2352 the token is unquoted and the last token read was a command
2353 separator (or expand_next_token is set), and we are currently
2354 processing an alias (pushed_string_list is non-empty) and this
2355 token is not the same as the current or any previously
2356 processed alias.
2357
2358 Special cases that disqualify:
2359 In a pattern list in a case statement (in_case_pattern_list). */
2360 if (interactive_shell && !quoted && !in_case_pattern_list &&
2361 (expand_next_token || command_token_position (last_read_token)))
2362 {
2363 char *alias_expand_word (), *expanded;
2364
2365 if (expanded_token_stack && token_has_been_expanded (token))
2366 goto no_expansion;
2367
2368 expanded = alias_expand_word (token);
2369 if (expanded)
2370 {
2371 int len = strlen (expanded), expand_next;
2372
2373 /* Erase the current token. */
2374 token_index = 0;
2375
2376 expand_next = (expanded[len - 1] == ' ') ||
2377 (expanded[len - 1] == '\t');
2378
2379 push_string (expanded, expand_next, token);
2380 goto re_read_token;
2381 }
2382 else
2383 /* This is an eligible token that does not have an expansion. */
2384 no_expansion:
2385 expand_next_token = 0;
2386 }
2387 else
2388 {
2389 expand_next_token = 0;
2390 }
2391 #endif /* ALIAS */
2392
2393 if (!posixly_correct)
2394 CHECK_FOR_RESERVED_WORD (token);
2395
2396 /* What if we are attempting to satisfy an open-brace grouper? */
2397 if (open_brace_awaiting_satisfaction && token[0] == '}' && !token[1])
2398 {
2399 open_brace_awaiting_satisfaction--;
2400 return ('}');
2401 }
2402
2403 the_word = (WORD_DESC *)xmalloc (sizeof (WORD_DESC));
2404 the_word->word = xmalloc (1 + token_index);
2405 strcpy (the_word->word, token);
2406 the_word->dollar_present = dollar_present;
2407 the_word->quoted = quoted;
2408 the_word->assignment = assignment (token);
2409
2410 yylval.word = the_word;
2411 result = WORD;
2412
2413 /* A word is an assignment if it appears at the beginning of a
2414 simple command, or after another assignment word. This is
2415 context-dependent, so it cannot be handled in the grammar. */
2416 if (assignment_acceptable (last_read_token) && the_word->assignment)
2417 result = ASSIGNMENT_WORD;
2418
2419 if (last_read_token == FUNCTION)
2420 allow_open_brace = 1;
2421 }
2422 return (result);
2423 }
2424
2425 /* Return 1 if TOKEN is a token that after being read would allow
2426 a reserved word to be seen, else 0. */
2427 static int
reserved_word_acceptable(token)2428 reserved_word_acceptable (token)
2429 int token;
2430 {
2431 #if 0
2432 if (member (token, "\n;()|&{") ||
2433 #else
2434 if (token == '\n' || token == ';' || token == '(' || token == ')' ||
2435 token == '|' || token == '&' || token == '{' ||
2436 #endif
2437 token == '}' || /* XXX */
2438 token == AND_AND ||
2439 token == BANG ||
2440 token == DO ||
2441 token == ELIF ||
2442 token == ELSE ||
2443 token == FI ||
2444 token == IF ||
2445 token == OR_OR ||
2446 token == SEMI_SEMI ||
2447 token == THEN ||
2448 token == UNTIL ||
2449 token == WHILE ||
2450 token == DONE || /* XXX these two are experimental */
2451 token == ESAC ||
2452 token == 0)
2453 return (1);
2454 else
2455 return (0);
2456 }
2457
2458 /* Return the index of TOKEN in the alist of reserved words, or -1 if
2459 TOKEN is not a shell reserved word. */
2460 int
find_reserved_word(token)2461 find_reserved_word (token)
2462 char *token;
2463 {
2464 int i;
2465 for (i = 0; word_token_alist[i].word != (char *)NULL; i++)
2466 if (STREQ (token, word_token_alist[i].word))
2467 return i;
2468 return -1;
2469 }
2470
2471 #if defined (READLINE)
2472 /* Called after each time readline is called. This insures that whatever
2473 the new prompt string is gets propagated to readline's local prompt
2474 variable. */
2475 static void
reset_readline_prompt()2476 reset_readline_prompt ()
2477 {
2478 if (prompt_string_pointer)
2479 {
2480 char *temp_prompt;
2481
2482 temp_prompt = *prompt_string_pointer
2483 ? decode_prompt_string (*prompt_string_pointer)
2484 : (char *)NULL;
2485
2486 if (temp_prompt == 0)
2487 {
2488 temp_prompt = xmalloc (1);
2489 temp_prompt[0] = '\0';
2490 }
2491
2492 FREE (current_readline_prompt);
2493
2494 current_readline_prompt = temp_prompt;
2495 }
2496 }
2497 #endif /* READLINE */
2498
2499 #if defined (HISTORY)
2500 /* A list of tokens which can be followed by newlines, but not by
2501 semi-colons. When concatenating multiple lines of history, the
2502 newline separator for such tokens is replaced with a space. */
2503 static int no_semi_successors[] = {
2504 '\n', '{', '(', ')', ';', '&', '|',
2505 CASE, DO, ELSE, IF, IN, SEMI_SEMI, THEN, UNTIL, WHILE, AND_AND, OR_OR,
2506 0
2507 };
2508
2509 /* If we are not within a delimited expression, try to be smart
2510 about which separators can be semi-colons and which must be
2511 newlines. */
2512 char *
history_delimiting_chars()2513 history_delimiting_chars ()
2514 {
2515 if (!delimiter_depth)
2516 {
2517 register int i;
2518
2519 for (i = 0; no_semi_successors[i]; i++)
2520 {
2521 if (token_before_that == no_semi_successors[i])
2522 return (" ");
2523 }
2524 return ("; ");
2525 }
2526 else
2527 return ("\n");
2528 }
2529 #endif /* HISTORY */
2530
2531 /* Issue a prompt, or prepare to issue a prompt when the next character
2532 is read. */
2533 static void
prompt_again()2534 prompt_again ()
2535 {
2536 char *temp_prompt;
2537
2538 if (!interactive) /* XXX */
2539 return;
2540
2541 ps1_prompt = get_string_value ("PS1");
2542 ps2_prompt = get_string_value ("PS2");
2543
2544 if (!prompt_string_pointer)
2545 prompt_string_pointer = &ps1_prompt;
2546
2547 temp_prompt = (*prompt_string_pointer)
2548 ? decode_prompt_string (*prompt_string_pointer)
2549 : (char *)NULL;
2550
2551 if (temp_prompt == 0)
2552 {
2553 temp_prompt = xmalloc (1);
2554 temp_prompt[0] = '\0';
2555 }
2556
2557 current_prompt_string = *prompt_string_pointer;
2558 prompt_string_pointer = &ps2_prompt;
2559
2560 #if defined (READLINE)
2561 if (!no_line_editing)
2562 {
2563 FREE (current_readline_prompt);
2564 current_readline_prompt = temp_prompt;
2565 }
2566 else
2567 #endif /* READLINE */
2568 {
2569 FREE (current_decoded_prompt);
2570 current_decoded_prompt = temp_prompt;
2571 }
2572 }
2573
2574 static void
print_prompt()2575 print_prompt ()
2576 {
2577 fprintf (stderr, "%s", current_decoded_prompt);
2578 fflush (stderr);
2579 }
2580
2581 /* Return a string which will be printed as a prompt. The string
2582 may contain special characters which are decoded as follows:
2583
2584 \t the time
2585 \d the date
2586 \n CRLF
2587 \s the name of the shell
2588 \w the current working directory
2589 \W the last element of PWD
2590 \u your username
2591 \h the hostname
2592 \# the command number of this command
2593 \! the history number of this command
2594 \$ a $ or a # if you are root
2595 \<octal> character code in octal
2596 \\ a backslash
2597 */
2598 #define PROMPT_GROWTH 50
2599 char *
decode_prompt_string(string)2600 decode_prompt_string (string)
2601 char *string;
2602 {
2603 int result_size = PROMPT_GROWTH;
2604 int result_index = 0;
2605 char *result;
2606 int c;
2607 char *temp = (char *)NULL;
2608 WORD_LIST *list;
2609
2610 #if defined (PROMPT_STRING_DECODE)
2611
2612 result = xmalloc (PROMPT_GROWTH);
2613 result[0] = 0;
2614
2615 while (c = *string++)
2616 {
2617 if (posixly_correct && c == '!')
2618 {
2619 if (*string == '!')
2620 {
2621 temp = savestring ("!");
2622 goto add_string;
2623 }
2624 else
2625 {
2626 #if !defined (HISTORY)
2627 temp = savestring ("1");
2628 #else /* HISTORY */
2629 temp = itos (history_number ());
2630 #endif /* HISTORY */
2631 string--; /* add_string increments string again. */
2632 goto add_string;
2633 }
2634 }
2635 if (c == '\\')
2636 {
2637 c = *string;
2638
2639 switch (c)
2640 {
2641 case '0':
2642 case '1':
2643 case '2':
2644 case '3':
2645 case '4':
2646 case '5':
2647 case '6':
2648 case '7':
2649 {
2650 char octal_string[4];
2651 int n;
2652
2653 strncpy (octal_string, string, 3);
2654 octal_string[3] = '\0';
2655
2656 n = read_octal (octal_string);
2657 temp = xmalloc (3);
2658
2659 if (n == CTLESC || n == CTLNUL)
2660 {
2661 string += 3;
2662 temp[0] = CTLESC;
2663 temp[1] = n;
2664 temp[2] = '\0';
2665 }
2666 else if (n == -1)
2667 {
2668 temp[0] = '\\';
2669 temp[1] = '\0';
2670 }
2671 else
2672 {
2673 string += 3;
2674 temp[0] = n;
2675 temp[1] = '\0';
2676 }
2677
2678 c = 0;
2679 goto add_string;
2680 }
2681
2682 case 't':
2683 case 'd':
2684 /* Make the current time/date into a string. */
2685 {
2686 time_t the_time = time (0);
2687 char *ttemp = ctime (&the_time);
2688 temp = savestring (ttemp);
2689
2690 if (c == 't')
2691 {
2692 strcpy (temp, temp + 11);
2693 temp[8] = '\0';
2694 }
2695 else
2696 temp[10] = '\0';
2697
2698 goto add_string;
2699 }
2700
2701 case 'n':
2702 if (!no_line_editing)
2703 temp = savestring ("\r\n");
2704 else
2705 temp = savestring ("\n");
2706 goto add_string;
2707
2708 case 's':
2709 {
2710 temp = base_pathname (shell_name);
2711 temp = savestring (temp);
2712 goto add_string;
2713 }
2714
2715 case 'w':
2716 case 'W':
2717 {
2718 /* Use the value of PWD because it is much more effecient. */
2719 #define EFFICIENT
2720 #if defined(EFFICIENT)
2721 char *polite_directory_format (), t_string[MAXPATHLEN];
2722
2723 temp = get_string_value ("PWD");
2724
2725 if (!temp)
2726 getwd (t_string);
2727 else
2728 strcpy (t_string, temp);
2729 #else
2730 getwd (t_string);
2731 #endif /* EFFICIENT */
2732
2733 if (c == 'W')
2734 {
2735 char *dir = (char *)strrchr (t_string, '/');
2736 if (dir && dir != t_string)
2737 strcpy (t_string, dir + 1);
2738 temp = savestring (t_string);
2739 }
2740 else
2741 temp = savestring (polite_directory_format (t_string));
2742 goto add_string;
2743 }
2744
2745 case 'u':
2746 {
2747 temp = savestring (current_user.user_name);
2748 goto add_string;
2749 }
2750
2751 case 'h':
2752 {
2753 char *t_string;
2754
2755 temp = savestring (current_host_name);
2756 if (t_string = (char *)strchr (temp, '.'))
2757 *t_string = '\0';
2758 goto add_string;
2759 }
2760
2761 case '#':
2762 {
2763 temp = itos (current_command_number);
2764 goto add_string;
2765 }
2766
2767 case '!':
2768 {
2769 #if !defined (HISTORY)
2770 temp = savestring ("1");
2771 #else /* HISTORY */
2772 temp = itos (history_number ());
2773 #endif /* HISTORY */
2774 goto add_string;
2775 }
2776
2777 case '$':
2778 temp = savestring (geteuid () == 0 ? "#" : "$");
2779 goto add_string;
2780
2781 #if defined (READLINE)
2782 case '[':
2783 case ']':
2784 temp = xmalloc(3);
2785 temp[0] = '\001';
2786 temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
2787 temp[2] = '\0';
2788 goto add_string;
2789 #endif
2790
2791 case '\\':
2792 temp = savestring ("\\");
2793 goto add_string;
2794
2795 default:
2796 temp = savestring ("\\ ");
2797 temp[1] = c;
2798
2799 add_string:
2800 if (c)
2801 string++;
2802 result =
2803 sub_append_string (temp, result, &result_index, &result_size);
2804 temp = (char *)NULL; /* Free ()'ed in sub_append_string (). */
2805 result[result_index] = '\0';
2806 break;
2807 }
2808 }
2809 else
2810 {
2811 while (3 + result_index > result_size)
2812 result = xrealloc (result, result_size += PROMPT_GROWTH);
2813
2814 result[result_index++] = c;
2815 result[result_index] = '\0';
2816 }
2817 }
2818 #else /* !PROMPT_STRING_DECODE */
2819 result = savestring (string);
2820 #endif /* !PROMPT_STRING_DECODE */
2821
2822 /* Perform variable and parameter expansion and command substitution on
2823 the prompt string. */
2824 list = expand_string_unsplit (result, 1);
2825 free (result);
2826 result = string_list (list);
2827 dispose_words (list);
2828
2829 return (result);
2830 }
2831
2832 /* Report a syntax error, and restart the parser. Call here for fatal
2833 errors. */
yyerror()2834 yyerror ()
2835 {
2836 report_syntax_error ((char *)NULL);
2837 reset_parser ();
2838 }
2839
2840 /* Report a syntax error with line numbers, etc.
2841 Call here for recoverable errors. If you have a message to print,
2842 then place it in MESSAGE, otherwise pass NULL and this will figure
2843 out an appropriate message for you. */
2844 static void
report_syntax_error(message)2845 report_syntax_error (message)
2846 char *message;
2847 {
2848 if (message)
2849 {
2850 if (!interactive)
2851 {
2852 char *name = bash_input.name ? bash_input.name : "stdin";
2853 report_error ("%s: line %d: `%s'", name, line_number, message);
2854 }
2855 else
2856 {
2857 if (EOF_Reached)
2858 EOF_Reached = 0;
2859 report_error ("%s", message);
2860 }
2861
2862 last_command_exit_value = EX_USAGE;
2863 return;
2864 }
2865
2866 if (shell_input_line && *shell_input_line)
2867 {
2868 char *t = shell_input_line;
2869 register int i = shell_input_line_index;
2870 int token_end = 0;
2871
2872 if (!t[i] && i)
2873 i--;
2874
2875 while (i && (t[i] == ' ' || t[i] == '\t' || t[i] == '\n'))
2876 i--;
2877
2878 if (i)
2879 token_end = i + 1;
2880
2881 while (i && !member (t[i], " \n\t;|&"))
2882 i--;
2883
2884 while (i != token_end && member (t[i], " \t\n"))
2885 i++;
2886
2887 if (token_end)
2888 {
2889 char *error_token;
2890 error_token = xmalloc (1 + (token_end - i));
2891 strncpy (error_token, t + i, token_end - i);
2892 error_token[token_end - i] = '\0';
2893
2894 report_error ("syntax error near unexpected token `%s'", error_token);
2895 free (error_token);
2896 }
2897 else if ((i == 0) && (token_end == 0)) /* a 1-character token */
2898 {
2899 char etoken[2];
2900 etoken[0] = t[i];
2901 etoken[1] = '\0';
2902
2903 report_error ("syntax error near unexpected token `%s'", etoken);
2904 }
2905
2906 if (!interactive)
2907 {
2908 char *temp = savestring (shell_input_line);
2909 char *name = bash_input.name ? bash_input.name : "stdin";
2910 int l = strlen (temp);
2911
2912 while (l && temp[l - 1] == '\n')
2913 temp[--l] = '\0';
2914
2915 report_error ("%s: line %d: `%s'", name, line_number, temp);
2916 free (temp);
2917 }
2918 }
2919 else
2920 {
2921 char *name, *msg;
2922 if (!interactive)
2923 name = bash_input.name ? bash_input.name : "stdin";
2924 if (EOF_Reached)
2925 msg = "syntax error: unexpected end of file";
2926 else
2927 msg = "syntax error";
2928 if (!interactive)
2929 report_error ("%s: line %d: %s", name, line_number, msg);
2930 else
2931 {
2932 /* This file uses EOF_Reached only for error reporting
2933 when the shell is interactive. Other mechanisms are
2934 used to decide whether or not to exit. */
2935 EOF_Reached = 0;
2936 report_error (msg);
2937 }
2938 }
2939 last_command_exit_value = EX_USAGE;
2940 }
2941
2942 /* ??? Needed function. ??? We have to be able to discard the constructs
2943 created during parsing. In the case of error, we want to return
2944 allocated objects to the memory pool. In the case of no error, we want
2945 to throw away the information about where the allocated objects live.
2946 (dispose_command () will actually free the command. */
discard_parser_constructs(error_p)2947 discard_parser_constructs (error_p)
2948 int error_p;
2949 {
2950 }
2951
2952 /* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */
2953
2954 /* A flag denoting whether or not ignoreeof is set. */
2955 int ignoreeof = 0;
2956
2957 /* The number of times that we have encountered an EOF character without
2958 another character intervening. When this gets above the limit, the
2959 shell terminates. */
2960 int eof_encountered = 0;
2961
2962 /* The limit for eof_encountered. */
2963 int eof_encountered_limit = 10;
2964
2965 /* If we have EOF as the only input unit, this user wants to leave
2966 the shell. If the shell is not interactive, then just leave.
2967 Otherwise, if ignoreeof is set, and we haven't done this the
2968 required number of times in a row, print a message. */
2969 static void
handle_eof_input_unit()2970 handle_eof_input_unit ()
2971 {
2972 if (interactive)
2973 {
2974 /* shell.c may use this to decide whether or not to write out the
2975 history, among other things. We use it only for error reporting
2976 in this file. */
2977 if (EOF_Reached)
2978 EOF_Reached = 0;
2979
2980 /* If the user wants to "ignore" eof, then let her do so, kind of. */
2981 if (ignoreeof)
2982 {
2983 if (eof_encountered < eof_encountered_limit)
2984 {
2985 fprintf (stderr, "Use \"%s\" to leave the shell.\n",
2986 login_shell ? "logout" : "exit");
2987 eof_encountered++;
2988 /* Reset the prompt string to be $PS1. */
2989 prompt_string_pointer = (char **)NULL;
2990 prompt_again ();
2991 last_read_token = current_token = '\n';
2992 return;
2993 }
2994 }
2995
2996 /* In this case EOF should exit the shell. Do it now. */
2997 reset_parser ();
2998 exit_builtin ((WORD_LIST *)NULL);
2999 }
3000 else
3001 {
3002 /* We don't write history files, etc., for non-interactive shells. */
3003 EOF_Reached = 1;
3004 }
3005 }
3006