diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/shell/ash.c b/shell/ash.c index 2bfec83e6..3184249f5 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2488,8 +2488,18 @@ putprompt(const char *s) | |||
2488 | #endif | 2488 | #endif |
2489 | 2489 | ||
2490 | /* expandstr() needs parsing machinery, so it is far away ahead... */ | 2490 | /* expandstr() needs parsing machinery, so it is far away ahead... */ |
2491 | static const char *expandstr(const char *ps); | 2491 | static const char *expandstr(const char *ps, int syntax_type); |
2492 | /* Values for syntax param */ | ||
2493 | #define BASESYNTAX 0 /* not in quotes */ | ||
2494 | #define DQSYNTAX 1 /* in double quotes */ | ||
2495 | #define SQSYNTAX 2 /* in single quotes */ | ||
2496 | #define ARISYNTAX 3 /* in arithmetic */ | ||
2497 | #define PSSYNTAX 4 /* prompt. never passed to SIT() */ | ||
2498 | /* PSSYNTAX expansion is identical to DQSYNTAX, except keeping '\$' as '\$' */ | ||
2492 | 2499 | ||
2500 | /* | ||
2501 | * called by editline -- any expansions to the prompt should be added here. | ||
2502 | */ | ||
2493 | static void | 2503 | static void |
2494 | setprompt_if(smallint do_set, int whichprompt) | 2504 | setprompt_if(smallint do_set, int whichprompt) |
2495 | { | 2505 | { |
@@ -2513,7 +2523,7 @@ setprompt_if(smallint do_set, int whichprompt) | |||
2513 | } | 2523 | } |
2514 | #if ENABLE_ASH_EXPAND_PRMT | 2524 | #if ENABLE_ASH_EXPAND_PRMT |
2515 | pushstackmark(&smark, stackblocksize()); | 2525 | pushstackmark(&smark, stackblocksize()); |
2516 | putprompt(expandstr(prompt)); | 2526 | putprompt(expandstr(prompt, PSSYNTAX)); |
2517 | popstackmark(&smark); | 2527 | popstackmark(&smark); |
2518 | #else | 2528 | #else |
2519 | putprompt(prompt); | 2529 | putprompt(prompt); |
@@ -2838,13 +2848,6 @@ enum { | |||
2838 | /* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF, | 2848 | /* c in SIT(c, syntax) must be an *unsigned char* or PEOA or PEOF, |
2839 | * caller must ensure proper cast on it if c is *char_ptr! | 2849 | * caller must ensure proper cast on it if c is *char_ptr! |
2840 | */ | 2850 | */ |
2841 | /* Values for syntax param */ | ||
2842 | #define BASESYNTAX 0 /* not in quotes */ | ||
2843 | #define DQSYNTAX 1 /* in double quotes */ | ||
2844 | #define SQSYNTAX 2 /* in single quotes */ | ||
2845 | #define ARISYNTAX 3 /* in arithmetic */ | ||
2846 | #define PSSYNTAX 4 /* prompt. never passed to SIT() */ | ||
2847 | |||
2848 | #if USE_SIT_FUNCTION | 2851 | #if USE_SIT_FUNCTION |
2849 | 2852 | ||
2850 | static int | 2853 | static int |
@@ -9709,7 +9712,7 @@ evalcommand(union node *cmd, int flags) | |||
9709 | if (xflag) { | 9712 | if (xflag) { |
9710 | const char *pfx = ""; | 9713 | const char *pfx = ""; |
9711 | 9714 | ||
9712 | fdprintf(preverrout_fd, "%s", expandstr(ps4val())); | 9715 | fdprintf(preverrout_fd, "%s", expandstr(ps4val(), DQSYNTAX)); |
9713 | 9716 | ||
9714 | sp = varlist.list; | 9717 | sp = varlist.list; |
9715 | while (sp) { | 9718 | while (sp) { |
@@ -11522,6 +11525,15 @@ decode_dollar_squote(void) | |||
11522 | } | 11525 | } |
11523 | #endif | 11526 | #endif |
11524 | 11527 | ||
11528 | /* Used by expandstr to get here-doc like behaviour. */ | ||
11529 | #define FAKEEOFMARK ((char*)(uintptr_t)1) | ||
11530 | |||
11531 | static ALWAYS_INLINE int | ||
11532 | realeofmark(const char *eofmark) | ||
11533 | { | ||
11534 | return eofmark && eofmark != FAKEEOFMARK; | ||
11535 | } | ||
11536 | |||
11525 | /* | 11537 | /* |
11526 | * If eofmark is NULL, read a word or a redirection symbol. If eofmark | 11538 | * If eofmark is NULL, read a word or a redirection symbol. If eofmark |
11527 | * is not NULL, read a here document. In the latter case, eofmark is the | 11539 | * is not NULL, read a here document. In the latter case, eofmark is the |
@@ -11767,7 +11779,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11767 | * we are at the end of the here document, this routine sets the c to PEOF. | 11779 | * we are at the end of the here document, this routine sets the c to PEOF. |
11768 | */ | 11780 | */ |
11769 | checkend: { | 11781 | checkend: { |
11770 | if (eofmark) { | 11782 | if (realeofmark(eofmark)) { |
11771 | int markloc; | 11783 | int markloc; |
11772 | char *p; | 11784 | char *p; |
11773 | 11785 | ||
@@ -12472,22 +12484,18 @@ parseheredoc(void) | |||
12472 | } | 12484 | } |
12473 | 12485 | ||
12474 | 12486 | ||
12475 | /* | ||
12476 | * called by editline -- any expansions to the prompt should be added here. | ||
12477 | */ | ||
12478 | static const char * | 12487 | static const char * |
12479 | expandstr(const char *ps) | 12488 | expandstr(const char *ps, int syntax_type) |
12480 | { | 12489 | { |
12481 | union node n; | 12490 | union node n; |
12482 | int saveprompt; | 12491 | int saveprompt; |
12483 | 12492 | ||
12484 | /* XXX Fix (char *) cast. It _is_ a bug. ps is variable's value, | 12493 | /* XXX Fix (char *) cast. */ |
12485 | * and token processing _can_ alter it (delete NULs etc). */ | ||
12486 | setinputstring((char *)ps); | 12494 | setinputstring((char *)ps); |
12487 | 12495 | ||
12488 | saveprompt = doprompt; | 12496 | saveprompt = doprompt; |
12489 | doprompt = 0; | 12497 | doprompt = 0; |
12490 | readtoken1(pgetc(), PSSYNTAX, nullstr, 0); | 12498 | readtoken1(pgetc(), syntax_type, FAKEEOFMARK, 0); |
12491 | doprompt = saveprompt; | 12499 | doprompt = saveprompt; |
12492 | 12500 | ||
12493 | popfile(); | 12501 | popfile(); |
@@ -13548,7 +13556,7 @@ procargs(char **argv) | |||
13548 | static void | 13556 | static void |
13549 | read_profile(const char *name) | 13557 | read_profile(const char *name) |
13550 | { | 13558 | { |
13551 | name = expandstr(name); | 13559 | name = expandstr(name, DQSYNTAX); |
13552 | if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0) | 13560 | if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0) |
13553 | return; | 13561 | return; |
13554 | cmdloop(0); | 13562 | cmdloop(0); |