From 7b125126a7a1bb58caa4e1091c5d87f5388d0c1a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fr=C3=A9d=C3=A9ric=20Delanoy?= Date: Thu, 25 Aug 2011 00:48:18 +0200 Subject: [PATCH] cmd: Fix FOR tab handling. --- programs/cmd/builtins.c | 20 +++++---------- programs/cmd/wcmd.h | 1 + programs/cmd/wcmdmain.c | 57 +++++++++++++++++++++-------------------- 3 files changed, 37 insertions(+), 41 deletions(-) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 7aaa90019c..7cc65201fe 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -902,10 +902,8 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { WIN32_FIND_DATAW fd; HANDLE hff; int i; - const WCHAR inW[] = {'i', 'n', ' ', '\0'}; - const WCHAR inTabW[] = {'i', 'n', '\t', '\0'}; - const WCHAR doW[] = {'d', 'o', ' ', '\0'}; - const WCHAR doTabW[] = {'d', 'o', '\t', '\0'}; + const WCHAR inW[] = {'i','n'}; + const WCHAR doW[] = {'d','o'}; CMD_LIST *setStart, *thisSet, *cmdStart, *cmdEnd; WCHAR variable[4]; WCHAR *firstCmd; @@ -981,10 +979,8 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { /* Ensure line continues with IN */ if (!*curPos - || (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - curPos, 3, inW, -1) != CSTR_EQUAL - && CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - curPos, 3, inTabW, -1) != CSTR_EQUAL)) { + || !WCMD_keyword_ws_found(inW, sizeof(inW)/sizeof(inW[0]), curPos)) { + WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR)); return; } @@ -1008,12 +1004,10 @@ 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); + WINE_TRACE("Looking for 'do ' in %p\n", *cmdList); if ((*cmdList == NULL) - || (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - (*cmdList)->command, 3, doW, -1) != CSTR_EQUAL - && CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - (*cmdList)->command, 3, doTabW, -1) != CSTR_EQUAL)) { + || !WCMD_keyword_ws_found(doW, sizeof(doW)/sizeof(doW[0]), (*cmdList)->command)) { + WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR)); return; } diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 19ba9131da..885add42ac 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -97,6 +97,7 @@ int WCMD_volume (int mode, const WCHAR *command); WCHAR *WCMD_fgets (WCHAR *s, int n, HANDLE stream); WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where); WCHAR *WCMD_skip_leading_spaces (WCHAR *string); +BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr); void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable, const WCHAR *forValue, BOOL justFors); void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext); diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 67b6ef4a20..0edc00579b 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -455,6 +455,18 @@ WCHAR *WCMD_skip_leading_spaces (WCHAR *string) { return ptr; } +/*************************************************************************** + * WCMD_keyword_ws_found + * + * Checks if the string located at ptr matches a keyword (of length len) + * followed by a whitespace character (space or tab) + */ +BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr) { + return (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + ptr, len, keyword, len) == CSTR_EQUAL) + && ((*(ptr + len) == ' ') || (*(ptr + len) == '\t')); +} + /************************************************************************* * WCMD_opt_s_strip_quotes * @@ -1742,8 +1754,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE CMD_DELIMITERS prevDelim = CMD_NONE; static WCHAR *extraSpace = NULL; /* Deliberately never freed */ const WCHAR remCmd[] = {'r','e','m',' ','\0'}; - const WCHAR forCmd[] = {'f','o','r',' ' ,'\0'}; - const WCHAR forTabCmd[] = {'f','o','r','\t','\0'}; + const WCHAR forCmd[] = {'f','o','r'}; const WCHAR ifCmd[] = {'i','f',' ','\0'}; const WCHAR ifElse[] = {'e','l','s','e',' ','\0'}; BOOL inRem = FALSE; @@ -1827,19 +1838,14 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE /* Certain commands need special handling */ if (curStringLen == 0 && curCopyTo == curString) { - const WCHAR forDO[] = {'d','o',' ' ,'\0'}; - const WCHAR forDOTab[] = {'d','o','\t','\0'}; + const WCHAR forDO[] = {'d','o'}; /* If command starts with 'rem', ignore any &&, ( etc */ if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, curPos, 4, remCmd, -1) == CSTR_EQUAL) { inRem = TRUE; - /* If command starts with 'for', handle ('s mid line after IN or DO */ - } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - curPos, 4, forCmd, -1) == CSTR_EQUAL - || CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - curPos, 4, forTabCmd, -1) == CSTR_EQUAL) { + } else if (WCMD_keyword_ws_found(forCmd, sizeof(forCmd)/sizeof(forCmd[0]), curPos)) { inFor = TRUE; /* If command starts with 'if' or 'else', handle ('s mid line. We should ensure this @@ -1866,37 +1872,32 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE whitespace, followed by DO, ie closeBracket inserts a NULL entry, curLen is then 0, and all whitespace is skipped */ } else if (inFor && - (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - curPos, 3, forDO, -1) == CSTR_EQUAL - || CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - curPos, 3, forDOTab, -1) == CSTR_EQUAL)) { - WINE_TRACE("Found DO\n"); + WCMD_keyword_ws_found(forDO, sizeof(forDO)/sizeof(forDO[0]), curPos)) { + const int keyw_len = sizeof(forDO)/sizeof(forDO[0]) + 1; + WINE_TRACE("Found 'DO '\n"); lastWasDo = TRUE; onlyWhiteSpace = TRUE; - memcpy(&curCopyTo[*curLen], curPos, 3*sizeof(WCHAR)); - (*curLen)+=3; - curPos+=3; + memcpy(&curCopyTo[*curLen], curPos, keyw_len*sizeof(WCHAR)); + (*curLen)+=keyw_len; + curPos+=keyw_len; continue; } } else if (curCopyTo == curString) { /* Special handling for the 'FOR' command */ if (inFor && lastWasWhiteSpace) { - const WCHAR forIN[] = {'i','n',' ' ,'\0'}; - const WCHAR forINTab[] = {'i','n','\t','\0'}; + const WCHAR forIN[] = {'i','n'}; - WINE_TRACE("Found 'FOR', comparing next parm: '%s'\n", wine_dbgstr_w(curPos)); + WINE_TRACE("Found 'FOR ', comparing next parm: '%s'\n", wine_dbgstr_w(curPos)); - if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - curPos, 3, forIN, -1) == CSTR_EQUAL - || CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - curPos, 3, forINTab, -1) == CSTR_EQUAL) { - WINE_TRACE("Found IN\n"); + if (WCMD_keyword_ws_found(forIN, sizeof(forIN)/sizeof(forIN[0]), curPos)) { + const int keyw_len = sizeof(forIN)/sizeof(forIN[0]) + 1; + WINE_TRACE("Found 'IN '\n"); lastWasIn = TRUE; onlyWhiteSpace = TRUE; - memcpy(&curCopyTo[*curLen], curPos, 3*sizeof(WCHAR)); - (*curLen)+=3; - curPos+=3; + memcpy(&curCopyTo[*curLen], curPos, keyw_len*sizeof(WCHAR)); + (*curLen)+=keyw_len; + curPos+=keyw_len; continue; } } -- 2.32.0.93.g670b81a890