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