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