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