diff options
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/shell/ash.c b/shell/ash.c index a63d40d7e..b71fc0299 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -9774,11 +9774,6 @@ popstring(void) | |||
| 9774 | INT_ON; | 9774 | INT_ON; |
| 9775 | } | 9775 | } |
| 9776 | 9776 | ||
| 9777 | //FIXME: BASH_COMPAT with "...&" does TWO pungetc(): | ||
| 9778 | //it peeks whether it is &>, and then pushes back both chars. | ||
| 9779 | //This function needs to save last *next_to_pgetc to buf[0] | ||
| 9780 | //to make two pungetc() reliable. Currently, | ||
| 9781 | // pgetc (out of buf: does preadfd), pgetc, pungetc, pungetc won't work... | ||
| 9782 | static int | 9777 | static int |
| 9783 | preadfd(void) | 9778 | preadfd(void) |
| 9784 | { | 9779 | { |
| @@ -10037,6 +10032,25 @@ pungetc(void) | |||
| 10037 | g_parsefile->unget++; | 10032 | g_parsefile->unget++; |
| 10038 | } | 10033 | } |
| 10039 | 10034 | ||
| 10035 | /* This one eats backslash+newline */ | ||
| 10036 | static int | ||
| 10037 | pgetc_eatbnl(void) | ||
| 10038 | { | ||
| 10039 | int c; | ||
| 10040 | |||
| 10041 | while ((c = pgetc()) == '\\') { | ||
| 10042 | if (pgetc() != '\n') { | ||
| 10043 | pungetc(); | ||
| 10044 | break; | ||
| 10045 | } | ||
| 10046 | |||
| 10047 | g_parsefile->linno++; | ||
| 10048 | setprompt_if(doprompt, 2); | ||
| 10049 | } | ||
| 10050 | |||
| 10051 | return c; | ||
| 10052 | } | ||
| 10053 | |||
| 10040 | /* | 10054 | /* |
| 10041 | * To handle the "." command, a stack of input files is used. Pushfile | 10055 | * To handle the "." command, a stack of input files is used. Pushfile |
| 10042 | * adds a new entry to the stack and popfile restores the previous level. | 10056 | * adds a new entry to the stack and popfile restores the previous level. |
| @@ -11625,7 +11639,7 @@ parsesub: { | |||
| 11625 | int typeloc; | 11639 | int typeloc; |
| 11626 | int flags; | 11640 | int flags; |
| 11627 | 11641 | ||
| 11628 | c = pgetc(); | 11642 | c = pgetc_eatbnl(); |
| 11629 | if (c > 255 /* PEOA or PEOF */ | 11643 | if (c > 255 /* PEOA or PEOF */ |
| 11630 | || (c != '(' && c != '{' && !is_name(c) && !is_special(c)) | 11644 | || (c != '(' && c != '{' && !is_name(c) && !is_special(c)) |
| 11631 | ) { | 11645 | ) { |
| @@ -11638,7 +11652,7 @@ parsesub: { | |||
| 11638 | pungetc(); | 11652 | pungetc(); |
| 11639 | } else if (c == '(') { | 11653 | } else if (c == '(') { |
| 11640 | /* $(command) or $((arith)) */ | 11654 | /* $(command) or $((arith)) */ |
| 11641 | if (pgetc() == '(') { | 11655 | if (pgetc_eatbnl() == '(') { |
| 11642 | #if ENABLE_SH_MATH_SUPPORT | 11656 | #if ENABLE_SH_MATH_SUPPORT |
| 11643 | PARSEARITH(); | 11657 | PARSEARITH(); |
| 11644 | #else | 11658 | #else |
| @@ -11655,9 +11669,9 @@ parsesub: { | |||
| 11655 | USTPUTC(VSNORMAL, out); | 11669 | USTPUTC(VSNORMAL, out); |
| 11656 | subtype = VSNORMAL; | 11670 | subtype = VSNORMAL; |
| 11657 | if (c == '{') { | 11671 | if (c == '{') { |
| 11658 | c = pgetc(); | 11672 | c = pgetc_eatbnl(); |
| 11659 | if (c == '#') { | 11673 | if (c == '#') { |
| 11660 | c = pgetc(); | 11674 | c = pgetc_eatbnl(); |
| 11661 | if (c == '}') | 11675 | if (c == '}') |
| 11662 | c = '#'; /* ${#} - same as $# */ | 11676 | c = '#'; /* ${#} - same as $# */ |
| 11663 | else | 11677 | else |
| @@ -11670,18 +11684,18 @@ parsesub: { | |||
| 11670 | /* $[{[#]]NAME[}] */ | 11684 | /* $[{[#]]NAME[}] */ |
| 11671 | do { | 11685 | do { |
| 11672 | STPUTC(c, out); | 11686 | STPUTC(c, out); |
| 11673 | c = pgetc(); | 11687 | c = pgetc_eatbnl(); |
| 11674 | } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c)); | 11688 | } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c)); |
| 11675 | } else if (isdigit(c)) { | 11689 | } else if (isdigit(c)) { |
| 11676 | /* $[{[#]]NUM[}] */ | 11690 | /* $[{[#]]NUM[}] */ |
| 11677 | do { | 11691 | do { |
| 11678 | STPUTC(c, out); | 11692 | STPUTC(c, out); |
| 11679 | c = pgetc(); | 11693 | c = pgetc_eatbnl(); |
| 11680 | } while (isdigit(c)); | 11694 | } while (isdigit(c)); |
| 11681 | } else if (is_special(c)) { | 11695 | } else if (is_special(c)) { |
| 11682 | /* $[{[#]]<specialchar>[}] */ | 11696 | /* $[{[#]]<specialchar>[}] */ |
| 11683 | USTPUTC(c, out); | 11697 | USTPUTC(c, out); |
| 11684 | c = pgetc(); | 11698 | c = pgetc_eatbnl(); |
| 11685 | } else { | 11699 | } else { |
| 11686 | badsub: | 11700 | badsub: |
| 11687 | raise_error_syntax("bad substitution"); | 11701 | raise_error_syntax("bad substitution"); |
| @@ -11699,7 +11713,7 @@ parsesub: { | |||
| 11699 | /* c == first char after VAR */ | 11713 | /* c == first char after VAR */ |
| 11700 | switch (c) { | 11714 | switch (c) { |
| 11701 | case ':': | 11715 | case ':': |
| 11702 | c = pgetc(); | 11716 | c = pgetc_eatbnl(); |
| 11703 | #if ENABLE_ASH_BASH_COMPAT | 11717 | #if ENABLE_ASH_BASH_COMPAT |
| 11704 | /* This check is only needed to not misinterpret | 11718 | /* This check is only needed to not misinterpret |
| 11705 | * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD} | 11719 | * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD} |
| @@ -11724,7 +11738,7 @@ parsesub: { | |||
| 11724 | case '#': { | 11738 | case '#': { |
| 11725 | int cc = c; | 11739 | int cc = c; |
| 11726 | subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT); | 11740 | subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT); |
| 11727 | c = pgetc(); | 11741 | c = pgetc_eatbnl(); |
| 11728 | if (c != cc) | 11742 | if (c != cc) |
| 11729 | goto do_pungetc; | 11743 | goto do_pungetc; |
| 11730 | subtype++; | 11744 | subtype++; |
| @@ -11736,7 +11750,7 @@ parsesub: { | |||
| 11736 | //TODO: encode pattern and repl separately. | 11750 | //TODO: encode pattern and repl separately. |
| 11737 | // Currently ${v/$var_with_slash/repl} is horribly broken | 11751 | // Currently ${v/$var_with_slash/repl} is horribly broken |
| 11738 | subtype = VSREPLACE; | 11752 | subtype = VSREPLACE; |
| 11739 | c = pgetc(); | 11753 | c = pgetc_eatbnl(); |
| 11740 | if (c != '/') | 11754 | if (c != '/') |
| 11741 | goto do_pungetc; | 11755 | goto do_pungetc; |
| 11742 | subtype++; /* VSREPLACEALL */ | 11756 | subtype++; /* VSREPLACEALL */ |
