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