cmd: Fix for loops within for loops.
This commit is contained in:
parent
f2699f9f60
commit
ae4571fb79
|
@ -92,7 +92,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
|
||||||
/* Note: although this batch program itself may be called, we are not retrying
|
/* Note: although this batch program itself may be called, we are not retrying
|
||||||
the command as a result of a call failing to find a program, hence the
|
the command as a result of a call failing to find a program, hence the
|
||||||
retryCall parameter below is FALSE */
|
retryCall parameter below is FALSE */
|
||||||
WCMD_process_commands(toExecute, FALSE, NULL, NULL, FALSE);
|
WCMD_process_commands(toExecute, FALSE, FALSE);
|
||||||
WCMD_free_commands(toExecute);
|
WCMD_free_commands(toExecute);
|
||||||
toExecute = NULL;
|
toExecute = NULL;
|
||||||
}
|
}
|
||||||
|
@ -358,8 +358,8 @@ void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHA
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* WCMD_HandleTildaModifiers
|
* WCMD_HandleTildaModifiers
|
||||||
*
|
*
|
||||||
* Handle the ~ modifiers when expanding %0-9 or (%a-z in for command)
|
* Handle the ~ modifiers when expanding %0-9 or (%a-z/A-Z in for command)
|
||||||
* %~xxxxxV (V=0-9 or A-Z)
|
* %~xxxxxV (V=0-9 or A-Z, a-z)
|
||||||
* Where xxxx is any combination of:
|
* Where xxxx is any combination of:
|
||||||
* ~ - Removes quotes
|
* ~ - Removes quotes
|
||||||
* f - Fully qualified path (assumes current dir if not drive\dir)
|
* f - Fully qualified path (assumes current dir if not drive\dir)
|
||||||
|
@ -387,8 +387,8 @@ void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHA
|
||||||
* Hence search forwards until find an invalid modifier, and then
|
* Hence search forwards until find an invalid modifier, and then
|
||||||
* backwards until find for variable or 0-9
|
* backwards until find for variable or 0-9
|
||||||
*/
|
*/
|
||||||
void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
|
void WCMD_HandleTildaModifiers(WCHAR **start, BOOL justFors)
|
||||||
const WCHAR *forValue, BOOL justFors) {
|
{
|
||||||
|
|
||||||
#define NUMMODIFIERS 11
|
#define NUMMODIFIERS 11
|
||||||
static const WCHAR validmodifiers[NUMMODIFIERS] = {
|
static const WCHAR validmodifiers[NUMMODIFIERS] = {
|
||||||
|
@ -442,18 +442,19 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (lastModifier > firstModifier) {
|
while (lastModifier > firstModifier) {
|
||||||
WINE_TRACE("Looking backwards for parameter id: %s / %s\n",
|
WINE_TRACE("Looking backwards for parameter id: %s\n",
|
||||||
wine_dbgstr_w(lastModifier), wine_dbgstr_w(forVariable));
|
wine_dbgstr_w(lastModifier));
|
||||||
|
|
||||||
if (!justFors && context && (*lastModifier >= '0' && *lastModifier <= '9')) {
|
if (!justFors && context && (*lastModifier >= '0' && *lastModifier <= '9')) {
|
||||||
/* Its a valid parameter identifier - OK */
|
/* Its a valid parameter identifier - OK */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else if (forVariable && *lastModifier == *(forVariable+1)) {
|
|
||||||
/* Its a valid parameter identifier - OK */
|
|
||||||
break;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
int foridx = FOR_VAR_IDX(*lastModifier);
|
||||||
|
/* Its a valid parameter identifier - OK */
|
||||||
|
if ((foridx >= 0) && (forloopcontext.variable[foridx] != NULL)) break;
|
||||||
|
|
||||||
|
/* Its not a valid parameter identifier - step backwards */
|
||||||
lastModifier--;
|
lastModifier--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -468,7 +469,8 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
|
||||||
*lastModifier-'0' + context -> shift_count[*lastModifier-'0'],
|
*lastModifier-'0' + context -> shift_count[*lastModifier-'0'],
|
||||||
NULL, FALSE, TRUE));
|
NULL, FALSE, TRUE));
|
||||||
} else {
|
} else {
|
||||||
strcpyW(outputparam, forValue);
|
int foridx = FOR_VAR_IDX(*lastModifier);
|
||||||
|
strcpyW(outputparam, forloopcontext.variable[foridx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* So now, firstModifier points to beginning of modifiers, lastModifier
|
/* So now, firstModifier points to beginning of modifiers, lastModifier
|
||||||
|
@ -696,17 +698,24 @@ void WCMD_call (WCHAR *command) {
|
||||||
if (context) {
|
if (context) {
|
||||||
|
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
|
FOR_CONTEXT oldcontext;
|
||||||
|
|
||||||
|
/* Save the for variable context, then start with an empty context
|
||||||
|
as for loop variables do not survive a call */
|
||||||
|
oldcontext = forloopcontext;
|
||||||
|
memset(&forloopcontext, 0, sizeof(forloopcontext));
|
||||||
|
|
||||||
/* Save the current file position, call the same file,
|
/* Save the current file position, call the same file,
|
||||||
restore position */
|
restore position */
|
||||||
li.QuadPart = 0;
|
li.QuadPart = 0;
|
||||||
li.u.LowPart = SetFilePointer(context -> h, li.u.LowPart,
|
li.u.LowPart = SetFilePointer(context -> h, li.u.LowPart,
|
||||||
&li.u.HighPart, FILE_CURRENT);
|
&li.u.HighPart, FILE_CURRENT);
|
||||||
|
|
||||||
WCMD_batch (param1, command, TRUE, gotoLabel, context->h);
|
WCMD_batch (param1, command, TRUE, gotoLabel, context->h);
|
||||||
|
|
||||||
SetFilePointer(context -> h, li.u.LowPart,
|
SetFilePointer(context -> h, li.u.LowPart,
|
||||||
&li.u.HighPart, FILE_BEGIN);
|
&li.u.HighPart, FILE_BEGIN);
|
||||||
|
|
||||||
|
/* Restore the for loop context */
|
||||||
|
forloopcontext = oldcontext;
|
||||||
} else {
|
} else {
|
||||||
WCMD_output_asis_stderr(WCMD_LoadMessage(WCMD_CALLINSCRIPT));
|
WCMD_output_asis_stderr(WCMD_LoadMessage(WCMD_CALLINSCRIPT));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1426,15 +1426,13 @@ void WCMD_echo (const WCHAR *args)
|
||||||
* commands->thiscommand string (eg. it may point after a DO or ELSE)
|
* commands->thiscommand string (eg. it may point after a DO or ELSE)
|
||||||
*/
|
*/
|
||||||
static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
|
static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
|
||||||
const WCHAR *variable, const WCHAR *value,
|
|
||||||
BOOL isIF, BOOL executecmds)
|
BOOL isIF, BOOL executecmds)
|
||||||
{
|
{
|
||||||
CMD_LIST *curPosition = *cmdList;
|
CMD_LIST *curPosition = *cmdList;
|
||||||
int myDepth = (*cmdList)->bracketDepth;
|
int myDepth = (*cmdList)->bracketDepth;
|
||||||
|
|
||||||
WINE_TRACE("cmdList(%p), firstCmd(%p), with variable '%s'='%s', doIt(%d)\n",
|
WINE_TRACE("cmdList(%p), firstCmd(%p), doIt(%d)\n",
|
||||||
cmdList, wine_dbgstr_w(firstcmd),
|
cmdList, wine_dbgstr_w(firstcmd),
|
||||||
wine_dbgstr_w(variable), wine_dbgstr_w(value),
|
|
||||||
executecmds);
|
executecmds);
|
||||||
|
|
||||||
/* Skip leading whitespace between condition and the command */
|
/* Skip leading whitespace between condition and the command */
|
||||||
|
@ -1443,7 +1441,7 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
|
||||||
/* Process the first command, if there is one */
|
/* Process the first command, if there is one */
|
||||||
if (executecmds && firstcmd && *firstcmd) {
|
if (executecmds && firstcmd && *firstcmd) {
|
||||||
WCHAR *command = WCMD_strdupW(firstcmd);
|
WCHAR *command = WCMD_strdupW(firstcmd);
|
||||||
WCMD_execute (firstcmd, (*cmdList)->redirects, variable, value, cmdList, FALSE);
|
WCMD_execute (firstcmd, (*cmdList)->redirects, cmdList, FALSE);
|
||||||
HeapFree(GetProcessHeap(), 0, command);
|
HeapFree(GetProcessHeap(), 0, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1471,15 +1469,15 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
|
||||||
if ((*cmdList)->prevDelim == CMD_ONFAILURE ||
|
if ((*cmdList)->prevDelim == CMD_ONFAILURE ||
|
||||||
(*cmdList)->prevDelim == CMD_ONSUCCESS) {
|
(*cmdList)->prevDelim == CMD_ONSUCCESS) {
|
||||||
if (processThese && (*cmdList)->command) {
|
if (processThese && (*cmdList)->command) {
|
||||||
WCMD_execute ((*cmdList)->command, (*cmdList)->redirects, variable,
|
WCMD_execute ((*cmdList)->command, (*cmdList)->redirects,
|
||||||
value, cmdList, FALSE);
|
cmdList, FALSE);
|
||||||
}
|
}
|
||||||
if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand;
|
if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand;
|
||||||
|
|
||||||
/* Execute any appended to the statement with (...) */
|
/* Execute any appended to the statement with (...) */
|
||||||
} else if ((*cmdList)->bracketDepth > myDepth) {
|
} else if ((*cmdList)->bracketDepth > myDepth) {
|
||||||
if (processThese) {
|
if (processThese) {
|
||||||
*cmdList = WCMD_process_commands(*cmdList, TRUE, variable, value, FALSE);
|
*cmdList = WCMD_process_commands(*cmdList, TRUE, FALSE);
|
||||||
WINE_TRACE("Back from processing commands, (next = %p)\n", *cmdList);
|
WINE_TRACE("Back from processing commands, (next = %p)\n", *cmdList);
|
||||||
}
|
}
|
||||||
if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand;
|
if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand;
|
||||||
|
@ -1501,7 +1499,7 @@ static void WCMD_part_execute(CMD_LIST **cmdList, const WCHAR *firstcmd,
|
||||||
/* Skip leading whitespace between condition and the command */
|
/* Skip leading whitespace between condition and the command */
|
||||||
while (*cmd && (*cmd==' ' || *cmd=='\t')) cmd++;
|
while (*cmd && (*cmd==' ' || *cmd=='\t')) cmd++;
|
||||||
if (*cmd) {
|
if (*cmd) {
|
||||||
WCMD_execute (cmd, (*cmdList)->redirects, variable, value, cmdList, FALSE);
|
WCMD_execute (cmd, (*cmdList)->redirects, cmdList, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand;
|
if (curPosition == *cmdList) *cmdList = (*cmdList)->nextcommand;
|
||||||
|
@ -1703,7 +1701,7 @@ static void WCMD_add_dirstowalk(DIRECTORY_STACK *dirsToWalk) {
|
||||||
static void WCMD_parse_line(CMD_LIST *cmdStart,
|
static void WCMD_parse_line(CMD_LIST *cmdStart,
|
||||||
const WCHAR *firstCmd,
|
const WCHAR *firstCmd,
|
||||||
CMD_LIST **cmdEnd,
|
CMD_LIST **cmdEnd,
|
||||||
const WCHAR *variable,
|
const WCHAR variable,
|
||||||
WCHAR *buffer,
|
WCHAR *buffer,
|
||||||
BOOL *doExecuted,
|
BOOL *doExecuted,
|
||||||
int *forf_skip,
|
int *forf_skip,
|
||||||
|
@ -1711,6 +1709,8 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
|
||||||
WCHAR *forf_delims) {
|
WCHAR *forf_delims) {
|
||||||
|
|
||||||
WCHAR *parm, *where;
|
WCHAR *parm, *where;
|
||||||
|
FOR_CONTEXT oldcontext;
|
||||||
|
int varidx;
|
||||||
|
|
||||||
/* Skip lines if requested */
|
/* Skip lines if requested */
|
||||||
if (*forf_skip) {
|
if (*forf_skip) {
|
||||||
|
@ -1718,18 +1718,29 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save away any existing for variable context (e.g. nested for loops) */
|
||||||
|
oldcontext = forloopcontext;
|
||||||
|
|
||||||
/* Extract the parameter */
|
/* Extract the parameter */
|
||||||
parm = WCMD_parameter_with_delims(buffer, 0, &where, FALSE, FALSE, forf_delims);
|
parm = WCMD_parameter_with_delims(buffer, 0, &where, FALSE, FALSE, forf_delims);
|
||||||
WINE_TRACE("Parsed parameter: %s from %s\n", wine_dbgstr_w(parm),
|
WINE_TRACE("Parsed parameter: %s from %s\n", wine_dbgstr_w(parm),
|
||||||
wine_dbgstr_w(buffer));
|
wine_dbgstr_w(buffer));
|
||||||
|
|
||||||
|
/* FIXME: Use tokens= line to populate forloopcontext */
|
||||||
|
varidx = FOR_VAR_IDX(variable);
|
||||||
|
if (varidx >=0) forloopcontext.variable[varidx] = WCMD_strdupW(parm);
|
||||||
|
|
||||||
if (where && where[0] != forf_eol) {
|
if (where && where[0] != forf_eol) {
|
||||||
CMD_LIST *thisCmdStart = cmdStart;
|
CMD_LIST *thisCmdStart = cmdStart;
|
||||||
*doExecuted = TRUE;
|
*doExecuted = TRUE;
|
||||||
WCMD_part_execute(&thisCmdStart, firstCmd, variable, parm, FALSE, TRUE);
|
WCMD_part_execute(&thisCmdStart, firstCmd, FALSE, TRUE);
|
||||||
*cmdEnd = thisCmdStart;
|
*cmdEnd = thisCmdStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (varidx >=0) HeapFree(GetProcessHeap(), 0, forloopcontext.variable[varidx]);
|
||||||
|
|
||||||
|
/* Restore the original for variable contextx */
|
||||||
|
forloopcontext = oldcontext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -1778,7 +1789,7 @@ static HANDLE WCMD_forf_getinputhandle(BOOL usebackq, WCHAR *itemstr, BOOL iscmd
|
||||||
wsprintfW(temp_cmd, cmdslashcW, itemstr);
|
wsprintfW(temp_cmd, cmdslashcW, itemstr);
|
||||||
WINE_TRACE("Issuing '%s' with redirs '%s'\n",
|
WINE_TRACE("Issuing '%s' with redirs '%s'\n",
|
||||||
wine_dbgstr_w(temp_cmd), wine_dbgstr_w(temp_str));
|
wine_dbgstr_w(temp_cmd), wine_dbgstr_w(temp_str));
|
||||||
WCMD_execute (temp_cmd, temp_str, NULL, NULL, NULL, FALSE);
|
WCMD_execute (temp_cmd, temp_str, NULL, FALSE);
|
||||||
|
|
||||||
/* Open the file, read line by line and process */
|
/* Open the file, read line by line and process */
|
||||||
hinput = CreateFileW(temp_file, GENERIC_READ, FILE_SHARE_READ,
|
hinput = CreateFileW(temp_file, GENERIC_READ, FILE_SHARE_READ,
|
||||||
|
@ -1814,6 +1825,8 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
static const WCHAR doW[] = {'d','o'};
|
static const WCHAR doW[] = {'d','o'};
|
||||||
CMD_LIST *setStart, *thisSet, *cmdStart, *cmdEnd;
|
CMD_LIST *setStart, *thisSet, *cmdStart, *cmdEnd;
|
||||||
WCHAR variable[4];
|
WCHAR variable[4];
|
||||||
|
int varidx = -1;
|
||||||
|
WCHAR *oldvariablevalue;
|
||||||
WCHAR *firstCmd;
|
WCHAR *firstCmd;
|
||||||
int thisDepth;
|
int thisDepth;
|
||||||
WCHAR optionsRoot[MAX_PATH];
|
WCHAR optionsRoot[MAX_PATH];
|
||||||
|
@ -1905,6 +1918,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
/* Variable should follow */
|
/* Variable should follow */
|
||||||
strcpyW(variable, thisArg);
|
strcpyW(variable, thisArg);
|
||||||
WINE_TRACE("Variable identified as %s\n", wine_dbgstr_w(variable));
|
WINE_TRACE("Variable identified as %s\n", wine_dbgstr_w(variable));
|
||||||
|
varidx = FOR_VAR_IDX(variable[1]);
|
||||||
|
|
||||||
/* Ensure line continues with IN */
|
/* Ensure line continues with IN */
|
||||||
thisArg = WCMD_parameter(p, parameterNo++, NULL, FALSE, FALSE);
|
thisArg = WCMD_parameter(p, parameterNo++, NULL, FALSE, FALSE);
|
||||||
|
@ -2022,8 +2036,16 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
strcpyW(fullitem, fd.cFileName);
|
strcpyW(fullitem, fd.cFileName);
|
||||||
}
|
}
|
||||||
doExecuted = TRUE;
|
doExecuted = TRUE;
|
||||||
WCMD_part_execute (&thisCmdStart, firstCmd, variable,
|
|
||||||
fullitem, FALSE, 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) {
|
||||||
|
oldvariablevalue = forloopcontext.variable[varidx];
|
||||||
|
forloopcontext.variable[varidx] = fullitem;
|
||||||
|
}
|
||||||
|
WCMD_part_execute (&thisCmdStart, firstCmd, FALSE, TRUE);
|
||||||
|
if (varidx >= 0) forloopcontext.variable[varidx] = oldvariablevalue;
|
||||||
|
|
||||||
cmdEnd = thisCmdStart;
|
cmdEnd = thisCmdStart;
|
||||||
}
|
}
|
||||||
} while (FindNextFileW(hff, &fd) != 0);
|
} while (FindNextFileW(hff, &fd) != 0);
|
||||||
|
@ -2031,7 +2053,16 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doExecuted = TRUE;
|
doExecuted = TRUE;
|
||||||
WCMD_part_execute(&thisCmdStart, firstCmd, variable, fullitem, FALSE, 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) {
|
||||||
|
oldvariablevalue = forloopcontext.variable[varidx];
|
||||||
|
forloopcontext.variable[varidx] = fullitem;
|
||||||
|
}
|
||||||
|
WCMD_part_execute (&thisCmdStart, firstCmd, FALSE, TRUE);
|
||||||
|
if (varidx >= 0) forloopcontext.variable[varidx] = oldvariablevalue;
|
||||||
|
|
||||||
cmdEnd = thisCmdStart;
|
cmdEnd = thisCmdStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2075,7 +2106,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
|
|
||||||
/* Read line by line until end of file */
|
/* Read line by line until end of file */
|
||||||
while (WCMD_fgets(buffer, sizeof(buffer)/sizeof(WCHAR), input)) {
|
while (WCMD_fgets(buffer, sizeof(buffer)/sizeof(WCHAR), input)) {
|
||||||
WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted,
|
WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable[1], buffer, &doExecuted,
|
||||||
&forf_skip, forf_eol, forf_delims);
|
&forf_skip, forf_eol, forf_delims);
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
}
|
}
|
||||||
|
@ -2103,7 +2134,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
|
|
||||||
/* Copy the item away from the global buffer used by WCMD_parameter */
|
/* Copy the item away from the global buffer used by WCMD_parameter */
|
||||||
strcpyW(buffer, itemStart);
|
strcpyW(buffer, itemStart);
|
||||||
WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted,
|
WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable[1], buffer, &doExecuted,
|
||||||
&forf_skip, forf_eol, forf_delims);
|
&forf_skip, forf_eol, forf_delims);
|
||||||
|
|
||||||
/* Only one string can be supplied in the whole set, abort future set processing */
|
/* Only one string can be supplied in the whole set, abort future set processing */
|
||||||
|
@ -2135,7 +2166,15 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
|
|
||||||
thisCmdStart = cmdStart;
|
thisCmdStart = cmdStart;
|
||||||
doExecuted = TRUE;
|
doExecuted = TRUE;
|
||||||
WCMD_part_execute(&thisCmdStart, firstCmd, variable, thisNum, FALSE, 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) {
|
||||||
|
oldvariablevalue = forloopcontext.variable[varidx];
|
||||||
|
forloopcontext.variable[varidx] = thisNum;
|
||||||
|
}
|
||||||
|
WCMD_part_execute (&thisCmdStart, firstCmd, FALSE, TRUE);
|
||||||
|
if (varidx >= 0) forloopcontext.variable[varidx] = oldvariablevalue;
|
||||||
}
|
}
|
||||||
cmdEnd = thisCmdStart;
|
cmdEnd = thisCmdStart;
|
||||||
}
|
}
|
||||||
|
@ -2160,7 +2199,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
||||||
if (!doExecuted) {
|
if (!doExecuted) {
|
||||||
thisCmdStart = cmdStart;
|
thisCmdStart = cmdStart;
|
||||||
WINE_TRACE("Skipping for loop commands due to no valid iterations\n");
|
WINE_TRACE("Skipping for loop commands due to no valid iterations\n");
|
||||||
WCMD_part_execute(&thisCmdStart, firstCmd, NULL, NULL, FALSE, FALSE);
|
WCMD_part_execute(&thisCmdStart, firstCmd, FALSE, FALSE);
|
||||||
cmdEnd = thisCmdStart;
|
cmdEnd = thisCmdStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2510,7 +2549,7 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList)
|
||||||
|
|
||||||
/* Process rest of IF statement which is on the same line
|
/* Process rest of IF statement which is on the same line
|
||||||
Note: This may process all or some of the cmdList (eg a GOTO) */
|
Note: This may process all or some of the cmdList (eg a GOTO) */
|
||||||
WCMD_part_execute(cmdList, command, NULL, NULL, TRUE, (test != negate));
|
WCMD_part_execute(cmdList, command, TRUE, (test != negate));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
syntax_err:
|
syntax_err:
|
||||||
|
|
|
@ -648,16 +648,16 @@ B'
|
||||||
"A B"
|
"A B"
|
||||||
C
|
C
|
||||||
--- imbricated FORs
|
--- imbricated FORs
|
||||||
@todo_wine@X Y
|
X Y
|
||||||
@todo_wine@X Y
|
X Y
|
||||||
@todo_wine@A C
|
A C
|
||||||
@todo_wine@A D
|
A D
|
||||||
@todo_wine@B C
|
B C
|
||||||
@todo_wine@B D
|
B D
|
||||||
@todo_wine@A C
|
A C
|
||||||
@todo_wine@A D
|
A D
|
||||||
@todo_wine@B C
|
B C
|
||||||
@todo_wine@B D
|
B D
|
||||||
--- basic wildcards
|
--- basic wildcards
|
||||||
bazbaz
|
bazbaz
|
||||||
--- for /d
|
--- for /d
|
||||||
|
|
|
@ -112,7 +112,7 @@ WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, BOOL raw,
|
||||||
BOOL wholecmdline, const WCHAR *delims);
|
BOOL wholecmdline, const WCHAR *delims);
|
||||||
WCHAR *WCMD_skip_leading_spaces (WCHAR *string);
|
WCHAR *WCMD_skip_leading_spaces (WCHAR *string);
|
||||||
BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr);
|
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_HandleTildaModifiers(WCHAR **start, BOOL justFors);
|
||||||
|
|
||||||
void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
|
void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
|
||||||
void WCMD_strip_quotes(WCHAR *cmd);
|
void WCMD_strip_quotes(WCHAR *cmd);
|
||||||
|
@ -122,11 +122,9 @@ void WCMD_strsubstW(WCHAR *start, const WCHAR* next, const WCHAR* insert, int le
|
||||||
BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars, LPDWORD charsRead);
|
BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars, LPDWORD charsRead);
|
||||||
|
|
||||||
WCHAR *WCMD_ReadAndParseLine(const WCHAR *initialcmd, CMD_LIST **output, HANDLE readFrom);
|
WCHAR *WCMD_ReadAndParseLine(const WCHAR *initialcmd, CMD_LIST **output, HANDLE readFrom);
|
||||||
CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket,
|
CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket, BOOL retrycall);
|
||||||
const WCHAR *var, const WCHAR *val, BOOL retrycall);
|
|
||||||
void WCMD_free_commands(CMD_LIST *cmds);
|
void WCMD_free_commands(CMD_LIST *cmds);
|
||||||
void WCMD_execute (const WCHAR *orig_command, const WCHAR *redirects,
|
void WCMD_execute (const WCHAR *orig_command, const WCHAR *redirects,
|
||||||
const WCHAR *parameter, const WCHAR *substitution,
|
|
||||||
CMD_LIST **cmdList, BOOL retrycall);
|
CMD_LIST **cmdList, BOOL retrycall);
|
||||||
|
|
||||||
/* Data structure to hold context when executing batch files */
|
/* Data structure to hold context when executing batch files */
|
||||||
|
@ -163,6 +161,16 @@ typedef struct _DIRECTORY_STACK
|
||||||
WCHAR *fileName;
|
WCHAR *fileName;
|
||||||
} DIRECTORY_STACK;
|
} DIRECTORY_STACK;
|
||||||
|
|
||||||
|
/* Data structure to for loop variables during for body execution, bearing
|
||||||
|
in mind that for loops can be nested */
|
||||||
|
#define MAX_FOR_VARIABLES 52
|
||||||
|
#define FOR_VAR_IDX(c) (((c)>='a'&&(c)<='z')?((c)-'a'):\
|
||||||
|
((c)>='A'&&(c)<='Z')?(26+(c)-'A'):-1)
|
||||||
|
|
||||||
|
typedef struct _FOR_CONTEXT {
|
||||||
|
WCHAR *variable[MAX_FOR_VARIABLES]; /* a-z then A-Z */
|
||||||
|
} FOR_CONTEXT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global variables quals, param1, param2 contain the current qualifiers
|
* Global variables quals, param1, param2 contain the current qualifiers
|
||||||
* (uppercased and concatenated) and parameters entered, with environment
|
* (uppercased and concatenated) and parameters entered, with environment
|
||||||
|
@ -171,6 +179,7 @@ typedef struct _DIRECTORY_STACK
|
||||||
extern WCHAR quals[MAX_PATH], param1[MAXSTRING], param2[MAXSTRING];
|
extern WCHAR quals[MAX_PATH], param1[MAXSTRING], param2[MAXSTRING];
|
||||||
extern DWORD errorlevel;
|
extern DWORD errorlevel;
|
||||||
extern BATCH_CONTEXT *context;
|
extern BATCH_CONTEXT *context;
|
||||||
|
extern FOR_CONTEXT forloopcontext;
|
||||||
|
|
||||||
#endif /* !RC_INVOKED */
|
#endif /* !RC_INVOKED */
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ BATCH_CONTEXT *context = NULL;
|
||||||
DWORD errorlevel;
|
DWORD errorlevel;
|
||||||
WCHAR quals[MAX_PATH], param1[MAXSTRING], param2[MAXSTRING];
|
WCHAR quals[MAX_PATH], param1[MAXSTRING], param2[MAXSTRING];
|
||||||
BOOL interactive;
|
BOOL interactive;
|
||||||
|
FOR_CONTEXT forloopcontext; /* The 'for' loop context */
|
||||||
|
|
||||||
int defaultColor = 7;
|
int defaultColor = 7;
|
||||||
BOOL echo_mode = TRUE;
|
BOOL echo_mode = TRUE;
|
||||||
|
@ -549,8 +550,8 @@ static inline BOOL WCMD_is_magic_envvar(const WCHAR *s, const WCHAR *magicvar)
|
||||||
*
|
*
|
||||||
* Expands environment variables, allowing for WCHARacter substitution
|
* Expands environment variables, allowing for WCHARacter substitution
|
||||||
*/
|
*/
|
||||||
static WCHAR *WCMD_expand_envvar(WCHAR *start,
|
static WCHAR *WCMD_expand_envvar(WCHAR *start)
|
||||||
const WCHAR *forVar, const WCHAR *forVal) {
|
{
|
||||||
WCHAR *endOfVar = NULL, *s;
|
WCHAR *endOfVar = NULL, *s;
|
||||||
WCHAR *colonpos = NULL;
|
WCHAR *colonpos = NULL;
|
||||||
WCHAR thisVar[MAXSTRING];
|
WCHAR thisVar[MAXSTRING];
|
||||||
|
@ -565,8 +566,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start,
|
||||||
static const WCHAR Random[] = {'R','A','N','D','O','M','\0'};
|
static const WCHAR Random[] = {'R','A','N','D','O','M','\0'};
|
||||||
static const WCHAR Delims[] = {'%',':','\0'};
|
static const WCHAR Delims[] = {'%',':','\0'};
|
||||||
|
|
||||||
WINE_TRACE("Expanding: %s (%s,%s)\n", wine_dbgstr_w(start),
|
WINE_TRACE("Expanding: %s\n", wine_dbgstr_w(start));
|
||||||
wine_dbgstr_w(forVal), wine_dbgstr_w(forVar));
|
|
||||||
|
|
||||||
/* Find the end of the environment variable, and extract name */
|
/* Find the end of the environment variable, and extract name */
|
||||||
endOfVar = strpbrkW(start+1, Delims);
|
endOfVar = strpbrkW(start+1, Delims);
|
||||||
|
@ -629,17 +629,6 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start,
|
||||||
static const WCHAR fmt[] = {'%','d','\0'};
|
static const WCHAR fmt[] = {'%','d','\0'};
|
||||||
wsprintfW(thisVarContents, fmt, rand() % 32768);
|
wsprintfW(thisVarContents, fmt, rand() % 32768);
|
||||||
len = strlenW(thisVarContents);
|
len = strlenW(thisVarContents);
|
||||||
|
|
||||||
/* Look for a matching 'for' variable */
|
|
||||||
} else if (forVar &&
|
|
||||||
(CompareStringW(LOCALE_USER_DEFAULT,
|
|
||||||
SORT_STRINGSORT,
|
|
||||||
thisVar,
|
|
||||||
(colonpos - thisVar) - 1,
|
|
||||||
forVar, -1) == CSTR_EQUAL)) {
|
|
||||||
strcpyW(thisVarContents, forVal);
|
|
||||||
len = strlenW(thisVarContents);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
len = ExpandEnvironmentStringsW(thisVar, thisVarContents,
|
len = ExpandEnvironmentStringsW(thisVar, thisVarContents,
|
||||||
|
@ -802,8 +791,7 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start,
|
||||||
* read in and not again, except for 'for' variable substitution.
|
* read in and not again, except for 'for' variable substitution.
|
||||||
* eg. As evidence, "echo %1 && shift && echo %1" or "echo %%path%%"
|
* eg. As evidence, "echo %1 && shift && echo %1" or "echo %%path%%"
|
||||||
*/
|
*/
|
||||||
static void handleExpansion(WCHAR *cmd, BOOL justFors,
|
static void handleExpansion(WCHAR *cmd, BOOL justFors) {
|
||||||
const WCHAR *forVariable, const WCHAR *forValue) {
|
|
||||||
|
|
||||||
/* For commands in a context (batch program): */
|
/* For commands in a context (batch program): */
|
||||||
/* Expand environment variables in a batch file %{0-9} first */
|
/* Expand environment variables in a batch file %{0-9} first */
|
||||||
|
@ -818,6 +806,15 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors,
|
||||||
WCHAR *t;
|
WCHAR *t;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Display the FOR variables in effect */
|
||||||
|
for (i=0;i<52;i++) {
|
||||||
|
if (forloopcontext.variable[i]) {
|
||||||
|
WINE_TRACE("FOR variable context: %c = '%s'\n",
|
||||||
|
i<26?i+'a':(i-26)+'A',
|
||||||
|
wine_dbgstr_w(forloopcontext.variable[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while ((p = strchrW(p, '%'))) {
|
while ((p = strchrW(p, '%'))) {
|
||||||
|
|
||||||
WINE_TRACE("Translate command:%s %d (at: %s)\n",
|
WINE_TRACE("Translate command:%s %d (at: %s)\n",
|
||||||
|
@ -833,7 +830,7 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors,
|
||||||
|
|
||||||
/* Replace %~ modifications if in batch program */
|
/* Replace %~ modifications if in batch program */
|
||||||
} else if (*(p+1) == '~') {
|
} else if (*(p+1) == '~') {
|
||||||
WCMD_HandleTildaModifiers(&p, forVariable, forValue, justFors);
|
WCMD_HandleTildaModifiers(&p, justFors);
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
/* Replace use of %0...%9 if in batch program*/
|
/* Replace use of %0...%9 if in batch program*/
|
||||||
|
@ -853,20 +850,18 @@ static void handleExpansion(WCHAR *cmd, BOOL justFors,
|
||||||
} else
|
} else
|
||||||
WCMD_strsubstW(p, p+2, NULL, 0);
|
WCMD_strsubstW(p, p+2, NULL, 0);
|
||||||
|
|
||||||
} else if (forVariable &&
|
} else {
|
||||||
(CompareStringW(LOCALE_USER_DEFAULT,
|
int forvaridx = FOR_VAR_IDX(*(p+1));
|
||||||
SORT_STRINGSORT,
|
if (forvaridx != -1 && forloopcontext.variable[forvaridx]) {
|
||||||
p,
|
/* Replace the 2 characters, % and for variable character */
|
||||||
strlenW(forVariable),
|
WCMD_strsubstW(p, p + 2, forloopcontext.variable[forvaridx], -1);
|
||||||
forVariable, -1) == CSTR_EQUAL)) {
|
} else if (!justFors) {
|
||||||
WCMD_strsubstW(p, p + strlenW(forVariable), forValue, -1);
|
p = WCMD_expand_envvar(p);
|
||||||
|
|
||||||
} else if (!justFors) {
|
/* In a FOR loop, see if this is the variable to replace */
|
||||||
p = WCMD_expand_envvar(p, forVariable, forValue);
|
} else { /* Ignore %'s on second pass of batch program */
|
||||||
|
p++;
|
||||||
/* In a FOR loop, see if this is the variable to replace */
|
}
|
||||||
} else { /* Ignore %'s on second pass of batch program */
|
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1224,7 +1219,7 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||||
|
|
||||||
/* Parse the command string, without reading any more input */
|
/* Parse the command string, without reading any more input */
|
||||||
WCMD_ReadAndParseLine(command, &toExecute, INVALID_HANDLE_VALUE);
|
WCMD_ReadAndParseLine(command, &toExecute, INVALID_HANDLE_VALUE);
|
||||||
WCMD_process_commands(toExecute, FALSE, NULL, NULL, called);
|
WCMD_process_commands(toExecute, FALSE, called);
|
||||||
WCMD_free_commands(toExecute);
|
WCMD_free_commands(toExecute);
|
||||||
toExecute = NULL;
|
toExecute = NULL;
|
||||||
return;
|
return;
|
||||||
|
@ -1248,7 +1243,6 @@ void WCMD_run_program (WCHAR *command, BOOL called)
|
||||||
* we are attempting this retry.
|
* we are attempting this retry.
|
||||||
*/
|
*/
|
||||||
void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
|
void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
|
||||||
const WCHAR *forVariable, const WCHAR *forValue,
|
|
||||||
CMD_LIST **cmdList, BOOL retrycall)
|
CMD_LIST **cmdList, BOOL retrycall)
|
||||||
{
|
{
|
||||||
WCHAR *cmd, *p, *redir;
|
WCHAR *cmd, *p, *redir;
|
||||||
|
@ -1267,9 +1261,8 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
|
||||||
STD_ERROR_HANDLE};
|
STD_ERROR_HANDLE};
|
||||||
BOOL prev_echo_mode, piped = FALSE;
|
BOOL prev_echo_mode, piped = FALSE;
|
||||||
|
|
||||||
WINE_TRACE("command on entry:%s (%p), with forVariable '%s'='%s'\n",
|
WINE_TRACE("command on entry:%s (%p)\n",
|
||||||
wine_dbgstr_w(command), cmdList,
|
wine_dbgstr_w(command), cmdList);
|
||||||
wine_dbgstr_w(forVariable), wine_dbgstr_w(forValue));
|
|
||||||
|
|
||||||
/* If the next command is a pipe then we implement pipes by redirecting
|
/* If the next command is a pipe then we implement pipes by redirecting
|
||||||
the output from this command to a temp file and input into the
|
the output from this command to a temp file and input into the
|
||||||
|
@ -1323,8 +1316,8 @@ void WCMD_execute (const WCHAR *command, const WCHAR *redirects,
|
||||||
|
|
||||||
/* Expand variables in command line mode only (batch mode will
|
/* Expand variables in command line mode only (batch mode will
|
||||||
be expanded as the line is read in, except for 'for' loops) */
|
be expanded as the line is read in, except for 'for' loops) */
|
||||||
handleExpansion(new_cmd, (context != NULL), forVariable, forValue);
|
handleExpansion(new_cmd, (context != NULL));
|
||||||
handleExpansion(new_redir, (context != NULL), forVariable, forValue);
|
handleExpansion(new_redir, (context != NULL));
|
||||||
cmd = new_cmd;
|
cmd = new_cmd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1847,7 +1840,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Replace env vars if in a batch context */
|
/* Replace env vars if in a batch context */
|
||||||
if (context) handleExpansion(extraSpace, FALSE, NULL, NULL);
|
if (context) handleExpansion(extraSpace, FALSE);
|
||||||
|
|
||||||
/* Skip preceding whitespace */
|
/* Skip preceding whitespace */
|
||||||
while (*curPos == ' ' || *curPos == '\t') curPos++;
|
while (*curPos == ' ' || *curPos == '\t') curPos++;
|
||||||
|
@ -2244,7 +2237,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
|
|
||||||
} while (*extraData == 0x00);
|
} while (*extraData == 0x00);
|
||||||
curPos = extraSpace;
|
curPos = extraSpace;
|
||||||
if (context) handleExpansion(extraSpace, FALSE, NULL, NULL);
|
if (context) handleExpansion(extraSpace, FALSE);
|
||||||
/* Continue to echo commands IF echo is on and in batch program */
|
/* Continue to echo commands IF echo is on and in batch program */
|
||||||
if (context && echo_mode && extraSpace[0] && (extraSpace[0] != '@')) {
|
if (context && echo_mode && extraSpace[0] && (extraSpace[0] != '@')) {
|
||||||
WCMD_output_asis(extraSpace);
|
WCMD_output_asis(extraSpace);
|
||||||
|
@ -2265,7 +2258,6 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_LIST **output, HANDLE
|
||||||
* Process all the commands read in so far
|
* 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,
|
||||||
const WCHAR *var, const WCHAR *val,
|
|
||||||
BOOL retrycall) {
|
BOOL retrycall) {
|
||||||
|
|
||||||
int bdepth = -1;
|
int bdepth = -1;
|
||||||
|
@ -2291,7 +2283,7 @@ CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket,
|
||||||
Also, skip over any batch labels (eg. :fred) */
|
Also, skip over any batch labels (eg. :fred) */
|
||||||
if (thisCmd->command && thisCmd->command[0] != ':') {
|
if (thisCmd->command && thisCmd->command[0] != ':') {
|
||||||
WINE_TRACE("Executing command: '%s'\n", wine_dbgstr_w(thisCmd->command));
|
WINE_TRACE("Executing command: '%s'\n", wine_dbgstr_w(thisCmd->command));
|
||||||
WCMD_execute (thisCmd->command, thisCmd->redirects, var, val, &thisCmd, retrycall);
|
WCMD_execute (thisCmd->command, thisCmd->redirects, &thisCmd, retrycall);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step on unless the command itself already stepped on */
|
/* Step on unless the command itself already stepped on */
|
||||||
|
@ -2581,7 +2573,7 @@ int wmain (int argc, WCHAR *argvW[])
|
||||||
|
|
||||||
/* Parse the command string, without reading any more input */
|
/* Parse the command string, without reading any more input */
|
||||||
WCMD_ReadAndParseLine(cmd, &toExecute, INVALID_HANDLE_VALUE);
|
WCMD_ReadAndParseLine(cmd, &toExecute, INVALID_HANDLE_VALUE);
|
||||||
WCMD_process_commands(toExecute, FALSE, NULL, NULL, FALSE);
|
WCMD_process_commands(toExecute, FALSE, FALSE);
|
||||||
WCMD_free_commands(toExecute);
|
WCMD_free_commands(toExecute);
|
||||||
toExecute = NULL;
|
toExecute = NULL;
|
||||||
|
|
||||||
|
@ -2668,7 +2660,7 @@ int wmain (int argc, WCHAR *argvW[])
|
||||||
if (opt_k) {
|
if (opt_k) {
|
||||||
/* Parse the command string, without reading any more input */
|
/* Parse the command string, without reading any more input */
|
||||||
WCMD_ReadAndParseLine(cmd, &toExecute, INVALID_HANDLE_VALUE);
|
WCMD_ReadAndParseLine(cmd, &toExecute, INVALID_HANDLE_VALUE);
|
||||||
WCMD_process_commands(toExecute, FALSE, NULL, NULL, FALSE);
|
WCMD_process_commands(toExecute, FALSE, FALSE);
|
||||||
WCMD_free_commands(toExecute);
|
WCMD_free_commands(toExecute);
|
||||||
toExecute = NULL;
|
toExecute = NULL;
|
||||||
HeapFree(GetProcessHeap(), 0, cmd);
|
HeapFree(GetProcessHeap(), 0, cmd);
|
||||||
|
@ -2688,7 +2680,7 @@ int wmain (int argc, WCHAR *argvW[])
|
||||||
if (echo_mode) WCMD_show_prompt();
|
if (echo_mode) WCMD_show_prompt();
|
||||||
if (!WCMD_ReadAndParseLine(NULL, &toExecute, GetStdHandle(STD_INPUT_HANDLE)))
|
if (!WCMD_ReadAndParseLine(NULL, &toExecute, GetStdHandle(STD_INPUT_HANDLE)))
|
||||||
break;
|
break;
|
||||||
WCMD_process_commands(toExecute, FALSE, NULL, NULL, FALSE);
|
WCMD_process_commands(toExecute, FALSE, FALSE);
|
||||||
WCMD_free_commands(toExecute);
|
WCMD_free_commands(toExecute);
|
||||||
toExecute = NULL;
|
toExecute = NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue