diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-03-24 05:25:59 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-03-24 05:25:59 +0100 |
| commit | 3eab24e64a65746ed9fcc5bed3e9a19a489b0573 (patch) | |
| tree | d22ebcecadb99fcb4ec94f1b461b39e3910a014c /shell | |
| parent | 68d5cb5dacbc80347119ac9cff365e5f04105ef1 (diff) | |
| download | busybox-w32-3eab24e64a65746ed9fcc5bed3e9a19a489b0573.tar.gz busybox-w32-3eab24e64a65746ed9fcc5bed3e9a19a489b0573.tar.bz2 busybox-w32-3eab24e64a65746ed9fcc5bed3e9a19a489b0573.zip | |
hush: make parse errors in sourced file non-fatal in interactive script
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/shell/hush.c b/shell/hush.c index 8154ac47b..e4c3a7d77 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -1095,17 +1095,10 @@ static void syntax_error_unterm_str(unsigned lineno, const char *s) | |||
| 1095 | die_if_script(lineno, "syntax error: unterminated %s", s); | 1095 | die_if_script(lineno, "syntax error: unterminated %s", s); |
| 1096 | } | 1096 | } |
| 1097 | 1097 | ||
| 1098 | /* It so happens that all such cases are totally fatal | ||
| 1099 | * even if shell is interactive: EOF while looking for closing | ||
| 1100 | * delimiter. There is nowhere to read stuff from after that, | ||
| 1101 | * it's EOF! The only choice is to terminate. | ||
| 1102 | */ | ||
| 1103 | static void syntax_error_unterm_ch(unsigned lineno, char ch) NORETURN; | ||
| 1104 | static void syntax_error_unterm_ch(unsigned lineno, char ch) | 1098 | static void syntax_error_unterm_ch(unsigned lineno, char ch) |
| 1105 | { | 1099 | { |
| 1106 | char msg[2] = { ch, '\0' }; | 1100 | char msg[2] = { ch, '\0' }; |
| 1107 | syntax_error_unterm_str(lineno, msg); | 1101 | syntax_error_unterm_str(lineno, msg); |
| 1108 | xfunc_die(); | ||
| 1109 | } | 1102 | } |
| 1110 | 1103 | ||
| 1111 | static void syntax_error_unexpected_ch(unsigned lineno, int ch) | 1104 | static void syntax_error_unexpected_ch(unsigned lineno, int ch) |
| @@ -3539,39 +3532,40 @@ static int parse_group(o_string *dest, struct parse_context *ctx, | |||
| 3539 | 3532 | ||
| 3540 | #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS | 3533 | #if ENABLE_HUSH_TICK || ENABLE_SH_MATH_SUPPORT || ENABLE_HUSH_DOLLAR_OPS |
| 3541 | /* Subroutines for copying $(...) and `...` things */ | 3534 | /* Subroutines for copying $(...) and `...` things */ |
| 3542 | static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); | 3535 | static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote); |
| 3543 | /* '...' */ | 3536 | /* '...' */ |
| 3544 | static void add_till_single_quote(o_string *dest, struct in_str *input) | 3537 | static int add_till_single_quote(o_string *dest, struct in_str *input) |
| 3545 | { | 3538 | { |
| 3546 | while (1) { | 3539 | while (1) { |
| 3547 | int ch = i_getch(input); | 3540 | int ch = i_getch(input); |
| 3548 | if (ch == EOF) { | 3541 | if (ch == EOF) { |
| 3549 | syntax_error_unterm_ch('\''); | 3542 | syntax_error_unterm_ch('\''); |
| 3550 | /*xfunc_die(); - redundant */ | 3543 | return 0; |
| 3551 | } | 3544 | } |
| 3552 | if (ch == '\'') | 3545 | if (ch == '\'') |
| 3553 | return; | 3546 | return 1; |
| 3554 | o_addchr(dest, ch); | 3547 | o_addchr(dest, ch); |
| 3555 | } | 3548 | } |
| 3556 | } | 3549 | } |
| 3557 | /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */ | 3550 | /* "...\"...`..`...." - do we need to handle "...$(..)..." too? */ |
| 3558 | static void add_till_double_quote(o_string *dest, struct in_str *input) | 3551 | static int add_till_double_quote(o_string *dest, struct in_str *input) |
| 3559 | { | 3552 | { |
| 3560 | while (1) { | 3553 | while (1) { |
| 3561 | int ch = i_getch(input); | 3554 | int ch = i_getch(input); |
| 3562 | if (ch == EOF) { | 3555 | if (ch == EOF) { |
| 3563 | syntax_error_unterm_ch('"'); | 3556 | syntax_error_unterm_ch('"'); |
| 3564 | /*xfunc_die(); - redundant */ | 3557 | return 0; |
| 3565 | } | 3558 | } |
| 3566 | if (ch == '"') | 3559 | if (ch == '"') |
| 3567 | return; | 3560 | return 1; |
| 3568 | if (ch == '\\') { /* \x. Copy both chars. */ | 3561 | if (ch == '\\') { /* \x. Copy both chars. */ |
| 3569 | o_addchr(dest, ch); | 3562 | o_addchr(dest, ch); |
| 3570 | ch = i_getch(input); | 3563 | ch = i_getch(input); |
| 3571 | } | 3564 | } |
| 3572 | o_addchr(dest, ch); | 3565 | o_addchr(dest, ch); |
| 3573 | if (ch == '`') { | 3566 | if (ch == '`') { |
| 3574 | add_till_backquote(dest, input, /*in_dquote:*/ 1); | 3567 | if (!add_till_backquote(dest, input, /*in_dquote:*/ 1)) |
| 3568 | return 0; | ||
| 3575 | o_addchr(dest, ch); | 3569 | o_addchr(dest, ch); |
| 3576 | continue; | 3570 | continue; |
| 3577 | } | 3571 | } |
| @@ -3592,12 +3586,12 @@ static void add_till_double_quote(o_string *dest, struct in_str *input) | |||
| 3592 | * Example Output | 3586 | * Example Output |
| 3593 | * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST | 3587 | * echo `echo '\'TEST\`echo ZZ\`BEST` \TESTZZBEST |
| 3594 | */ | 3588 | */ |
| 3595 | static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquote) | 3589 | static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote) |
| 3596 | { | 3590 | { |
| 3597 | while (1) { | 3591 | while (1) { |
| 3598 | int ch = i_getch(input); | 3592 | int ch = i_getch(input); |
| 3599 | if (ch == '`') | 3593 | if (ch == '`') |
| 3600 | return; | 3594 | return 1; |
| 3601 | if (ch == '\\') { | 3595 | if (ch == '\\') { |
| 3602 | /* \x. Copy both unless it is \`, \$, \\ and maybe \" */ | 3596 | /* \x. Copy both unless it is \`, \$, \\ and maybe \" */ |
| 3603 | ch = i_getch(input); | 3597 | ch = i_getch(input); |
| @@ -3611,7 +3605,7 @@ static void add_till_backquote(o_string *dest, struct in_str *input, int in_dquo | |||
| 3611 | } | 3605 | } |
| 3612 | if (ch == EOF) { | 3606 | if (ch == EOF) { |
| 3613 | syntax_error_unterm_ch('`'); | 3607 | syntax_error_unterm_ch('`'); |
| 3614 | /*xfunc_die(); - redundant */ | 3608 | return 0; |
| 3615 | } | 3609 | } |
| 3616 | o_addchr(dest, ch); | 3610 | o_addchr(dest, ch); |
| 3617 | } | 3611 | } |
| @@ -3647,7 +3641,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
| 3647 | ch = i_getch(input); | 3641 | ch = i_getch(input); |
| 3648 | if (ch == EOF) { | 3642 | if (ch == EOF) { |
| 3649 | syntax_error_unterm_ch(end_ch); | 3643 | syntax_error_unterm_ch(end_ch); |
| 3650 | /*xfunc_die(); - redundant */ | 3644 | return 0; |
| 3651 | } | 3645 | } |
| 3652 | if (ch == end_ch IF_HUSH_BASH_COMPAT( || ch == end_char2)) { | 3646 | if (ch == end_ch IF_HUSH_BASH_COMPAT( || ch == end_char2)) { |
| 3653 | if (!dbl) | 3647 | if (!dbl) |
| @@ -3661,22 +3655,26 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
| 3661 | o_addchr(dest, ch); | 3655 | o_addchr(dest, ch); |
| 3662 | if (ch == '(' || ch == '{') { | 3656 | if (ch == '(' || ch == '{') { |
| 3663 | ch = (ch == '(' ? ')' : '}'); | 3657 | ch = (ch == '(' ? ')' : '}'); |
| 3664 | add_till_closing_bracket(dest, input, ch); | 3658 | if (!add_till_closing_bracket(dest, input, ch)) |
| 3659 | return 0; | ||
| 3665 | o_addchr(dest, ch); | 3660 | o_addchr(dest, ch); |
| 3666 | continue; | 3661 | continue; |
| 3667 | } | 3662 | } |
| 3668 | if (ch == '\'') { | 3663 | if (ch == '\'') { |
| 3669 | add_till_single_quote(dest, input); | 3664 | if (!add_till_single_quote(dest, input)) |
| 3665 | return 0; | ||
| 3670 | o_addchr(dest, ch); | 3666 | o_addchr(dest, ch); |
| 3671 | continue; | 3667 | continue; |
| 3672 | } | 3668 | } |
| 3673 | if (ch == '"') { | 3669 | if (ch == '"') { |
| 3674 | add_till_double_quote(dest, input); | 3670 | if (!add_till_double_quote(dest, input)) |
| 3671 | return 0; | ||
| 3675 | o_addchr(dest, ch); | 3672 | o_addchr(dest, ch); |
| 3676 | continue; | 3673 | continue; |
| 3677 | } | 3674 | } |
| 3678 | if (ch == '`') { | 3675 | if (ch == '`') { |
| 3679 | add_till_backquote(dest, input, /*in_dquote:*/ 0); | 3676 | if (!add_till_backquote(dest, input, /*in_dquote:*/ 0)) |
| 3677 | return 0; | ||
| 3680 | o_addchr(dest, ch); | 3678 | o_addchr(dest, ch); |
| 3681 | continue; | 3679 | continue; |
| 3682 | } | 3680 | } |
| @@ -3685,7 +3683,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
| 3685 | ch = i_getch(input); | 3683 | ch = i_getch(input); |
| 3686 | if (ch == EOF) { | 3684 | if (ch == EOF) { |
| 3687 | syntax_error_unterm_ch(')'); | 3685 | syntax_error_unterm_ch(')'); |
| 3688 | /*xfunc_die(); - redundant */ | 3686 | return 0; |
| 3689 | } | 3687 | } |
| 3690 | o_addchr(dest, ch); | 3688 | o_addchr(dest, ch); |
| 3691 | continue; | 3689 | continue; |
| @@ -3756,8 +3754,8 @@ static int parse_dollar(o_string *as_string, | |||
| 3756 | ) { | 3754 | ) { |
| 3757 | bad_dollar_syntax: | 3755 | bad_dollar_syntax: |
| 3758 | syntax_error_unterm_str("${name}"); | 3756 | syntax_error_unterm_str("${name}"); |
| 3759 | debug_printf_parse("parse_dollar return 1: unterminated ${name}\n"); | 3757 | debug_printf_parse("parse_dollar return 0: unterminated ${name}\n"); |
| 3760 | return 1; | 3758 | return 0; |
| 3761 | } | 3759 | } |
| 3762 | nommu_addchr(as_string, ch); | 3760 | nommu_addchr(as_string, ch); |
| 3763 | ch |= quote_mask; | 3761 | ch |= quote_mask; |
| @@ -3813,6 +3811,8 @@ static int parse_dollar(o_string *as_string, | |||
| 3813 | pos = dest->length; | 3811 | pos = dest->length; |
| 3814 | #if ENABLE_HUSH_DOLLAR_OPS | 3812 | #if ENABLE_HUSH_DOLLAR_OPS |
| 3815 | last_ch = add_till_closing_bracket(dest, input, end_ch); | 3813 | last_ch = add_till_closing_bracket(dest, input, end_ch); |
| 3814 | if (last_ch == 0) /* error? */ | ||
| 3815 | return 0; | ||
| 3816 | #else | 3816 | #else |
| 3817 | #error Simple code to only allow ${var} is not implemented | 3817 | #error Simple code to only allow ${var} is not implemented |
| 3818 | #endif | 3818 | #endif |
| @@ -3857,7 +3857,8 @@ static int parse_dollar(o_string *as_string, | |||
| 3857 | o_addchr(dest, /*quote_mask |*/ '+'); | 3857 | o_addchr(dest, /*quote_mask |*/ '+'); |
| 3858 | if (!BB_MMU) | 3858 | if (!BB_MMU) |
| 3859 | pos = dest->length; | 3859 | pos = dest->length; |
| 3860 | add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG); | 3860 | if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG)) |
| 3861 | return 0; /* error */ | ||
| 3861 | if (as_string) { | 3862 | if (as_string) { |
| 3862 | o_addstr(as_string, dest->data + pos); | 3863 | o_addstr(as_string, dest->data + pos); |
| 3863 | o_addchr(as_string, ')'); | 3864 | o_addchr(as_string, ')'); |
| @@ -3872,7 +3873,8 @@ static int parse_dollar(o_string *as_string, | |||
| 3872 | o_addchr(dest, quote_mask | '`'); | 3873 | o_addchr(dest, quote_mask | '`'); |
| 3873 | if (!BB_MMU) | 3874 | if (!BB_MMU) |
| 3874 | pos = dest->length; | 3875 | pos = dest->length; |
| 3875 | add_till_closing_bracket(dest, input, ')'); | 3876 | if (!add_till_closing_bracket(dest, input, ')')) |
| 3877 | return 0; /* error */ | ||
| 3876 | if (as_string) { | 3878 | if (as_string) { |
| 3877 | o_addstr(as_string, dest->data + pos); | 3879 | o_addstr(as_string, dest->data + pos); |
| 3878 | o_addchr(as_string, ')'); | 3880 | o_addchr(as_string, ')'); |
| @@ -3899,8 +3901,8 @@ static int parse_dollar(o_string *as_string, | |||
| 3899 | default: | 3901 | default: |
| 3900 | o_addQchr(dest, '$'); | 3902 | o_addQchr(dest, '$'); |
| 3901 | } | 3903 | } |
| 3902 | debug_printf_parse("parse_dollar return 0\n"); | 3904 | debug_printf_parse("parse_dollar return 1 (ok)\n"); |
| 3903 | return 0; | 3905 | return 1; |
| 3904 | #undef as_string | 3906 | #undef as_string |
| 3905 | } | 3907 | } |
| 3906 | 3908 | ||
| @@ -3941,13 +3943,13 @@ static int encode_string(o_string *as_string, | |||
| 3941 | if (ch != EOF) | 3943 | if (ch != EOF) |
| 3942 | nommu_addchr(as_string, ch); | 3944 | nommu_addchr(as_string, ch); |
| 3943 | if (ch == dquote_end) { /* may be only '"' or EOF */ | 3945 | if (ch == dquote_end) { /* may be only '"' or EOF */ |
| 3944 | debug_printf_parse("encode_string return 0\n"); | 3946 | debug_printf_parse("encode_string return 1 (ok)\n"); |
| 3945 | return 0; | 3947 | return 1; |
| 3946 | } | 3948 | } |
| 3947 | /* note: can't move it above ch == dquote_end check! */ | 3949 | /* note: can't move it above ch == dquote_end check! */ |
| 3948 | if (ch == EOF) { | 3950 | if (ch == EOF) { |
| 3949 | syntax_error_unterm_ch('"'); | 3951 | syntax_error_unterm_ch('"'); |
| 3950 | /*xfunc_die(); - redundant */ | 3952 | return 0; /* error */ |
| 3951 | } | 3953 | } |
| 3952 | next = '\0'; | 3954 | next = '\0'; |
| 3953 | if (ch != '\n') { | 3955 | if (ch != '\n') { |
| @@ -3978,10 +3980,10 @@ static int encode_string(o_string *as_string, | |||
| 3978 | goto again; | 3980 | goto again; |
| 3979 | } | 3981 | } |
| 3980 | if (ch == '$') { | 3982 | if (ch == '$') { |
| 3981 | if (parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80) != 0) { | 3983 | if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) { |
| 3982 | debug_printf_parse("encode_string return 1: " | 3984 | debug_printf_parse("encode_string return 0: " |
| 3983 | "parse_dollar returned non-0\n"); | 3985 | "parse_dollar returned 0 (error)\n"); |
| 3984 | return 1; | 3986 | return 0; |
| 3985 | } | 3987 | } |
| 3986 | goto again; | 3988 | goto again; |
| 3987 | } | 3989 | } |
| @@ -3990,7 +3992,8 @@ static int encode_string(o_string *as_string, | |||
| 3990 | //unsigned pos = dest->length; | 3992 | //unsigned pos = dest->length; |
| 3991 | o_addchr(dest, SPECIAL_VAR_SYMBOL); | 3993 | o_addchr(dest, SPECIAL_VAR_SYMBOL); |
| 3992 | o_addchr(dest, 0x80 | '`'); | 3994 | o_addchr(dest, 0x80 | '`'); |
| 3993 | add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"'); | 3995 | if (!add_till_backquote(dest, input, /*in_dquote:*/ dquote_end == '"')) |
| 3996 | return 0; /* error */ | ||
| 3994 | o_addchr(dest, SPECIAL_VAR_SYMBOL); | 3997 | o_addchr(dest, SPECIAL_VAR_SYMBOL); |
| 3995 | //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); | 3998 | //debug_printf_subst("SUBST RES3 '%s'\n", dest->data + pos); |
| 3996 | goto again; | 3999 | goto again; |
| @@ -4061,8 +4064,8 @@ static struct pipe *parse_stream(char **pstring, | |||
| 4061 | /* end_trigger == '}' case errors out earlier, | 4064 | /* end_trigger == '}' case errors out earlier, |
| 4062 | * checking only ')' */ | 4065 | * checking only ')' */ |
| 4063 | if (end_trigger == ')') { | 4066 | if (end_trigger == ')') { |
| 4064 | syntax_error_unterm_ch('('); /* exits */ | 4067 | syntax_error_unterm_ch('('); |
| 4065 | /* goto parse_error; */ | 4068 | goto parse_error; |
| 4066 | } | 4069 | } |
| 4067 | 4070 | ||
| 4068 | if (done_word(&dest, &ctx)) { | 4071 | if (done_word(&dest, &ctx)) { |
| @@ -4353,9 +4356,9 @@ static struct pipe *parse_stream(char **pstring, | |||
| 4353 | dest.has_quoted_part = 1; | 4356 | dest.has_quoted_part = 1; |
| 4354 | break; | 4357 | break; |
| 4355 | case '$': | 4358 | case '$': |
| 4356 | if (parse_dollar(&ctx.as_string, &dest, input, /*quote_mask:*/ 0) != 0) { | 4359 | if (!parse_dollar(&ctx.as_string, &dest, input, /*quote_mask:*/ 0)) { |
| 4357 | debug_printf_parse("parse_stream parse error: " | 4360 | debug_printf_parse("parse_stream parse error: " |
| 4358 | "parse_dollar returned non-0\n"); | 4361 | "parse_dollar returned 0 (error)\n"); |
| 4359 | goto parse_error; | 4362 | goto parse_error; |
| 4360 | } | 4363 | } |
| 4361 | break; | 4364 | break; |
| @@ -4365,7 +4368,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 4365 | ch = i_getch(input); | 4368 | ch = i_getch(input); |
| 4366 | if (ch == EOF) { | 4369 | if (ch == EOF) { |
| 4367 | syntax_error_unterm_ch('\''); | 4370 | syntax_error_unterm_ch('\''); |
| 4368 | /*xfunc_die(); - redundant */ | 4371 | goto parse_error; |
| 4369 | } | 4372 | } |
| 4370 | nommu_addchr(&ctx.as_string, ch); | 4373 | nommu_addchr(&ctx.as_string, ch); |
| 4371 | if (ch == '\'') | 4374 | if (ch == '\'') |
| @@ -4377,7 +4380,7 @@ static struct pipe *parse_stream(char **pstring, | |||
| 4377 | dest.has_quoted_part = 1; | 4380 | dest.has_quoted_part = 1; |
| 4378 | if (dest.o_assignment == NOT_ASSIGNMENT) | 4381 | if (dest.o_assignment == NOT_ASSIGNMENT) |
| 4379 | dest.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS; | 4382 | dest.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS; |
| 4380 | if (encode_string(&ctx.as_string, &dest, input, '"', /*process_bkslash:*/ 1)) | 4383 | if (!encode_string(&ctx.as_string, &dest, input, '"', /*process_bkslash:*/ 1)) |
| 4381 | goto parse_error; | 4384 | goto parse_error; |
| 4382 | dest.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS; | 4385 | dest.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS; |
| 4383 | break; | 4386 | break; |
| @@ -4388,7 +4391,8 @@ static struct pipe *parse_stream(char **pstring, | |||
| 4388 | o_addchr(&dest, SPECIAL_VAR_SYMBOL); | 4391 | o_addchr(&dest, SPECIAL_VAR_SYMBOL); |
| 4389 | o_addchr(&dest, '`'); | 4392 | o_addchr(&dest, '`'); |
| 4390 | pos = dest.length; | 4393 | pos = dest.length; |
| 4391 | add_till_backquote(&dest, input, /*in_dquote:*/ 0); | 4394 | if (!add_till_backquote(&dest, input, /*in_dquote:*/ 0)) |
| 4395 | goto parse_error; | ||
| 4392 | # if !BB_MMU | 4396 | # if !BB_MMU |
| 4393 | o_addstr(&ctx.as_string, dest.data + pos); | 4397 | o_addstr(&ctx.as_string, dest.data + pos); |
| 4394 | o_addchr(&ctx.as_string, '`'); | 4398 | o_addchr(&ctx.as_string, '`'); |
| @@ -4664,6 +4668,7 @@ static char *encode_then_expand_string(const char *str, int process_bkslash, int | |||
| 4664 | */ | 4668 | */ |
| 4665 | setup_string_in_str(&input, str); | 4669 | setup_string_in_str(&input, str); |
| 4666 | encode_string(NULL, &dest, &input, EOF, process_bkslash); | 4670 | encode_string(NULL, &dest, &input, EOF, process_bkslash); |
| 4671 | //TODO: error check (encode_string returns 0 on error)? | ||
| 4667 | //bb_error_msg("'%s' -> '%s'", str, dest.data); | 4672 | //bb_error_msg("'%s' -> '%s'", str, dest.data); |
| 4668 | exp_str = expand_string_to_string(dest.data, /*unbackslash:*/ do_unbackslash); | 4673 | exp_str = expand_string_to_string(dest.data, /*unbackslash:*/ do_unbackslash); |
| 4669 | //bb_error_msg("'%s' -> '%s'", dest.data, exp_str); | 4674 | //bb_error_msg("'%s' -> '%s'", dest.data, exp_str); |
| @@ -8625,6 +8630,8 @@ static int FAST_FUNC builtin_source(char **argv) | |||
| 8625 | #endif | 8630 | #endif |
| 8626 | save_and_replace_G_args(&sv, argv); | 8631 | save_and_replace_G_args(&sv, argv); |
| 8627 | 8632 | ||
| 8633 | //TODO: syntax errors in sourced file should never abort the "calling" script. | ||
| 8634 | //Try: bash -c '. ./bad_file; echo YES' | ||
| 8628 | parse_and_run_file(input); | 8635 | parse_and_run_file(input); |
| 8629 | fclose(input); | 8636 | fclose(input); |
| 8630 | 8637 | ||
