aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c46
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... */
2491static const char *expandstr(const char *ps); 2491static 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 */
2493static void 2503static void
2494setprompt_if(smallint do_set, int whichprompt) 2504setprompt_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
2850static int 2853static 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
11531static ALWAYS_INLINE int
11532realeofmark(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 */
11769checkend: { 11781checkend: {
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 */
12478static const char * 12487static const char *
12479expandstr(const char *ps) 12488expandstr(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)
13548static void 13556static void
13549read_profile(const char *name) 13557read_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);