From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/cmd/builtins.c | 683 +--------------------------------------- programs/cmd/wcmdmain.c | 1 + 2 files changed, 2 insertions(+), 682 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 82ba8088b02..d911f851976 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1673,110 +1673,6 @@ void WCMD_part_execute(CMD_NODE **cmdList, const WCHAR *firstcmd, } }
-static BOOL option_equals(WCHAR **haystack, const WCHAR *needle) -{ - int len = wcslen(needle); - - if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - *haystack, len, needle, len) == CSTR_EQUAL) { - *haystack += len; - return TRUE; - } - - return FALSE; -} - -/***************************************************************************** - * WCMD_parse_forf_options - * - * Parses the for /f 'options', extracting the values and validating the - * keywords. Note all keywords are optional. - * Parameters: - * options [I] The unparsed parameter string - * eol [O] Set to the comment character (eol=x) - * skip [O] Set to the number of lines to skip (skip=xx) - * delims [O] Set to the token delimiters (delims=) - * tokens [O] Set to the requested tokens, as provided (tokens=) - * usebackq [O] Set to TRUE if usebackq found - * - * Returns TRUE on success, FALSE on syntax error - * - */ -static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip, - WCHAR *delims, WCHAR *tokens, BOOL *usebackq) -{ - - WCHAR *pos = options; - int len = lstrlenW(pos); - - /* Initialize to defaults */ - lstrcpyW(delims, L" \t"); - lstrcpyW(tokens, L"1"); - *eol = 0; - *skip = 0; - *usebackq = FALSE; - - /* Strip (optional) leading and trailing quotes */ - if ((*pos == '"') && (pos[len-1] == '"')) { - pos[len-1] = 0; - pos++; - } - - /* Process each keyword */ - while (pos && *pos) { - if (*pos == ' ' || *pos == '\t') { - pos++; - - /* Save End of line character (Ignore line if first token (based on delims) starts with it) */ - } else if (option_equals(&pos, L"eol=")) { - *eol = *pos++; - 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 (option_equals(&pos, L"skip=")) { - WCHAR *nextchar = NULL; - *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 (option_equals(&pos, L"usebackq")) { - *usebackq = TRUE; - 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 (option_equals(&pos, L"delims=")) { - int i=0; - - while (*pos && *pos != ' ') { - delims[i++] = *pos; - pos++; - } - if (*pos==' ' && *(pos+1)==0) delims[i++] = *pos; - delims[i++] = 0; /* Null terminate the delims */ - WINE_TRACE("Found delims as '%s'\n", wine_dbgstr_w(delims)); - - /* Save the tokens being requested */ - } else if (option_equals(&pos, L"tokens=")) { - int i=0; - - while (*pos && *pos != ' ') { - tokens[i++] = *pos; - pos++; - } - tokens[i++] = 0; /* Null terminate the tokens */ - WINE_TRACE("Found tokens as '%s'\n", wine_dbgstr_w(tokens)); - - } else { - WINE_WARN("Unexpected data in optionsroot: '%s'\n", wine_dbgstr_w(pos)); - return FALSE; - } - } - return TRUE; -} - /***************************************************************************** * WCMD_add_dirstowalk * @@ -1953,177 +1849,6 @@ int WCMD_for_nexttoken(int lasttoken, const WCHAR *tokenstr, return nexttoken; }
-/************************************************************************** - * WCMD_parse_line - * - * When parsing file or string contents (for /f), once the string to parse - * has been identified, handle the various options and call the do part - * if appropriate. - * - * Parameters: - * cmdStart [I] - Identifies the list of commands making up the - * for loop body (especially if brackets in use) - * firstCmd [I] - The textual start of the command after the DO - * which is within the first item of cmdStart - * cmdEnd [O] - Identifies where to continue after the DO - * variable [I] - The variable identified on the for line - * buffer [I] - The string to parse - * doExecuted [O] - Set to TRUE if the DO is ever executed once - * forf_skip [I/O] - How many lines to skip first - * forf_eol [I] - The 'end of line' (comment) character - * forf_delims [I] - The delimiters to use when breaking the string apart - * forf_tokens [I] - The tokens to use when breaking the string apart - */ -static void WCMD_parse_line(CMD_NODE *cmdStart, - const WCHAR *firstCmd, - CMD_NODE **cmdEnd, - int varidx, - WCHAR *buffer, - BOOL *doExecuted, - int *forf_skip, - WCHAR forf_eol, - WCHAR *forf_delims, - WCHAR *forf_tokens) { - - WCHAR *parm; - int varoffset; - int nexttoken, lasttoken = -1; - BOOL starfound = FALSE; - BOOL thisduplicate = FALSE; - BOOL anyduplicates = FALSE; - int totalfound; - static WCHAR emptyW[] = L""; - - /* Skip lines if requested */ - if (*forf_skip) { - (*forf_skip)--; - return; - } - - /* Save away any existing for variable context (e.g. nested for loops) */ - WCMD_save_for_loop_context(FALSE); - - /* Extract the parameters based on the tokens= value (There will always - be some value, as if it is not supplied, it defaults to tokens=1). - Rough logic: - Count how many tokens are named in the line, identify the lowest - Empty (set to null terminated string) that number of named variables - While lasttoken != nextlowest - %letter = parameter number 'nextlowest' - letter++ (if >26 or >52 abort) - Go through token= string finding next lowest number - If token ends in * set %letter = raw position of token(nextnumber+1) - */ - lasttoken = -1; - nexttoken = WCMD_for_nexttoken(lasttoken, forf_tokens, &totalfound, - &starfound, &thisduplicate); - - /* Empty out variables */ - for (varoffset=0; - varidx >= 0 && varoffset<totalfound && for_var_index_in_range(varidx, varoffset); - varoffset++) { - WCMD_set_for_loop_variable(varidx + varoffset, emptyW); - } - - /* Loop extracting the tokens - Note: nexttoken of 0 means there were no tokens requested, to handle - the special case of tokens=* */ - varoffset = 0; - WINE_TRACE("Parsing buffer into tokens: '%s'\n", wine_dbgstr_w(buffer)); - while (varidx >= 0 && (nexttoken > 0 && (nexttoken > lasttoken))) { - anyduplicates |= thisduplicate; - - if (!for_var_index_in_range(varidx, varoffset)) break; - - /* Extract the token number requested and set into the next variable context */ - parm = WCMD_parameter_with_delims(buffer, (nexttoken-1), NULL, TRUE, FALSE, forf_delims); - WINE_TRACE("Parsed token %d(%d) as parameter %s\n", nexttoken, - varidx + varoffset, wine_dbgstr_w(parm)); - if (varidx >=0) { - if (parm) - WCMD_set_for_loop_variable(varidx + varoffset, parm); - varoffset++; - } - - /* Find the next token */ - lasttoken = nexttoken; - nexttoken = WCMD_for_nexttoken(lasttoken, forf_tokens, NULL, - &starfound, &thisduplicate); - } - - /* If all the rest of the tokens were requested, and there is still space in - the variable range, write them now */ - if (!anyduplicates && starfound && varidx >= 0 && for_var_index_in_range(varidx, varoffset)) { - nexttoken++; - WCMD_parameter_with_delims(buffer, (nexttoken-1), &parm, FALSE, FALSE, forf_delims); - WINE_TRACE("Parsed allremaining tokens (%d) as parameter %s\n", - varidx + varoffset, wine_dbgstr_w(parm)); - if (parm) - WCMD_set_for_loop_variable(varidx + varoffset, parm); - } - - /* Execute the body of the foor loop with these values */ - if (varidx >= 0 && forloopcontext->variable[varidx] && forloopcontext->variable[varidx][0] != forf_eol) { - CMD_NODE *thisCmdStart = cmdStart; - *doExecuted = TRUE; - WCMD_part_execute(&thisCmdStart, firstCmd, FALSE, TRUE); - *cmdEnd = thisCmdStart; - } - - WCMD_restore_for_loop_context(); -} - -/************************************************************************** - * WCMD_forf_getinput - * - * Return a FILE* which can be used for reading the input lines, - * either to a specific file (which may be quote delimited as we have to - * read the parameters in raw mode) or to a command which we need to - * execute. The command being executed runs in its own shell and stores - * its data in a temporary file. - * - * Parameters: - * usebackq [I] - Indicates whether usebackq is in effect or not - * itemStr [I] - The item to be handled, either a filename or - * whole command string to execute - * iscmd [I] - Identifies whether this is a command or not - * - * Returns a file handle which can be used to read the input lines from. - */ -static FILE *WCMD_forf_getinput(BOOL usebackq, WCHAR *itemstr, BOOL iscmd) -{ - WCHAR *trimmed = NULL; - FILE* ret; - - /* Remove leading and trailing character (but there may be trailing whitespace too) */ - if ((iscmd && (itemstr[0] == '`' && usebackq)) || - (iscmd && (itemstr[0] == ''' && !usebackq)) || - (!iscmd && (itemstr[0] == '"' && usebackq))) - { - trimmed = WCMD_strtrim(itemstr); - if (trimmed) - itemstr = trimmed; - itemstr[lstrlenW(itemstr)-1] = 0x00; - itemstr++; - } - - if (iscmd) - { - WCHAR temp_cmd[MAXSTRING]; - wsprintfW(temp_cmd, L"CMD.EXE /C %s", itemstr); - WINE_TRACE("Reading output of '%s'\n", wine_dbgstr_w(temp_cmd)); - ret = _wpopen(temp_cmd, L"rt,ccs=unicode"); - } - else - { - /* Open the file, read line by line and process */ - WINE_TRACE("Reading input to parse from '%s'\n", wine_dbgstr_w(itemstr)); - ret = _wfopen(itemstr, L"rt,ccs=unicode"); - } - free(trimmed); - return ret; -} - /************************************************************************** * WCMD_for * @@ -2136,411 +1861,6 @@ static FILE *WCMD_forf_getinput(BOOL usebackq, WCHAR *itemstr, BOOL iscmd) * */
-static void WCMD_for_OLD (WCHAR *p, CMD_NODE **cmdList) { - - WIN32_FIND_DATAW fd; - HANDLE hff; - int i; - const int in_len = lstrlenW(L"in"); - CMD_NODE *setStart, *thisSet, *cmdStart, *cmdEnd; - WCHAR variable[4]; - int varidx = -1; - WCHAR *firstCmd; - int thisDepth; - WCHAR optionsRoot[MAX_PATH]; - DIRECTORY_STACK *dirsToWalk = NULL; - BOOL expandDirs = FALSE; - BOOL useNumbers = FALSE; - BOOL doFileset = FALSE; - BOOL doRecurse = FALSE; - BOOL doExecuted = FALSE; /* Has the 'do' part been executed */ - LONG numbers[3] = {0,0,0}; /* Defaults to 0 in native */ - int itemNum; - CMD_NODE *thisCmdStart; - int parameterNo = 0; - WCHAR forf_eol = 0; - int forf_skip = 0; - WCHAR forf_delims[256]; - WCHAR forf_tokens[MAXSTRING]; - BOOL forf_usebackq = FALSE; - - /* Handle optional qualifiers (multiple are allowed) */ - WCHAR *thisArg = WCMD_parameter(p, parameterNo++, NULL, FALSE, FALSE); - - optionsRoot[0] = 0; - while (thisArg && *thisArg == '/') { - WINE_TRACE("Processing qualifier at %s\n", wine_dbgstr_w(thisArg)); - thisArg++; - switch (towupper(*thisArg)) { - case 'D': expandDirs = TRUE; break; - case 'L': useNumbers = TRUE; break; - - /* Recursive is special case - /R can have an optional path following it */ - /* filenamesets are another special case - /F can have an optional options following it */ - case 'R': - case 'F': - { - /* When recursing directories, use current directory as the starting point unless - subsequently overridden */ - doRecurse = (towupper(*thisArg) == 'R'); - if (doRecurse) GetCurrentDirectoryW(ARRAY_SIZE(optionsRoot), optionsRoot); - - doFileset = (towupper(*thisArg) == 'F'); - - /* Retrieve next parameter to see if is root/options (raw form required - with for /f, or unquoted in for /r) */ - thisArg = WCMD_parameter(p, parameterNo, NULL, doFileset, FALSE); - - /* Next parm is either qualifier, path/options or variable - - only care about it if it is the path/options */ - if (thisArg && *thisArg != '/' && *thisArg != '%') { - parameterNo++; - lstrcpyW(optionsRoot, thisArg); - } - break; - } - default: - WINE_FIXME("for qualifier '%c' unhandled\n", *thisArg); - } - - /* Step to next token */ - thisArg = WCMD_parameter(p, parameterNo++, NULL, FALSE, FALSE); - } - - /* Ensure line continues with variable */ - if (*thisArg != '%') { - WCMD_output_stderr (WCMD_LoadMessage(WCMD_SYNTAXERR)); - return; - } - - /* With for /f parse the options if provided */ - if (doFileset) { - if (!WCMD_parse_forf_options(optionsRoot, &forf_eol, &forf_skip, - forf_delims, forf_tokens, &forf_usebackq)) - { - WCMD_output_stderr (WCMD_LoadMessage(WCMD_SYNTAXERR)); - return; - } - - /* Set up the list of directories to recurse if we are going to */ - } else if (doRecurse) { - /* Allocate memory, add to list */ - dirsToWalk = WCMD_dir_stack_create(optionsRoot, NULL); - TRACE("Starting with root directory %s\n", wine_dbgstr_w(dirsToWalk->dirName)); - } - - /* Variable should follow */ - lstrcpyW(variable, thisArg); - WINE_TRACE("Variable identified as %s\n", wine_dbgstr_w(variable)); - varidx = for_var_char_to_index(variable[1]); - - /* Ensure line continues with IN */ - thisArg = WCMD_parameter(p, parameterNo++, NULL, FALSE, FALSE); - if (!thisArg - || !(CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - thisArg, in_len, L"in", in_len) == CSTR_EQUAL)) { - WCMD_output_stderr (WCMD_LoadMessage(WCMD_SYNTAXERR)); - return; - } - - /* Save away where the set of data starts and the variable */ - thisDepth = CMD_node_get_depth(*cmdList); - *cmdList = CMD_node_next(*cmdList); - setStart = (*cmdList); - - /* Skip until the close bracket */ - WINE_TRACE("Searching %p as the set\n", *cmdList); - while (*cmdList && - CMD_node_get_command(*cmdList)->command != NULL && - CMD_node_get_depth(*cmdList) > thisDepth) { - WINE_TRACE("Skipping %p which is part of the set\n", *cmdList); - *cmdList = CMD_node_next(*cmdList); - } - - /* Skip the close bracket, if there is one */ - if (*cmdList) *cmdList = CMD_node_next(*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(L"do", CMD_node_get_command(*cmdList)->command)) { - WCMD_output_stderr (WCMD_LoadMessage(WCMD_SYNTAXERR)); - return; - } - - cmdEnd = *cmdList; - - /* Loop repeatedly per-directory we are potentially walking, when in for /r - mode, or once for the rest of the time. */ - do { - - /* Save away the starting position for the commands (and offset for the - first one) */ - cmdStart = *cmdList; - firstCmd = CMD_node_get_command(*cmdList)->command + 3; /* Skip 'do ' */ - itemNum = 0; - - /* If we are recursing directories (ie /R), add all sub directories now, then - prefix the root when searching for the item */ - if (dirsToWalk) WCMD_add_dirstowalk(dirsToWalk); - - thisSet = setStart; - /* Loop through all set entries */ - while (thisSet && - CMD_node_get_command(thisSet)->command != NULL && - CMD_node_get_depth(thisSet) >= thisDepth) { - - /* Loop through all entries on the same line */ - WCHAR *staticitem; - WCHAR *itemStart; - WCHAR buffer[MAXSTRING]; - - WINE_TRACE("Processing for set %p\n", thisSet); - i = 0; - while (*(staticitem = WCMD_parameter (CMD_node_get_command(thisSet)->command, i, &itemStart, TRUE, FALSE))) { - - /* - * If the parameter within the set has a wildcard then search for matching files - * otherwise do a literal substitution. - */ - - /* Take a copy of the item returned from WCMD_parameter as it is held in a - static buffer which can be overwritten during parsing of the for body */ - WCHAR item[MAXSTRING]; - lstrcpyW(item, staticitem); - - thisCmdStart = cmdStart; - - itemNum++; - WINE_TRACE("Processing for item %d '%s'\n", itemNum, wine_dbgstr_w(item)); - - if (!useNumbers && !doFileset) { - WCHAR fullitem[MAX_PATH]; - int prefixlen = 0; - - /* Now build the item to use / search for in the specified directory, - as it is fully qualified in the /R case */ - if (dirsToWalk) { - lstrcpyW(fullitem, dirsToWalk->dirName); - lstrcatW(fullitem, L"\"); - lstrcatW(fullitem, item); - } else { - WCHAR *prefix = wcsrchr(item, '\'); - if (prefix) prefixlen = (prefix - item) + 1; - lstrcpyW(fullitem, item); - } - - if (wcspbrk(fullitem, L"*?")) { - hff = FindFirstFileW(fullitem, &fd); - if (hff != INVALID_HANDLE_VALUE) { - do { - BOOL isDirectory = FALSE; - - if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) isDirectory = TRUE; - - /* Handle as files or dirs appropriately, but ignore . and .. */ - if (isDirectory == expandDirs && - (lstrcmpW(fd.cFileName, L"..") != 0) && (lstrcmpW(fd.cFileName, L".") != 0)) - { - thisCmdStart = cmdStart; - WINE_TRACE("Processing FOR filename %s\n", wine_dbgstr_w(fd.cFileName)); - - if (doRecurse) { - if (wcslen(dirsToWalk->dirName) + 1 + wcslen(fd.cFileName) >= MAX_PATH) - { - WINE_TRACE("Skipping too long path %s\%s\n", - debugstr_w(dirsToWalk->dirName), debugstr_w(fd.cFileName)); - continue; - } - lstrcpyW(fullitem, dirsToWalk->dirName); - lstrcatW(fullitem, L"\"); - lstrcatW(fullitem, fd.cFileName); - } else { - if (prefixlen) lstrcpynW(fullitem, item, prefixlen + 1); - fullitem[prefixlen] = 0x00; - lstrcatW(fullitem, fd.cFileName); - } - doExecuted = TRUE; - - WCMD_save_for_loop_context(FALSE); - /* Save away any existing for variable context (e.g. nested for loops) - and restore it after executing the body of this for loop */ - if (varidx >= 0) - WCMD_set_for_loop_variable(varidx, fullitem); - WCMD_part_execute (&thisCmdStart, firstCmd, FALSE, TRUE); - WCMD_restore_for_loop_context(); - - cmdEnd = thisCmdStart; - } - } while (FindNextFileW(hff, &fd) != 0); - FindClose (hff); - } - } else { - doExecuted = TRUE; - - WCMD_save_for_loop_context(FALSE); - /* Save away any existing for variable context (e.g. nested for loops) - and restore it after executing the body of this for loop */ - if (varidx >= 0) - WCMD_set_for_loop_variable(varidx, fullitem); - WCMD_part_execute (&thisCmdStart, firstCmd, FALSE, TRUE); - WCMD_restore_for_loop_context(); - - cmdEnd = thisCmdStart; - } - - } else if (useNumbers) { - /* Convert the first 3 numbers to signed longs and save */ - if (itemNum <=3) numbers[itemNum-1] = wcstol(item, NULL, 10); - /* else ignore them! */ - - /* Filesets - either a list of files, or a command to run and parse the output */ - } else if (doFileset && ((!forf_usebackq && *itemStart != '"') || - (forf_usebackq && *itemStart != '''))) { - - FILE *input; - WCHAR *itemparm; - - WINE_TRACE("Processing for filespec from item %d '%s'\n", itemNum, - wine_dbgstr_w(item)); - - /* If backquote or single quote, we need to launch that command - and parse the results - use a temporary file */ - if ((forf_usebackq && *itemStart == '`') || - (!forf_usebackq && *itemStart == ''')) { - - /* Use itemstart because the command is the whole set, not just the first token */ - itemparm = itemStart; - } else { - - /* Use item because the file to process is just the first item in the set */ - itemparm = item; - } - input = WCMD_forf_getinput(forf_usebackq, itemparm, (itemparm==itemStart)); - - /* Process the input file */ - if (!input) { - WCMD_print_error (); - WCMD_output_stderr(WCMD_LoadMessage(WCMD_READFAIL), item); - errorlevel = 1; - return; /* FOR loop aborts at first failure here */ - - } else { - - /* Read line by line until end of file */ - while (fgetws(buffer, ARRAY_SIZE(buffer), input)) { - size_t len = wcslen(buffer); - /* Either our buffer isn't large enough to fit a full line, or there's a stray - * '\0' in the buffer. - */ - if (!feof(input) && (len == 0 || (buffer[len - 1] != '\n' && buffer[len - 1] != '\r'))) - break; - while (len && (buffer[len - 1] == '\n' || buffer[len - 1] == '\r')) - buffer[--len] = L'\0'; - WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, for_var_char_to_index(variable[1]), buffer, &doExecuted, - &forf_skip, forf_eol, forf_delims, forf_tokens); - buffer[0] = 0; - } - fclose (input); - } - - /* When we have processed the item as a whole command, abort future set processing */ - if (itemparm==itemStart) { - thisSet = NULL; - break; - } - - /* Filesets - A string literal */ - } else if (doFileset && ((!forf_usebackq && *itemStart == '"') || - (forf_usebackq && *itemStart == '''))) { - - /* Remove leading and trailing character, ready to parse with delims= delimiters - Note that the last quote is removed from the set and the string terminates - there to mimic windows */ - WCHAR *strend = wcsrchr(itemStart, forf_usebackq?''':'"'); - if (strend) { - *strend = 0x00; - itemStart++; - } - - /* Copy the item away from the global buffer used by WCMD_parameter */ - lstrcpyW(buffer, itemStart); - WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, for_var_char_to_index(variable[1]), buffer, &doExecuted, - &forf_skip, forf_eol, forf_delims, forf_tokens); - - /* Only one string can be supplied in the whole set, abort future set processing */ - thisSet = NULL; - break; - } - - WINE_TRACE("Post-command, cmdEnd = %p\n", cmdEnd); - i++; - } - - /* Move onto the next set line */ - if (thisSet) thisSet = CMD_node_next(thisSet); - } - - /* If /L is provided, now run the for loop */ - if (useNumbers) { - WCHAR thisNum[20]; - - WINE_TRACE("FOR /L provided range from %ld to %ld step %ld\n", - numbers[0], numbers[2], numbers[1]); - for (i=numbers[0]; - (numbers[1]<0)? i>=numbers[2] : i<=numbers[2]; - i=i + numbers[1]) { - - swprintf(thisNum, ARRAY_SIZE(thisNum), L"%d", i); - WINE_TRACE("Processing FOR number %s\n", wine_dbgstr_w(thisNum)); - - thisCmdStart = cmdStart; - doExecuted = TRUE; - - /* Save away any existing for variable context (e.g. nested for loops) - and restore it after executing the body of this for loop */ - if (varidx >= 0) - { - WCMD_save_for_loop_context(FALSE); - WCMD_set_for_loop_variable(varidx, thisNum); - } - WCMD_part_execute (&thisCmdStart, firstCmd, FALSE, TRUE); - if (varidx >= 0) - WCMD_restore_for_loop_context(); - } - cmdEnd = thisCmdStart; - } - - /* If we are walking directories, move on to any which remain */ - if (dirsToWalk != NULL) { - dirsToWalk = WCMD_dir_stack_free(dirsToWalk); - if (dirsToWalk) WINE_TRACE("Moving to next directory to iterate: %s\n", - wine_dbgstr_w(dirsToWalk->dirName)); - else WINE_TRACE("Finished all directories.\n"); - } - - } while (dirsToWalk != NULL); - - /* Now skip over the do part if we did not perform the for loop so far. - We store in cmdEnd the next command after the do block, but we only - know this if something was run. If it has not been, we need to calculate - it. */ - if (!doExecuted) { - thisCmdStart = cmdStart; - WINE_TRACE("Skipping for loop commands due to no valid iterations\n"); - WCMD_part_execute(&thisCmdStart, firstCmd, FALSE, FALSE); - cmdEnd = thisCmdStart; - } - - /* When the loop ends, either something like a GOTO or EXIT /b has terminated - all processing, OR it should be pointing to the end of && processing OR - it should be pointing at the NULL end of bracket for the DO. The return - value needs to be the NEXT command to execute, which it either is, or - we need to step over the closing bracket */ - *cmdList = cmdEnd; - if (cmdEnd && CMD_node_get_command(cmdEnd)->command == NULL) *cmdList = CMD_node_next(cmdEnd); -} - void WCMD_for(WCHAR *p, CMD_NODE **cmdList) { CMD_FOR_CONTROL *for_ctrl; @@ -2548,8 +1868,7 @@ void WCMD_for(WCHAR *p, CMD_NODE **cmdList) for_ctrl = for_control_parse(p); if (!for_ctrl) { - /* temporary code: use OLD code for non migrated FOR constructs */ - WCMD_for_OLD(p, cmdList); + *cmdList = NULL; return; }
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index f2030d7e985..22bfb1853da 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -2277,6 +2277,7 @@ CMD_FOR_CONTROL *for_control_parse(WCHAR *opts_var) for_op = CMD_FOR_FILE_SET; break; default: + FIXME("Unexpected situation\n"); return NULL; }