Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48486 Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- programs/cmd/wcmdmain.c | 42 +++++++++++++++-------------------------- 1 file changed, 15 insertions(+), 27 deletions(-)
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index dd7d14e50e5..2260ed9da35 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -1813,11 +1813,6 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE CMD_LIST *lastEntry = NULL; CMD_DELIMITERS prevDelim = CMD_NONE; static WCHAR *extraSpace = NULL; /* Deliberately never freed */ - static const WCHAR remCmd[] = {'r','e','m'}; - static const WCHAR forCmd[] = {'f','o','r'}; - static const WCHAR ifCmd[] = {'i','f'}; - static const WCHAR ifElse[] = {'e','l','s','e'}; - static const WCHAR setCmd[] = {'s','e','t'}; BOOL inOneLine = FALSE; BOOL inFor = FALSE; BOOL inIn = FALSE; @@ -1870,10 +1865,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
/* Show prompt before batch line IF echo is on and in batch program */ if (context && echo_mode && *curPos && (*curPos != '@')) { - static const WCHAR echoDot[] = {'e','c','h','o','.'}; - static const WCHAR echoCol[] = {'e','c','h','o',':'}; - static const WCHAR echoSlash[] = {'e','c','h','o','/'}; - const DWORD len = ARRAY_SIZE(echoDot); + const DWORD len = ARRAY_SIZE(L"echo.") - 1; DWORD curr_size = lstrlenW(curPos); DWORD min_len = (curr_size < len ? curr_size : len); WCMD_show_prompt(TRUE); @@ -1881,11 +1873,11 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE /* I don't know why Windows puts a space here but it does */ /* Except for lines starting with 'echo.', 'echo:' or 'echo/'. Ask MS why */ if (CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, - curPos, min_len, echoDot, len) != CSTR_EQUAL + curPos, min_len, L"echo.", len) != CSTR_EQUAL && CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, - curPos, min_len, echoCol, len) != CSTR_EQUAL + curPos, min_len, L"echo:", len) != CSTR_EQUAL && CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, - curPos, min_len, echoSlash, len) != CSTR_EQUAL) + curPos, min_len, L"echo/", len) != CSTR_EQUAL) { WCMD_output_asis(L" "); } @@ -1921,13 +1913,11 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
/* Certain commands need special handling */ if (curStringLen == 0 && curCopyTo == curString) { - static const WCHAR forDO[] = {'d','o'}; - /* If command starts with 'rem ' or identifies a label, ignore any &&, ( etc. */ - if (WCMD_keyword_ws_found(remCmd, ARRAY_SIZE(remCmd), curPos) || *curPos == ':') { + if (WCMD_keyword_ws_found(L"rem", ARRAY_SIZE(L"rem") - 1, curPos) || *curPos == ':') { inOneLine = TRUE;
- } else if (WCMD_keyword_ws_found(forCmd, ARRAY_SIZE(forCmd), curPos)) { + } else if (WCMD_keyword_ws_found(L"for", ARRAY_SIZE(L"for") - 1, curPos)) { inFor = TRUE;
/* If command starts with 'if ' or 'else ', handle ('s mid line. We should ensure this @@ -1935,14 +1925,14 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE should suffice for now. To be able to handle ('s in the condition part take as much as evaluate_if_condition would take and skip parsing it here. */ - } else if (WCMD_keyword_ws_found(ifCmd, ARRAY_SIZE(ifCmd), curPos)) { + } else if (WCMD_keyword_ws_found(L"if", ARRAY_SIZE(L"if") - 1, curPos)) { int negate; /* Negate condition */ int test; /* Condition evaluation result */ WCHAR *p, *command;
inIf = TRUE;
- p = curPos+(ARRAY_SIZE(ifCmd)); + p = curPos+(ARRAY_SIZE(L"if") - 1); while (*p == ' ' || *p == '\t') p++; WCMD_parse (p, quals, param1, param2); @@ -1960,11 +1950,11 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE curPos+=if_condition_len; }
- if (WCMD_keyword_ws_found(setCmd, ARRAY_SIZE(setCmd), curPos)) + if (WCMD_keyword_ws_found(L"set", ARRAY_SIZE(L"set") - 1, curPos)) ignoreBracket = TRUE;
- } else if (WCMD_keyword_ws_found(ifElse, ARRAY_SIZE(ifElse), curPos)) { - const int keyw_len = ARRAY_SIZE(ifElse) + 1; + } else if (WCMD_keyword_ws_found(L"else", ARRAY_SIZE(L"else") - 1, curPos)) { + const int keyw_len = ARRAY_SIZE(L"else"); inElse = TRUE; lastWasElse = TRUE; onlyWhiteSpace = TRUE; @@ -1985,8 +1975,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE /* In a for loop, the DO command will follow a close bracket followed by whitespace, followed by DO, ie closeBracket inserts a NULL entry, curLen is then 0, and all whitespace is skipped */ - } else if (inFor && WCMD_keyword_ws_found(forDO, ARRAY_SIZE(forDO), curPos)) { - const int keyw_len = ARRAY_SIZE(forDO) + 1; + } else if (inFor && WCMD_keyword_ws_found(L"do", ARRAY_SIZE(L"do") - 1, curPos)) { + const int keyw_len = ARRAY_SIZE(L"do"); WINE_TRACE("Found 'DO '\n"); lastWasDo = TRUE; onlyWhiteSpace = TRUE; @@ -1999,12 +1989,10 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
/* Special handling for the 'FOR' command */ if (inFor && lastWasWhiteSpace) { - static const WCHAR forIN[] = {'i','n'}; - WINE_TRACE("Found 'FOR ', comparing next parm: '%s'\n", wine_dbgstr_w(curPos));
- if (WCMD_keyword_ws_found(forIN, ARRAY_SIZE(forIN), curPos)) { - const int keyw_len = ARRAY_SIZE(forIN) + 1; + if (WCMD_keyword_ws_found(L"in", ARRAY_SIZE(L"in") - 1, curPos)) { + const int keyw_len = ARRAY_SIZE(L"in"); WINE_TRACE("Found 'IN '\n"); lastWasIn = TRUE; onlyWhiteSpace = TRUE;
Signed-off-by: Gijs Vermeulen gijsvrm@gmail.com --- programs/cmd/builtins.c | 47 ++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 26 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 0fb40d94e49..79dfed43777 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1533,8 +1533,6 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd, BOOL processThese = executecmds;
while (*cmdList) { - static const WCHAR ifElse[] = {'e','l','s','e'}; - /* execute all appropriate commands */ curPosition = *cmdList;
@@ -1566,13 +1564,13 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
/* End of the command - does 'ELSE ' follow as the next command? */ } else { - if (isIF && WCMD_keyword_ws_found(ifElse, ARRAY_SIZE(ifElse), (*cmdList)->command)) { + if (isIF && WCMD_keyword_ws_found(L"else", ARRAY_SIZE(L"else") - 1, (*cmdList)->command)) { /* Swap between if and else processing */ processThese = !executecmds;
/* Process the ELSE part */ if (processThese) { - const int keyw_len = ARRAY_SIZE(ifElse) + 1; + const int keyw_len = ARRAY_SIZE(L"else"); WCHAR *cmd = ((*cmdList)->command) + keyw_len;
/* Skip leading whitespace between condition and the command */ @@ -1599,8 +1597,7 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd, the same bracket depth as the IF, then the IF statement is over. This is required to handle nested ifs properly */ } else if (isIF && (*cmdList)->bracketDepth == myDepth) { - static const WCHAR doW[] = {'d','o'}; - if (WCMD_keyword_ws_found(doW, ARRAY_SIZE(doW), (*cmdList)->command)) { + if (WCMD_keyword_ws_found(L"do", ARRAY_SIZE(L"do") - 1, (*cmdList)->command)) { WINE_TRACE("Still inside FOR-loop, not an end of IF statement\n"); *cmdList = (*cmdList)->nextcommand; } else { @@ -1642,11 +1639,11 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
WCHAR *pos = options; int len = lstrlenW(pos); - static const WCHAR eolW[] = {'e','o','l','='}; - static const WCHAR skipW[] = {'s','k','i','p','='}; - static const WCHAR tokensW[] = {'t','o','k','e','n','s','='}; - static const WCHAR delimsW[] = {'d','e','l','i','m','s','='}; - static const WCHAR usebackqW[] = {'u','s','e','b','a','c','k','q'}; + static const int eol_len = ARRAY_SIZE(L"eol=") - 1; + static const int skip_len = ARRAY_SIZE(L"skip=") - 1; + static const int tokens_len = ARRAY_SIZE(L"tokens=") - 1; + static const int delims_len = ARRAY_SIZE(L"delims=") - 1; + static const int usebackq_len = ARRAY_SIZE(L"usebackq") - 1;
/* Initialize to defaults */ lstrcpyW(delims, L" \t"); @@ -1668,35 +1665,35 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
/* Save End of line character (Ignore line if first token (based on delims) starts with it) */ } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - pos, ARRAY_SIZE(eolW), eolW, ARRAY_SIZE(eolW)) == CSTR_EQUAL) { - *eol = *(pos + ARRAY_SIZE(eolW)); - pos = pos + ARRAY_SIZE(eolW) + 1; + pos, eol_len, L"eol=", eol_len) == CSTR_EQUAL) { + *eol = *(pos + eol_len); + pos = pos + eol_len + 1; WINE_TRACE("Found eol as %c(%x)\n", *eol, *eol);
/* Save number of lines to skip (Can be in base 10, hex (0x...) or octal (0xx) */ } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - pos, ARRAY_SIZE(skipW), skipW, ARRAY_SIZE(skipW)) == CSTR_EQUAL) { + pos, skip_len, L"skip=", skip_len) == CSTR_EQUAL) { WCHAR *nextchar = NULL; - pos = pos + ARRAY_SIZE(skipW); + pos = pos + skip_len; *skip = wcstoul(pos, &nextchar, 0); WINE_TRACE("Found skip as %d lines\n", *skip); pos = nextchar;
/* Save if usebackq semantics are in effect */ } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, pos, - ARRAY_SIZE(usebackqW), usebackqW, ARRAY_SIZE(usebackqW)) == CSTR_EQUAL) { + usebackq_len, L"usebackq", usebackq_len) == CSTR_EQUAL) { *usebackq = TRUE; - pos = pos + ARRAY_SIZE(usebackqW); + pos = pos + usebackq_len; WINE_TRACE("Found usebackq\n");
/* Save the supplied delims. Slightly odd as space can be a delimiter but only if you finish the optionsroot string with delims= otherwise the space is just a token delimiter! */ } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - pos, ARRAY_SIZE(delimsW), delimsW, ARRAY_SIZE(delimsW)) == CSTR_EQUAL) { + pos, delims_len, L"delims=", delims_len) == CSTR_EQUAL) { int i=0;
- pos = pos + ARRAY_SIZE(delimsW); + pos = pos + delims_len; while (*pos && *pos != ' ') { delims[i++] = *pos; pos++; @@ -1707,10 +1704,10 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
/* Save the tokens being requested */ } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - pos, ARRAY_SIZE(tokensW), tokensW, ARRAY_SIZE(tokensW)) == CSTR_EQUAL) { + pos, tokens_len, L"tokens=", tokens_len) == CSTR_EQUAL) { int i=0;
- pos = pos + ARRAY_SIZE(tokensW); + pos = pos + tokens_len; while (*pos && *pos != ' ') { tokens[i++] = *pos; pos++; @@ -2109,8 +2106,6 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { WIN32_FIND_DATAW fd; HANDLE hff; int i; - static const WCHAR inW[] = {'i','n'}; - static const WCHAR doW[] = {'d','o'}; CMD_LIST *setStart, *thisSet, *cmdStart, *cmdEnd; WCHAR variable[4]; int varidx = -1; @@ -2210,7 +2205,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { thisArg = WCMD_parameter(p, parameterNo++, NULL, FALSE, FALSE); if (!thisArg || !(CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - thisArg, ARRAY_SIZE(inW), inW, ARRAY_SIZE(inW)) == CSTR_EQUAL)) { + thisArg, ARRAY_SIZE(L"in") - 1, L"in", ARRAY_SIZE(L"in") - 1) == CSTR_EQUAL)) { WCMD_output_stderr (WCMD_LoadMessage(WCMD_SYNTAXERR)); return; } @@ -2235,7 +2230,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { /* Syntax error if missing close bracket, or nothing following it and once we have the complete set, we expect a DO */ WINE_TRACE("Looking for 'do ' in %p\n", *cmdList); - if ((*cmdList == NULL) || !WCMD_keyword_ws_found(doW, ARRAY_SIZE(doW), (*cmdList)->command)) { + if ((*cmdList == NULL) || !WCMD_keyword_ws_found(L"do", ARRAY_SIZE(L"do") - 1, (*cmdList)->command)) { WCMD_output_stderr (WCMD_LoadMessage(WCMD_SYNTAXERR)); return; }