[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] fix cmd and hist nums in ${var@P} inside $PS[012]
From: |
Grisha Levit |
Subject: |
[PATCH] fix cmd and hist nums in ${var@P} inside $PS[012] |
Date: |
Tue, 26 Mar 2024 09:02:58 -0400 |
When \# or \! is decoded in a ${var@P} expansion embedded in a prompt
string, the value can be off by one from that of the same sequence
embedded directly in the prompt string.
$ H='\!'
$ PS1='(\!:${H@P}) $'
(3:2 501:500) $
* parse.y
- decode_prompt_string: accept new int flag to signify a real prompt
string is being decoded; update callers
* externs.h
- decode_prompt_string: update declaration
---
eval.c | 2 +-
externs.h | 2 +-
parse.y | 23 ++++++++++++++++-------
print_cmd.c | 2 +-
subst.c | 2 +-
5 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/eval.c b/eval.c
index a08cb578..2fee976c 100644
--- a/eval.c
+++ b/eval.c
@@ -157,7 +157,7 @@ reader_loop (void)
old_eof = EOF_Reached;
EOF_Reached = 0;
- ps0_string = decode_prompt_string (ps0_prompt);
+ ps0_string = decode_prompt_string (ps0_prompt, 1);
if (ps0_string && *ps0_string)
{
fprintf (stderr, "%s", ps0_string);
diff --git a/externs.h b/externs.h
index b60fb79e..683c72f6 100644
--- a/externs.h
+++ b/externs.h
@@ -128,7 +128,7 @@ extern void clear_shell_input_line (void);
extern int handle_ignoreeof (int);
-extern char *decode_prompt_string (char *);
+extern char *decode_prompt_string (char *, int);
extern int get_current_prompt_level (void);
extern void set_current_prompt_level (int);
diff --git a/parse.y b/parse.y
index 3e28d24d..3211ea64 100644
--- a/parse.y
+++ b/parse.y
@@ -6036,7 +6036,7 @@ prompt_again (int force)
prompt_string_pointer = &ps1_prompt;
temp_prompt = *prompt_string_pointer
- ? decode_prompt_string (*prompt_string_pointer)
+ ? decode_prompt_string (*prompt_string_pointer, 1)
: (char *)NULL;
if (temp_prompt == 0)
@@ -6139,10 +6139,10 @@ prompt_history_number (char *pmt)
*/
#define PROMPT_GROWTH 48
char *
-decode_prompt_string (char *string)
+decode_prompt_string (char *string, int is_prompt)
{
WORD_LIST *list;
- char *result, *t, *orig_string, *last_lastarg;
+ char *result, *t, *last_lastarg;
struct dstack save_dstack;
int last_exit_value, last_comsub_pid, last_comsub_status;
#if defined (PROMPT_STRING_DECODE)
@@ -6155,11 +6155,16 @@ decode_prompt_string (char *string)
char timebuf[128];
char *timefmt;
size_t tslen;
+ static char *decoding_prompt;
result = (char *)xmalloc (result_size = PROMPT_GROWTH);
result[result_index = 0] = 0;
temp = (char *)NULL;
- orig_string = string;
+
+ /* Keep track of which (real) prompt string is being decoded so that we can
+ process embedded ${var@P} expansions correctly. */
+ if (is_prompt)
+ decoding_prompt = string;
while (c = *string++)
{
@@ -6175,7 +6180,7 @@ decode_prompt_string (char *string)
#if !defined (HISTORY)
temp = savestring ("1");
#else /* HISTORY */
- temp = itos (prompt_history_number (orig_string));
+ temp = itos (prompt_history_number (decoding_prompt));
#endif /* HISTORY */
string--; /* add_string increments string again. */
goto add_string;
@@ -6436,7 +6441,7 @@ decode_prompt_string (char *string)
n = current_command_number;
/* If we have already incremented current_command_number (PS4,
${var@P}), compensate */
- if (orig_string != ps0_prompt && orig_string != ps1_prompt &&
orig_string != ps2_prompt)
+ if (decoding_prompt != ps0_prompt && decoding_prompt !=
ps1_prompt && decoding_prompt != ps2_prompt)
n--;
temp = itos (n);
goto add_string;
@@ -6445,7 +6450,7 @@ decode_prompt_string (char *string)
#if !defined (HISTORY)
temp = savestring ("1");
#else /* HISTORY */
- temp = itos (prompt_history_number (orig_string));
+ temp = itos (prompt_history_number (decoding_prompt));
#endif /* HISTORY */
goto add_string;
@@ -6570,6 +6575,10 @@ not_escape:
}
dstack = save_dstack;
+#if defined (PROMPT_STRING_DECODE)
+ if (is_prompt)
+ decoding_prompt = (char *)NULL;
+#endif
return (result);
}
diff --git a/print_cmd.c b/print_cmd.c
index 9d3ab73b..36268e19 100644
--- a/print_cmd.c
+++ b/print_cmd.c
@@ -460,7 +460,7 @@ indirection_level_string (void)
return (indirection_string);
old = change_flag ('x', FLAG_OFF);
- ps4 = decode_prompt_string (ps4);
+ ps4 = decode_prompt_string (ps4, 1);
if (old)
change_flag ('x', FLAG_ON);
diff --git a/subst.c b/subst.c
index 2c51021b..ee0afd67 100644
--- a/subst.c
+++ b/subst.c
@@ -8745,7 +8745,7 @@ string_transform (int xc, SHELL_VAR *v, char *s)
ret = ansicstr (s, strlen (s), 0, 0, 0);
break;
case 'P':
- ret = decode_prompt_string (s);
+ ret = decode_prompt_string (s, 0);
break;
case 'Q':
ret = sh_quote_reusable (s, 0);
--
2.44.0
- [PATCH] fix cmd and hist nums in ${var@P} inside $PS[012],
Grisha Levit <=