Module: wine
Branch: master
Commit: 2ff533c1f2c6b6054260d7a448126a0d32015a0c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2ff533c1f2c6b6054260d7a44…
Author: Jason Edmeades <jason(a)edmeades.me.uk>
Date: Tue Sep 25 21:02:09 2012 +0100
cmd: Support for ^ character at end of line.
Based on a patch by John Chow.
---
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 e8ffe53..7c4b37f 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 */