[PATCH 3/5] [cmd] Support for ^ character at end of line
Ann and Jason Edmeades
jason at edmeades.me.uk
Tue Sep 25 18:07:37 CDT 2012
This adds support for the ^ character joining lines. Its initially based
on a patch by John Chow added to bug 18346 (attachment 26812) but extended
in order to support an edge case which was highlighted by tests.
[Fixes rest of bug 18346]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20120926/3a0a56b8/attachment-0001.html>
-------------- next part --------------
From 8404b450d86cc6c67562e9073b9f2eab4248365c Mon Sep 17 00:00:00 2001
From: Jason Edmeades <jason at edmeades.me.uk>
Date: Tue, 25 Sep 2012 21:02:09 +0100
Subject: [PATCH 3/5] [cmd] Support for ^ character at end of line
This adds support for the ^ character joining lines. Its initially based
on a patch by John Chow added to bug 18346 (attachment 26812) but extended
in order to support an edge case which was highlighted by tests.
[Fixes rest of bug 18346]
---
programs/cmd/tests/test_builtins.cmd | 9 ++++++
programs/cmd/tests/test_builtins.cmd.exp | 6 ++++
programs/cmd/wcmdmain.c | 52 +++++++++++++++++++++++++-----
3 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 444b6e6..27a8672 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -197,6 +197,15 @@ echo ^hell^o, world
echo hell^o, world
echo hell^^o, world
echo hell^^^o, world
+echo hello^
+world
+echo hello^
+
+world
+echo hello^
+
+
+echo finished
mkdir foobar
echo baz> foobar\baz
type foobar\baz
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index b019280..2888ffc 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -201,6 +201,12 @@ hello, world
hello, world
hell^o, world
hell^o, world
+helloworld
+hello
+world
+hello
+
+finished
baz
baz
foo | echo bar
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index a328f83..b095deb 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -1788,6 +1788,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
BOOL lastWasIn = FALSE;
BOOL lastWasElse = FALSE;
BOOL lastWasRedirect = TRUE;
+ BOOL lastWasCaret = FALSE;
/* Allocate working space for a command read from keyboard, file etc */
if (!extraSpace)
@@ -1856,6 +1857,12 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
lastWasWhiteSpace, onlyWhiteSpace);
*/
+ /* Prevent overflow caused by the caret escape char*/
+ if (*curLen >= MAXSTRING) {
+ WINE_ERR("Overflow detected in command\n");
+ return NULL;
+ }
+
/* Certain commands need special handling */
if (curStringLen == 0 && curCopyTo == curString) {
static const WCHAR forDO[] = {'d','o'};
@@ -1928,6 +1935,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
else thisChar = 'X'; /* Character with no special processing */
lastWasWhiteSpace = FALSE; /* Will be reset below */
+ lastWasCaret = FALSE;
switch (thisChar) {
@@ -2070,7 +2078,15 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
}
break;
- case '^': if (!inQuotes) curPos++;
+ case '^': if (!inQuotes) {
+ /* If we reach the end of the input, we need to wait for more */
+ if (*(curPos+1) == 0x00) {
+ lastWasCaret = TRUE;
+ WINE_TRACE("Caret found at end of line\n");
+ break;
+ }
+ curPos++;
+ }
curCopyTo[(*curLen)++] = *curPos;
break;
@@ -2147,8 +2163,9 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
lastWasIn = lastWasDo = FALSE;
}
- /* If we have reached the end, add this command into the list */
- if (*curPos == 0x00 && *curLen > 0) {
+ /* If we have reached the end, add this command into the list
+ Do not add command to list if escape char ^ was last */
+ if (*curPos == 0x00 && !lastWasCaret && *curLen > 0) {
/* Add an entry to the command list */
WCMD_addCommand(curString, &curStringLen,
@@ -2158,19 +2175,38 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
&lastEntry, output);
}
- /* If we have reached the end of the string, see if bracketing outstanding */
- if (*curPos == 0x00 && curDepth > 0 && readFrom != INVALID_HANDLE_VALUE) {
+ /* If we have reached the end of the string, see if bracketing or
+ final caret is outstanding */
+ if (*curPos == 0x00 && (curDepth > 0 || lastWasCaret) &&
+ readFrom != INVALID_HANDLE_VALUE) {
+ WCHAR *extraData;
+
+ WINE_TRACE("Need to read more data as outstanding brackets or carets\n");
inRem = FALSE;
prevDelim = CMD_NONE;
inQuotes = 0;
memset(extraSpace, 0x00, (MAXSTRING+1) * sizeof(WCHAR));
+ extraData = extraSpace;
/* Read more, skipping any blank lines */
- while (*extraSpace == 0x00) {
+ do {
+ WINE_TRACE("Read more input\n");
if (!context) WCMD_output_asis( WCMD_LoadMessage(WCMD_MOREPROMPT));
- if (!WCMD_fgets(extraSpace, MAXSTRING, readFrom))
+ if (!WCMD_fgets(extraData, MAXSTRING, readFrom))
break;
- }
+
+ /* Edge case for carets - a completely blank line (ie was just
+ CRLF) is oddly added as an LF but then more data is received (but
+ only once more!) */
+ if (lastWasCaret) {
+ if (*extraSpace == 0x00) {
+ WINE_TRACE("Read nothing, so appending LF char and will try again\n");
+ *extraData++ = '\r';
+ *extraData = 0x00;
+ } else break;
+ }
+
+ } while (*extraData == 0x00);
curPos = extraSpace;
if (context) handleExpansion(extraSpace, FALSE, NULL, NULL);
/* Continue to echo commands IF echo is on and in batch program */
--
1.7.9.5
More information about the wine-patches
mailing list