Module: wine Branch: master Commit: 2ff533c1f2c6b6054260d7a448126a0d32015a0c URL: http://source.winehq.org/git/wine.git/?a=commit;h=2ff533c1f2c6b6054260d7a448...
Author: Jason Edmeades jason@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 */