summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/input.c33
-rw-r--r--Src/lex.c4
-rw-r--r--Src/zsh.h1
3 files changed, 36 insertions, 2 deletions
diff --git a/Src/input.c b/Src/input.c
index 9520fdd6d..f919e5757 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -330,8 +330,37 @@ inputline(void)
}
}
isfirstch = 1;
- /* Put this into the input channel. */
- inputsetline(ingetcline, INP_FREE);
+ if ((inbufflags & INP_APPEND) && inbuf) {
+ /*
+ * We need new input but need to be able to back up
+ * over the old input, so append this line.
+ * Pushing the line onto the stack doesn't have the right
+ * effect.
+ *
+ * This is quite a simple and inefficient fix, but currently
+ * we only need it when backing up over a multi-line $((...
+ * that turned out to be a command substitution rather than
+ * a math substitution, which is a very special case.
+ * So it's not worth rewriting.
+ */
+ char *oinbuf = inbuf;
+ int newlen = strlen(ingetcline);
+ int oldlen = (int)(inbufptr - inbuf) + inbufleft;
+ if (inbufflags & INP_FREE) {
+ inbuf = realloc(inbuf, oldlen + newlen + 1);
+ inbufptr += inbuf - oinbuf;
+ strcpy(inbuf + oldlen, ingetcline);
+ } else {
+ /* Paranoia: don't think this is used */
+ DPUTS(1, "Appending to unallocated input line.");
+ }
+ inbufleft += newlen;
+ inbufct += newlen;
+ inbufflags |= INP_FREE;
+ } else {
+ /* Put this into the input channel. */
+ inputsetline(ingetcline, INP_FREE);
+ }
return 0;
}
diff --git a/Src/lex.c b/Src/lex.c
index 91628d4c2..006848543 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -483,9 +483,13 @@ cmd_or_math(int cs_type)
{
int oldlen = lexbuf.len;
int c;
+ int oinflags = inbufflags;
cmdpush(cs_type);
+ inbufflags |= INP_APPEND;
c = dquote_parse(')', 0);
+ if (!(oinflags & INP_APPEND))
+ inbufflags &= ~INP_APPEND;
cmdpop();
*lexbuf.ptr = '\0';
if (!c) {
diff --git a/Src/zsh.h b/Src/zsh.h
index 94e9ffc9f..dd946d214 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -410,6 +410,7 @@ enum {
#define INP_CONT (1<<3) /* continue onto previously stacked input */
#define INP_ALCONT (1<<4) /* stack is continued from alias expn. */
#define INP_LINENO (1<<5) /* update line number */
+#define INP_APPEND (1<<6) /* Append new lines to allow backup */
/* Flags for metafy */
#define META_REALLOC 0