From 54d890ca1e4cf8a52e6a468bc43d1d916bb2b800 Mon Sep 17 00:00:00 2001 From: Jason Edmeades Date: Fri, 15 Jun 2007 20:59:28 +0100 Subject: [PATCH] cmd.exe: Fix FOR so it works as 'well' as before. --- programs/cmd/batch.c | 20 +-- programs/cmd/builtins.c | 341 ++++++++++++++++++++++++++-------------- programs/cmd/wcmd.h | 9 +- programs/cmd/wcmdmain.c | 61 ++++--- 4 files changed, 273 insertions(+), 158 deletions(-) diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c index 0990b7e0f7..8f0187c885 100644 --- a/programs/cmd/batch.c +++ b/programs/cmd/batch.c @@ -109,7 +109,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HAN CMD_LIST *toExecute = NULL; /* Commands left to be executed */ if (WCMD_ReadAndParseLine(NULL, &toExecute, h) == NULL) break; - WCMD_process_commands(toExecute, FALSE); + WCMD_process_commands(toExecute, FALSE, NULL, NULL); WCMD_free_commands(toExecute); toExecute = NULL; } @@ -168,21 +168,9 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where) { i++; p = param; break; - case '(': - if (where != NULL && i==n) *where = s; - s++; - while ((*s != '\0') && (*s != ')')) { - *p++ = *s++; - } - if (i == n) { - *p = '\0'; - return param; - } - if (*s == ')') s++; - param[0] = '\0'; - i++; - p = param; - break; + /* The code to handle bracketed parms is removed because it should no longer + be necessary after the multiline support has been added and the for loop + set of data is now parseable individually. */ case '\0': return param; default: diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 0ec86e58b1..a7642281e1 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -40,7 +40,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(cmd); -void WCMD_execute (WCHAR *orig_command, WCHAR *parameter, WCHAR *substitution, CMD_LIST **cmdList); +static void WCMD_part_execute(CMD_LIST **commands, WCHAR *firstcmd, WCHAR *variable, + WCHAR *value, BOOL isIF, BOOL conditionTRUE); struct env_stack *saved_environment; struct env_stack *pushd_directories; @@ -571,6 +572,12 @@ void WCMD_echo (const WCHAR *command) { * WCMD_for * * Batch file loop processing. + * + * On entry: cmdList contains the syntax up to the set + * next cmdList and all in that bracket contain the set data + * next cmdlist contains the DO cmd + * following that is either brackets or && entries (as per if) + * * FIXME: We don't exhaustively check syntax. Any command which works in MessDOS * will probably work here, but the reverse is not necessarily the case... */ @@ -579,45 +586,211 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { WIN32_FIND_DATA fd; HANDLE hff; - WCHAR *cmd, *item; - WCHAR set[MAX_PATH], param[MAX_PATH]; int i; const WCHAR inW[] = {'i', 'n', '\0'}; - const WCHAR doW[] = {'d', 'o', '\0'}; + const WCHAR doW[] = {'d', 'o', ' ','\0'}; + CMD_LIST *setStart, *thisSet, *cmdStart, *cmdEnd; + WCHAR variable[4]; + WCHAR *firstCmd; + int thisDepth; + /* Check: + the first line includes the % variable name as first parm + we have been provided with more parts to the command + and there is at least some set data + and IN as the one after that */ if (lstrcmpiW (WCMD_parameter (p, 1, NULL), inW) - || lstrcmpiW (WCMD_parameter (p, 3, NULL), doW) - || (param1[0] != '%')) { + || (*cmdList) == NULL + || (*cmdList)->nextcommand == NULL + || (param1[0] != '%') + || (strlenW(param1) > 3)) { WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR)); return; } - lstrcpynW (set, WCMD_parameter (p, 2, NULL), sizeof(set)/sizeof(WCHAR)); - WCMD_parameter (p, 4, &cmd); - strcpyW (param, param1); -/* - * If the parameter within the set has a wildcard then search for matching files - * otherwise do a literal substitution. - */ + /* Save away where the set of data starts and the variable */ + strcpyW(variable, param1); + thisDepth = (*cmdList)->bracketDepth; + *cmdList = (*cmdList)->nextcommand; + setStart = (*cmdList); - i = 0; - while (*(item = WCMD_parameter (set, i, NULL))) { - static const WCHAR wildcards[] = {'*','?','\0'}; - if (strpbrkW (item, wildcards)) { - hff = FindFirstFile (item, &fd); - if (hff == INVALID_HANDLE_VALUE) { - return; - } - do { - WCMD_execute (cmd, param, fd.cFileName, cmdList); - } while (FindNextFile(hff, &fd) != 0); - FindClose (hff); - } - else { - WCMD_execute (cmd, param, item, cmdList); - } - i++; + /* Skip until the close bracket */ + WINE_TRACE("Searching %p as the set\n", *cmdList); + while (*cmdList && + (*cmdList)->command != NULL && + (*cmdList)->bracketDepth > thisDepth) { + WINE_TRACE("Skipping %p which is part of the set\n", *cmdList); + *cmdList = (*cmdList)->nextcommand; } + + /* Skip the close bracket, if there is one */ + if (*cmdList) *cmdList = (*cmdList)->nextcommand; + + /* 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) || + (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, + (*cmdList)->command, 3, doW, -1) != 2)) { + WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR)); + return; + } + + /* Save away the starting position for the commands (and offset for the + first one */ + cmdStart = *cmdList; + cmdEnd = *cmdList; + firstCmd = (*cmdList)->command + 3; /* Skip 'do ' */ + + thisSet = setStart; + /* Loop through all set entries */ + while (thisSet && + thisSet->command != NULL && + thisSet->bracketDepth >= thisDepth) { + + /* Loop through all entries on the same line */ + WCHAR *item; + + WINE_TRACE("Processing for set %p\n", thisSet); + i = 0; + while (*(item = WCMD_parameter (thisSet->command, i, NULL))) { + + /* + * If the parameter within the set has a wildcard then search for matching files + * otherwise do a literal substitution. + */ + static const WCHAR wildcards[] = {'*','?','\0'}; + CMD_LIST *thisCmdStart = cmdStart; + + WINE_TRACE("Processing for item '%s'\n", wine_dbgstr_w(item)); + if (strpbrkW (item, wildcards)) { + hff = FindFirstFile (item, &fd); + if (hff != INVALID_HANDLE_VALUE) { + do { + thisCmdStart = cmdStart; + WINE_TRACE("Processing FOR filename %s\n", wine_dbgstr_w(fd.cFileName)); + WCMD_part_execute (&thisCmdStart, firstCmd, variable, + fd.cFileName, FALSE, TRUE); + + } while (FindNextFile(hff, &fd) != 0); + FindClose (hff); + } + } else { + WCMD_part_execute(&thisCmdStart, firstCmd, variable, item, FALSE, TRUE); + } + + WINE_TRACE("Post-command, cmdEnd = %p\n", cmdEnd); + cmdEnd = thisCmdStart; + i++; + } + + /* Move onto the next set line */ + thisSet = thisSet->nextcommand; + } + + /* 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 && cmdEnd->command == NULL) *cmdList = cmdEnd->nextcommand; +} + + +/***************************************************************************** + * WCMD_part_execute + * + * Execute a command, and any && or bracketed follow on to the command. The + * first command to be executed may not be at the front of the + * commands->thiscommand string (eg. it may point after a DO or ELSE + * Returns TRUE if something like exit or goto has aborted all processing + */ +void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable, + WCHAR *value, BOOL isIF, BOOL conditionTRUE) { + + CMD_LIST *curPosition = *cmdList; + int myDepth = (*cmdList)->bracketDepth; + + WINE_TRACE("cmdList(%p), firstCmd(%p), with '%s'='%s', doIt(%d)\n", + cmdList, wine_dbgstr_w(firstcmd), + wine_dbgstr_w(variable), wine_dbgstr_w(value), + conditionTRUE); + + /* Skip leading whitespace between condition and the command */ + while (firstcmd && *firstcmd && (*firstcmd==' ' || *firstcmd=='\t')) firstcmd++; + + /* Process the first command, if there is one */ + if (conditionTRUE && firstcmd && *firstcmd) { + WCHAR *command = WCMD_strdupW(firstcmd); + WCMD_execute (firstcmd, variable, value, cmdList); + free (command); + } + + + /* If it didnt move the position, step to next command */ + if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; + + /* Process any other parts of the command */ + if (*cmdList) { + BOOL processThese = TRUE; + + if (isIF) processThese = conditionTRUE; + + while (*cmdList) { + const WCHAR ifElse[] = {'e','l','s','e',' ','\0'}; + + /* execute all appropriate commands */ + curPosition = *cmdList; + + WINE_TRACE("Processing cmdList(%p) - &(%d) bd(%d / %d)\n", + *cmdList, + (*cmdList)->isAmphersand, + (*cmdList)->bracketDepth, myDepth); + + /* Execute any appended to the statement with &&'s */ + if ((*cmdList)->isAmphersand) { + if (processThese) { + WCMD_execute ((*cmdList)->command, variable, value, cmdList); + } + if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; + + /* Execute any appended to the statement with (...) */ + } else if ((*cmdList)->bracketDepth > myDepth) { + if (processThese) { + *cmdList = WCMD_process_commands(*cmdList, TRUE, variable, value); + WINE_TRACE("Back from processing commands, (next = %p)\n", *cmdList); + } + if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; + + /* End of the command - does 'ELSE ' follow as the next command? */ + } else { + if (isIF && CompareString (LOCALE_USER_DEFAULT, + NORM_IGNORECASE | SORT_STRINGSORT, + (*cmdList)->command, 5, ifElse, -1) == 2) { + + /* Swap between if and else processing */ + processThese = !processThese; + + /* Process the ELSE part */ + if (processThese) { + WCHAR *cmd = ((*cmdList)->command) + strlenW(ifElse); + + /* Skip leading whitespace between condition and the command */ + while (*cmd && (*cmd==' ' || *cmd=='\t')) cmd++; + if (*cmd) { + WCMD_execute (cmd, variable, value, cmdList); + } + } + if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; + } else { + WINE_TRACE("Found end of this IF statement (next = %p)\n", *cmdList); + break; + } + } + } + } + return; } /***************************************************************************** @@ -631,22 +804,26 @@ void WCMD_execute (WCHAR *orig_cmd, WCHAR *param, WCHAR *subst, CMD_LIST **cmdLi WCHAR *new_cmd, *p, *s, *dup; int size; - size = strlenW (orig_cmd); - new_cmd = (WCHAR *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, size); - dup = s = WCMD_strdupW(orig_cmd); + if (param) { + size = (strlenW (orig_cmd) + 1) * sizeof(WCHAR); + new_cmd = (WCHAR *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, size); + dup = s = WCMD_strdupW(orig_cmd); - while ((p = strstrW (s, param))) { - *p = '\0'; - size += strlenW (subst); - new_cmd = (WCHAR *) LocalReAlloc ((HANDLE)new_cmd, size, 0); + while ((p = strstrW (s, param))) { + *p = '\0'; + size += strlenW (subst) * sizeof(WCHAR); + new_cmd = (WCHAR *) LocalReAlloc ((HANDLE)new_cmd, size, 0); + strcatW (new_cmd, s); + strcatW (new_cmd, subst); + s = p + strlenW (param); + } strcatW (new_cmd, s); - strcatW (new_cmd, subst); - s = p + strlenW (param); + WCMD_process_command (new_cmd, cmdList); + free (dup); + LocalFree ((HANDLE)new_cmd); + } else { + WCMD_process_command (orig_cmd, cmdList); } - strcatW (new_cmd, s); - WCMD_process_command (new_cmd, cmdList); - free (dup); - LocalFree ((HANDLE)new_cmd); } @@ -810,8 +987,6 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList) { static const WCHAR existW[] = {'e','x','i','s','t','\0'}; static const WCHAR defdW[] = {'d','e','f','i','n','e','d','\0'}; static const WCHAR eqeqW[] = {'=','=','\0'}; - CMD_LIST *curPosition; - int myDepth; if (!lstrcmpiW (param1, notW)) { negate = 1; @@ -848,81 +1023,7 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList) { /* Process rest of IF statement which is on the same line Note: This may process all or some of the cmdList (eg a GOTO) */ - curPosition = *cmdList; - myDepth = (*cmdList)->bracketDepth; - - if (test != negate) { - WCHAR *cmd = command; - - /* Skip leading whitespace between condition and the command */ - while (cmd && *cmd && (*cmd==' ' || *cmd=='\t')) cmd++; - - if (cmd && *cmd) { - command = WCMD_strdupW(cmd); - WCMD_process_command (command, cmdList); - free (command); - } - } - - /* If it didnt move the position, step to next command */ - if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; - - /* Process any other parts of the IF */ - if (*cmdList) { - BOOL processThese = (test != negate); - - while (*cmdList) { - const WCHAR ifElse[] = {'e','l','s','e',' ','\0'}; - - /* execute all appropriate commands */ - curPosition = *cmdList; - - WINE_TRACE("Processing cmdList(%p) - &(%d) bd(%d / %d)\n", - *cmdList, - (*cmdList)->isAmphersand, - (*cmdList)->bracketDepth, myDepth); - - /* Execute any appended to the statement with &&'s */ - if ((*cmdList)->isAmphersand) { - if (processThese) { - WCMD_process_command((*cmdList)->command, cmdList); - } - if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; - - /* Execute any appended to the statement with (...) */ - } else if ((*cmdList)->bracketDepth > myDepth) { - if (processThese) { - *cmdList = WCMD_process_commands(*cmdList, TRUE); - WINE_TRACE("Back from processing commands, (next = %p)\n", *cmdList); - } - if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; - - /* End of the command - does 'ELSE ' follow as the next command? */ - } else { - if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, - (*cmdList)->command, 5, ifElse, -1) == 2) { - - /* Swap between if and else processing */ - processThese = !processThese; - - /* Process the ELSE part */ - if (processThese) { - WCHAR *cmd = ((*cmdList)->command) + strlenW(ifElse); - - /* Skip leading whitespace between condition and the command */ - while (*cmd && (*cmd==' ' || *cmd=='\t')) cmd++; - if (*cmd) { - WCMD_process_command(cmd, cmdList); - } - } - if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand; - } else { - WINE_TRACE("Found end of this IF statement (next = %p)\n", *cmdList); - break; - } - } - } - } + WCMD_part_execute(cmdList, command, NULL, NULL, TRUE, (test != negate)); } /**************************************************************************** diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 90f0179da8..0781fb6c8f 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -62,7 +62,7 @@ void WCMD_output (const WCHAR *format, ...); void WCMD_output_asis (const WCHAR *message); void WCMD_parse (WCHAR *s, WCHAR *q, WCHAR *p1, WCHAR *p2); void WCMD_pause (void); -void WCMD_pipe (CMD_LIST **command); +void WCMD_pipe (CMD_LIST **command, WCHAR *var, WCHAR *val); void WCMD_popd (void); void WCMD_print_error (void); void WCMD_process_command (WCHAR *command, CMD_LIST **cmdList); @@ -101,9 +101,10 @@ WCHAR *WCMD_strdupW(WCHAR *input); BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars, LPDWORD charsRead, const LPOVERLAPPED unused); -WCHAR *WCMD_ReadAndParseLine(WCHAR *initialcmd, CMD_LIST **output, HANDLE readFrom); -CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket); -void WCMD_free_commands(CMD_LIST *cmds); +WCHAR *WCMD_ReadAndParseLine(WCHAR *initialcmd, CMD_LIST **output, HANDLE readFrom); +CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket, WCHAR *var, WCHAR *val); +void WCMD_free_commands(CMD_LIST *cmds); +void WCMD_execute (WCHAR *orig_command, WCHAR *parameter, WCHAR *substitution, CMD_LIST **cmdList); /* Data structure to hold context when executing batch files */ diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c index 0a9c4d2367..36b8612624 100644 --- a/programs/cmd/wcmdmain.c +++ b/programs/cmd/wcmdmain.c @@ -324,7 +324,7 @@ int wmain (int argc, WCHAR *argvW[]) /* Parse the command string, without reading any more input */ WCMD_ReadAndParseLine(cmd, &toExecute, INVALID_HANDLE_VALUE); - WCMD_process_commands(toExecute, FALSE); + WCMD_process_commands(toExecute, FALSE, NULL, NULL); WCMD_free_commands(toExecute); toExecute = NULL; @@ -417,7 +417,7 @@ int wmain (int argc, WCHAR *argvW[]) if (opt_k) { /* Parse the command string, without reading any more input */ WCMD_ReadAndParseLine(cmd, &toExecute, INVALID_HANDLE_VALUE); - WCMD_process_commands(toExecute, FALSE); + WCMD_process_commands(toExecute, FALSE, NULL, NULL); WCMD_free_commands(toExecute); toExecute = NULL; HeapFree(GetProcessHeap(), 0, cmd); @@ -449,7 +449,7 @@ int wmain (int argc, WCHAR *argvW[]) if (WCMD_ReadAndParseLine(NULL, &toExecute, GetStdHandle(STD_INPUT_HANDLE)) == NULL) break; - WCMD_process_commands(toExecute, FALSE); + WCMD_process_commands(toExecute, FALSE, NULL, NULL); WCMD_free_commands(toExecute); toExecute = NULL; } @@ -497,8 +497,12 @@ void WCMD_process_command (WCHAR *command, CMD_LIST **cmdList) while ((p = strchrW(p, '%'))) { i = *(p+1) - '0'; + /* Dont touch %% */ + if (*(p+1) == '%') { + p+=2; + /* Replace %~ modifications if in batch program */ - if (context && *(p+1) == '~') { + } else if (context && *(p+1) == '~') { WCMD_HandleTildaModifiers(&p, NULL); p++; @@ -531,13 +535,17 @@ void WCMD_process_command (WCHAR *command, CMD_LIST **cmdList) if (context) { p = cmd; while ((p = strchrW(p, '%'))) { - s = strchrW(p+1, '%'); - if (!s) { - *p=0x00; + if (*(p+1) == '%') { + p+=2; } else { - t = WCMD_strdupW(s+1); - strcpyW(p, t); - free(t); + s = strchrW(p+1, '%'); + if (!s) { + *p=0x00; + } else { + t = WCMD_strdupW(s+1); + strcpyW(p, t); + free(t); + } } } @@ -1487,7 +1495,7 @@ void WCMD_opt_s_strip_quotes(WCHAR *cmd) { * Handle pipes within a command - the DOS way using temporary files. */ -void WCMD_pipe (CMD_LIST **cmdEntry) { +void WCMD_pipe (CMD_LIST **cmdEntry, WCHAR *var, WCHAR *val) { WCHAR *p; WCHAR *command = (*cmdEntry)->command; @@ -1503,19 +1511,19 @@ void WCMD_pipe (CMD_LIST **cmdEntry) { p = strchrW(command, '|'); *p++ = '\0'; wsprintf (temp_cmd, redirOut, command, temp_file); - WCMD_process_command (temp_cmd, cmdEntry); + WCMD_execute (temp_cmd, var, val, cmdEntry); command = p; while ((p = strchrW(command, '|'))) { *p++ = '\0'; GetTempFileName (temp_path, cmdW, 0, temp_file2); wsprintf (temp_cmd, redirBoth, command, temp_file, temp_file2); - WCMD_process_command (temp_cmd, cmdEntry); + WCMD_execute (temp_cmd, var, val, cmdEntry); DeleteFile (temp_file); strcpyW (temp_file, temp_file2); command = p; } wsprintf (temp_cmd, redirIn, command, temp_file); - WCMD_process_command (temp_cmd, cmdEntry); + WCMD_execute (temp_cmd, var, val, cmdEntry); DeleteFile (temp_file); } @@ -1913,6 +1921,7 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF const WCHAR ifElse[] = {'e','l','s','e',' ','\0'}; BOOL inRem = FALSE; BOOL inFor = FALSE; + BOOL inIn = FALSE; BOOL inIf = FALSE; BOOL inElse= FALSE; BOOL onlyWhiteSpace = FALSE; @@ -2057,11 +2066,15 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF onlyWhiteSpace, inFor, lastWasIn, lastWasDo, inIf, inElse, lastWasElse); - if (curLen == 0) { + + /* Ignore open brackets inside the for set */ + if (curLen == 0 && !inIn) { + WINE_TRACE("@@@4\n"); curDepth++; /* If in quotes, ignore brackets */ } else if (inQuotes) { + WINE_TRACE("@@@3\n"); curString[curLen++] = *curPos; /* In a FOR loop, an unquoted '(' may occur straight after @@ -2075,6 +2088,13 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF (inElse && lastWasElse && onlyWhiteSpace) || (inFor && (lastWasIn || lastWasDo) && onlyWhiteSpace)) { + WINE_TRACE("@@@2\n"); + /* If entering into an 'IN', set inIn */ + if (inFor && lastWasIn && onlyWhiteSpace) { + WINE_TRACE("Inside an IN\n"); + inIn = TRUE; + } + /* Add the current command */ thisEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(CMD_LIST)); thisEntry->command = HeapAlloc(GetProcessHeap(), 0, @@ -2094,6 +2114,7 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF curDepth++; } else { + WINE_TRACE("@@@1\n"); curString[curLen++] = *curPos; } break; @@ -2159,6 +2180,9 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF *output = thisEntry; } lastEntry = thisEntry; + + /* Leave inIn if necessary */ + if (inIn) inIn = FALSE; } else { curString[curLen++] = *curPos; } @@ -2227,7 +2251,8 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF * * Process all the commands read in so far */ -CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket) { +CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket, + WCHAR *var, WCHAR *val) { int bdepth = -1; @@ -2255,9 +2280,9 @@ CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket) { WINE_TRACE("Executing command: '%s'\n", wine_dbgstr_w(thisCmd->command)); if (strchrW(thisCmd->command,'|') != NULL) { - WCMD_pipe (&thisCmd); + WCMD_pipe (&thisCmd, var, val); } else { - WCMD_process_command (thisCmd->command, &thisCmd); + WCMD_execute (thisCmd->command, var, val, &thisCmd); } }