mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
Various fixes to the way cmd handles errorlevel and the "return values" of commands:
- Changed type of return values from BOOL to INT, with 0 indicating success and any other value indicating failure. If the left side of an || operator returns nonzero, errorlevel is set to that value. - The return value of a batch file or FOR is the return value of the last command executed in it. An empty batch file returns 0, unless it was CALLed, in which case it returns errorlevel. - CALL sets errorlevel to the return value of whatever was called. - Running a GUI program doesn't change errorlevel, but always returns 0. - CMD /C uses the command's return value, not errorlevel, as the process exit code. svn path=/trunk/; revision=40474
This commit is contained in:
parent
54f4f31dae
commit
8cf11060a9
7 changed files with 108 additions and 85 deletions
|
@ -203,11 +203,12 @@ VOID ExitBatch()
|
|||
*
|
||||
*/
|
||||
|
||||
BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
|
||||
INT Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
|
||||
{
|
||||
BATCH_CONTEXT new;
|
||||
LPFOR_CONTEXT saved_fc;
|
||||
INT i;
|
||||
INT ret = 0;
|
||||
|
||||
HANDLE hFile;
|
||||
SetLastError(0);
|
||||
|
@ -221,7 +222,7 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd
|
|||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ConErrResPuts(STRING_BATCH_ERROR);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (bc != NULL && Cmd == bc->current)
|
||||
|
@ -238,10 +239,19 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd
|
|||
else
|
||||
{
|
||||
struct _SETLOCAL *setlocal = NULL;
|
||||
/* If a batch file runs another batch file as part of a compound command
|
||||
* (e.g. "x.bat & somethingelse") then the first file gets terminated. */
|
||||
if (bc && Cmd != NULL)
|
||||
|
||||
if (Cmd == NULL)
|
||||
{
|
||||
/* This is a CALL. CALL will set errorlevel to our return value, so
|
||||
* in order to keep the value of errorlevel unchanged in the case
|
||||
* of calling an empty batch file, we must return that same value. */
|
||||
ret = nErrorLevel;
|
||||
}
|
||||
else if (bc)
|
||||
{
|
||||
/* If a batch file runs another batch file as part of a compound command
|
||||
* (e.g. "x.bat & somethingelse") then the first file gets terminated. */
|
||||
|
||||
/* Get its SETLOCAL stack so it can be migrated to the new context */
|
||||
setlocal = bc->setlocal;
|
||||
bc->setlocal = NULL;
|
||||
|
@ -272,7 +282,7 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd
|
|||
if (bc->raw_params == NULL)
|
||||
{
|
||||
error_out_of_memory();
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check if this is a "CALL :label" */
|
||||
|
@ -303,14 +313,14 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd
|
|||
}
|
||||
|
||||
bc->current = Cmd;
|
||||
ExecuteCommand(Cmd);
|
||||
ret = ExecuteCommand(Cmd);
|
||||
FreeCommand(Cmd);
|
||||
}
|
||||
|
||||
TRACE ("Batch: returns TRUE\n");
|
||||
|
||||
fc = saved_fc;
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
VOID AddBatchRedirection(REDIRECTION **RedirList)
|
||||
|
|
|
@ -47,7 +47,7 @@ extern TCHAR textline[BATCH_BUFFSIZE]; /* Buffer for reading Batch file lines */
|
|||
LPTSTR FindArg (TCHAR, BOOL *);
|
||||
LPTSTR BatchParams (LPTSTR, LPTSTR);
|
||||
VOID ExitBatch ();
|
||||
BOOL Batch (LPTSTR, LPTSTR, LPTSTR, PARSED_COMMAND *);
|
||||
INT Batch (LPTSTR, LPTSTR, LPTSTR, PARSED_COMMAND *);
|
||||
LPTSTR ReadBatchLine();
|
||||
VOID AddBatchRedirection(REDIRECTION **);
|
||||
|
||||
|
|
|
@ -73,10 +73,12 @@ INT cmd_call (LPTSTR param)
|
|||
/* CALL :label - call a subroutine of the current batch file */
|
||||
while (*param == _T(' '))
|
||||
param++;
|
||||
return !Batch(bc->BatchFilePath, first, param, NULL);
|
||||
nErrorLevel = Batch(bc->BatchFilePath, first, param, NULL);
|
||||
return nErrorLevel;
|
||||
}
|
||||
|
||||
return !DoCommand(first, param, NULL);
|
||||
nErrorLevel = DoCommand(first, param, NULL);
|
||||
return nErrorLevel;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -308,7 +308,7 @@ HANDLE RunFile(DWORD flags, LPTSTR filename, LPTSTR params,
|
|||
* Rest - rest of command line
|
||||
*/
|
||||
|
||||
static BOOL
|
||||
static INT
|
||||
Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
||||
{
|
||||
TCHAR szFullName[MAX_PATH];
|
||||
|
@ -363,7 +363,7 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
|||
}
|
||||
|
||||
if (!working) ConErrResPuts (STRING_FREE_ERROR1);
|
||||
return working;
|
||||
return !working;
|
||||
}
|
||||
|
||||
/* get the PATH environment variable and parse it */
|
||||
|
@ -372,7 +372,7 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
|||
if (!SearchForExecutable(First, szFullName))
|
||||
{
|
||||
error_bad_command(first);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
GetConsoleTitle (szWindowTitle, MAX_PATH);
|
||||
|
@ -384,7 +384,7 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
|||
while (*rest == _T(' '))
|
||||
rest++;
|
||||
TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest));
|
||||
Batch (szFullName, first, rest, Cmd);
|
||||
dwExitCode = Batch(szFullName, first, rest, Cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -448,17 +448,13 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
|||
GetExitCodeProcess (prci.hProcess, &dwExitCode);
|
||||
nErrorLevel = (INT)dwExitCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
nErrorLevel = 0;
|
||||
}
|
||||
CloseHandle (prci.hProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE ("[ShellExecute failed!: %s]\n", debugstr_aw(Full));
|
||||
error_bad_command (first);
|
||||
nErrorLevel = 1;
|
||||
dwExitCode = 1;
|
||||
}
|
||||
|
||||
// restore console mode
|
||||
|
@ -472,7 +468,7 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
|||
OutputCodePage = GetConsoleOutputCP();
|
||||
SetConsoleTitle (szWindowTitle);
|
||||
|
||||
return nErrorLevel == 0;
|
||||
return dwExitCode;
|
||||
}
|
||||
|
||||
|
||||
|
@ -485,7 +481,7 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
|||
* rest - rest of command line
|
||||
*/
|
||||
|
||||
BOOL
|
||||
INT
|
||||
DoCommand(LPTSTR first, LPTSTR rest, PARSED_COMMAND *Cmd)
|
||||
{
|
||||
TCHAR com[_tcslen(first) + _tcslen(rest) + 2]; /* full command line */
|
||||
|
@ -530,7 +526,7 @@ DoCommand(LPTSTR first, LPTSTR rest, PARSED_COMMAND *Cmd)
|
|||
if (_tcsicmp(cmdptr->name, _T("echo")) != 0)
|
||||
while (_istspace(*param))
|
||||
param++;
|
||||
return !cmdptr->func(param);
|
||||
return cmdptr->func(param);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -543,14 +539,16 @@ DoCommand(LPTSTR first, LPTSTR rest, PARSED_COMMAND *Cmd)
|
|||
* full input/output redirection and piping are supported
|
||||
*/
|
||||
|
||||
VOID ParseCommandLine (LPTSTR cmd)
|
||||
INT ParseCommandLine (LPTSTR cmd)
|
||||
{
|
||||
INT Ret = 0;
|
||||
PARSED_COMMAND *Cmd = ParseCommand(cmd);
|
||||
if (Cmd)
|
||||
{
|
||||
ExecuteCommand(Cmd);
|
||||
Ret = ExecuteCommand(Cmd);
|
||||
FreeCommand(Cmd);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* Execute a command without waiting for it to finish. If it's an internal
|
||||
|
@ -679,27 +677,27 @@ failed:
|
|||
#endif
|
||||
}
|
||||
|
||||
BOOL
|
||||
INT
|
||||
ExecuteCommand(PARSED_COMMAND *Cmd)
|
||||
{
|
||||
PARSED_COMMAND *Sub;
|
||||
LPTSTR First, Rest;
|
||||
BOOL Success = TRUE;
|
||||
INT Ret = 0;
|
||||
|
||||
if (!PerformRedirection(Cmd->Redirections))
|
||||
return FALSE;
|
||||
return 1;
|
||||
|
||||
switch (Cmd->Type)
|
||||
{
|
||||
case C_COMMAND:
|
||||
Success = FALSE;
|
||||
Ret = 1;
|
||||
First = DoDelayedExpansion(Cmd->Command.First);
|
||||
if (First)
|
||||
{
|
||||
Rest = DoDelayedExpansion(Cmd->Command.Rest);
|
||||
if (Rest)
|
||||
{
|
||||
Success = DoCommand(First, Rest, Cmd);
|
||||
Ret = DoCommand(First, Rest, Cmd);
|
||||
cmd_free(Rest);
|
||||
}
|
||||
cmd_free(First);
|
||||
|
@ -709,31 +707,36 @@ ExecuteCommand(PARSED_COMMAND *Cmd)
|
|||
case C_BLOCK:
|
||||
case C_MULTI:
|
||||
for (Sub = Cmd->Subcommands; Sub; Sub = Sub->Next)
|
||||
Success = ExecuteCommand(Sub);
|
||||
Ret = ExecuteCommand(Sub);
|
||||
break;
|
||||
case C_IFFAILURE:
|
||||
Sub = Cmd->Subcommands;
|
||||
Ret = ExecuteCommand(Sub);
|
||||
if (Ret != 0)
|
||||
{
|
||||
nErrorLevel = Ret;
|
||||
Ret = ExecuteCommand(Sub->Next);
|
||||
}
|
||||
break;
|
||||
case C_IFSUCCESS:
|
||||
Sub = Cmd->Subcommands;
|
||||
Success = ExecuteCommand(Sub);
|
||||
if (Success == (Cmd->Type - C_IFFAILURE))
|
||||
{
|
||||
Sub = Sub->Next;
|
||||
Success = ExecuteCommand(Sub);
|
||||
}
|
||||
Ret = ExecuteCommand(Sub);
|
||||
if (Ret == 0)
|
||||
Ret = ExecuteCommand(Sub->Next);
|
||||
break;
|
||||
case C_PIPE:
|
||||
ExecutePipeline(Cmd);
|
||||
break;
|
||||
case C_IF:
|
||||
Success = ExecuteIf(Cmd);
|
||||
Ret = ExecuteIf(Cmd);
|
||||
break;
|
||||
case C_FOR:
|
||||
Success = ExecuteFor(Cmd);
|
||||
Ret = ExecuteFor(Cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
UndoRedirection(Cmd->Redirections, NULL);
|
||||
return Success;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -1402,7 +1405,7 @@ ReadLine (TCHAR *commandline, BOOL bMore)
|
|||
return SubstituteVars(ip, commandline, _T('%'));
|
||||
}
|
||||
|
||||
static INT
|
||||
static VOID
|
||||
ProcessInput()
|
||||
{
|
||||
PARSED_COMMAND *Cmd;
|
||||
|
@ -1416,8 +1419,6 @@ ProcessInput()
|
|||
ExecuteCommand(Cmd);
|
||||
FreeCommand(Cmd);
|
||||
}
|
||||
|
||||
return nErrorLevel;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1614,6 +1615,7 @@ Initialize()
|
|||
TCHAR commandline[CMDLINE_LENGTH];
|
||||
TCHAR ModuleName[_MAX_PATH + 1];
|
||||
TCHAR lpBuffer[2];
|
||||
INT nExitCode;
|
||||
|
||||
//INT len;
|
||||
TCHAR *ptr, *cmdLine, option = 0;
|
||||
|
@ -1760,9 +1762,12 @@ Initialize()
|
|||
{
|
||||
/* Do the /C or /K command */
|
||||
GetCmdLineCommand(commandline, &ptr[2], AlwaysStrip);
|
||||
ParseCommandLine(commandline);
|
||||
nExitCode = ParseCommandLine(commandline);
|
||||
if (option != _T('K'))
|
||||
{
|
||||
nErrorLevel = nExitCode;
|
||||
bExit = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1806,7 +1811,6 @@ int cmd_main (int argc, const TCHAR *argv[])
|
|||
HANDLE hConsole;
|
||||
TCHAR startPath[MAX_PATH];
|
||||
CONSOLE_SCREEN_BUFFER_INFO Info;
|
||||
INT nExitCode;
|
||||
|
||||
lpOriginalEnvironment = DuplicateEnvironment();
|
||||
|
||||
|
@ -1839,15 +1843,15 @@ int cmd_main (int argc, const TCHAR *argv[])
|
|||
Initialize();
|
||||
|
||||
/* call prompt routine */
|
||||
nExitCode = ProcessInput();
|
||||
ProcessInput();
|
||||
|
||||
/* do the cleanup */
|
||||
Cleanup();
|
||||
|
||||
cmd_free(lpOriginalEnvironment);
|
||||
|
||||
cmd_exit(nExitCode);
|
||||
return(nExitCode);
|
||||
cmd_exit(nErrorLevel);
|
||||
return(nErrorLevel);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -102,16 +102,16 @@ INT cmd_cls (LPTSTR);
|
|||
/* Prototypes for CMD.C */
|
||||
INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, INT len, BOOL bPutSeperator);
|
||||
HANDLE RunFile(DWORD, LPTSTR, LPTSTR, LPTSTR, INT);
|
||||
VOID ParseCommandLine (LPTSTR);
|
||||
INT ParseCommandLine(LPTSTR);
|
||||
struct _PARSED_COMMAND;
|
||||
BOOL ExecuteCommand(struct _PARSED_COMMAND *Cmd);
|
||||
INT ExecuteCommand(struct _PARSED_COMMAND *Cmd);
|
||||
LPCTSTR GetEnvVarOrSpecial ( LPCTSTR varName );
|
||||
VOID AddBreakHandler (VOID);
|
||||
VOID RemoveBreakHandler (VOID);
|
||||
BOOL SubstituteVars(TCHAR *Src, TCHAR *Dest, TCHAR Delim);
|
||||
BOOL SubstituteForVars(TCHAR *Src, TCHAR *Dest);
|
||||
LPTSTR DoDelayedExpansion(LPTSTR Line);
|
||||
BOOL DoCommand(LPTSTR first, LPTSTR rest, struct _PARSED_COMMAND *Cmd);
|
||||
INT DoCommand(LPTSTR first, LPTSTR rest, struct _PARSED_COMMAND *Cmd);
|
||||
BOOL ReadLine(TCHAR *commandline, BOOL bMore);
|
||||
int cmd_main (int argc, const TCHAR *argv[]);
|
||||
|
||||
|
@ -254,7 +254,7 @@ VOID CompleteFilename (LPTSTR, BOOL, LPTSTR, UINT);
|
|||
#define FOR_LOOP 4 /* /L */
|
||||
#define FOR_RECURSIVE 8 /* /R */
|
||||
INT cmd_for (LPTSTR);
|
||||
BOOL ExecuteFor(struct _PARSED_COMMAND *Cmd);
|
||||
INT ExecuteFor(struct _PARSED_COMMAND *Cmd);
|
||||
|
||||
|
||||
/* Prototypes for FREE.C */
|
||||
|
@ -283,7 +283,7 @@ INT CommandHistory (LPTSTR param);
|
|||
enum { IF_CMDEXTVERSION, IF_DEFINED, IF_ERRORLEVEL, IF_EXIST,
|
||||
IF_STRINGEQ, /* == */
|
||||
IF_EQU, IF_GTR, IF_GEQ, IF_LSS, IF_LEQ, IF_NEQ };
|
||||
BOOL ExecuteIf(struct _PARSED_COMMAND *Cmd);
|
||||
INT ExecuteIf(struct _PARSED_COMMAND *Cmd);
|
||||
|
||||
|
||||
/* Prototypes for INTERNAL.C */
|
||||
|
|
|
@ -69,7 +69,7 @@ static BOOL GetNextElement(TCHAR **pStart, TCHAR **pEnd)
|
|||
}
|
||||
|
||||
/* Execute a single instance of a FOR command */
|
||||
static void RunInstance(PARSED_COMMAND *Cmd)
|
||||
static INT RunInstance(PARSED_COMMAND *Cmd)
|
||||
{
|
||||
if (bEcho && !bDisableBatchEcho && Cmd->Subcommands->Type != C_QUIET)
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ static void RunInstance(PARSED_COMMAND *Cmd)
|
|||
ConOutChar(_T('\n'));
|
||||
}
|
||||
/* Just run the command (variable expansion is done in DoDelayedExpansion) */
|
||||
ExecuteCommand(Cmd->Subcommands);
|
||||
return ExecuteCommand(Cmd->Subcommands);
|
||||
}
|
||||
|
||||
/* Check if this FOR should be terminated early */
|
||||
|
@ -117,7 +117,7 @@ static LPTSTR ReadFileContents(FILE *InputFile, TCHAR *Buffer)
|
|||
return Contents;
|
||||
}
|
||||
|
||||
static BOOL ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
||||
static INT ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
||||
{
|
||||
LPTSTR Delims = _T(" \t");
|
||||
TCHAR Eol = _T(';');
|
||||
|
@ -129,6 +129,7 @@ static BOOL ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
|||
LPTSTR Variables[32];
|
||||
TCHAR *Start, *End;
|
||||
INT i;
|
||||
INT Ret = 0;
|
||||
|
||||
if (Cmd->For.Params)
|
||||
{
|
||||
|
@ -228,7 +229,7 @@ static BOOL ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
|||
{
|
||||
error:
|
||||
error_syntax(Param);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +271,7 @@ static BOOL ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
|||
if (!InputFile)
|
||||
{
|
||||
error_bad_command(Start + 1);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
FullInput = ReadFileContents(InputFile, Buffer);
|
||||
_pclose(InputFile);
|
||||
|
@ -286,7 +287,7 @@ static BOOL ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
|||
if (!InputFile)
|
||||
{
|
||||
error_sfile_not_found(Start);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
FullInput = ReadFileContents(InputFile, Buffer);
|
||||
fclose(InputFile);
|
||||
|
@ -295,7 +296,7 @@ static BOOL ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
|||
if (!FullInput)
|
||||
{
|
||||
error_out_of_memory();
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Loop over the input line by line */
|
||||
|
@ -337,20 +338,21 @@ static BOOL ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
|||
|
||||
/* Don't run unless the line had enough tokens to fill at least one variable */
|
||||
if (*Variables[0])
|
||||
RunInstance(Cmd);
|
||||
Ret = RunInstance(Cmd);
|
||||
} while (!Exiting(Cmd) && (In = NextLine) != NULL);
|
||||
cmd_free(FullInput);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* FOR /L: Do a numeric loop */
|
||||
static void ForLoop(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
||||
static INT ForLoop(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
||||
{
|
||||
enum { START, STEP, END };
|
||||
INT params[3] = { 0, 0, 0 };
|
||||
INT i;
|
||||
INT Ret = 0;
|
||||
|
||||
TCHAR *Start, *End = List;
|
||||
for (i = 0; i < 3 && GetNextElement(&Start, &End); i++)
|
||||
|
@ -361,17 +363,19 @@ static void ForLoop(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
|
|||
(params[STEP] >= 0 ? (i <= params[END]) : (i >= params[END])))
|
||||
{
|
||||
_itot(i, Buffer, 10);
|
||||
RunInstance(Cmd);
|
||||
Ret = RunInstance(Cmd);
|
||||
i += params[STEP];
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* Process a FOR in one directory. Stored in Buffer (up to BufPos) is a
|
||||
* string which is prefixed to each element of the list. In a normal FOR
|
||||
* it will be empty, but in FOR /R it will be the directory name. */
|
||||
static void ForDir(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
|
||||
static INT ForDir(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
|
||||
{
|
||||
TCHAR *Start, *End = List;
|
||||
INT Ret = 0;
|
||||
while (!Exiting(Cmd) && GetNextElement(&Start, &End))
|
||||
{
|
||||
if (BufPos + (End - Start) > &Buffer[CMDLINE_LENGTH])
|
||||
|
@ -402,22 +406,24 @@ static void ForDir(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPo
|
|||
_tcscmp(w32fd.cFileName, _T("..")) == 0)
|
||||
continue;
|
||||
_tcscpy(FilePart, w32fd.cFileName);
|
||||
RunInstance(Cmd);
|
||||
Ret = RunInstance(Cmd);
|
||||
} while (!Exiting(Cmd) && FindNextFile(hFind, &w32fd));
|
||||
FindClose(hFind);
|
||||
}
|
||||
else
|
||||
{
|
||||
RunInstance(Cmd);
|
||||
Ret = RunInstance(Cmd);
|
||||
}
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* FOR /R: Process a FOR in each directory of a tree, recursively. */
|
||||
static void ForRecursive(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
|
||||
static INT ForRecursive(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
|
||||
{
|
||||
HANDLE hFind;
|
||||
WIN32_FIND_DATA w32fd;
|
||||
INT Ret = 0;
|
||||
|
||||
if (BufPos[-1] != _T('\\'))
|
||||
{
|
||||
|
@ -425,12 +431,12 @@ static void ForRecursive(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR
|
|||
*BufPos = _T('\0');
|
||||
}
|
||||
|
||||
ForDir(Cmd, List, Buffer, BufPos);
|
||||
Ret = ForDir(Cmd, List, Buffer, BufPos);
|
||||
|
||||
_tcscpy(BufPos, _T("*"));
|
||||
hFind = FindFirstFile(Buffer, &w32fd);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
return Ret;
|
||||
do
|
||||
{
|
||||
if (!(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
|
@ -438,9 +444,10 @@ static void ForRecursive(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR
|
|||
if (_tcscmp(w32fd.cFileName, _T(".")) == 0 ||
|
||||
_tcscmp(w32fd.cFileName, _T("..")) == 0)
|
||||
continue;
|
||||
ForRecursive(Cmd, List, Buffer, _stpcpy(BufPos, w32fd.cFileName));
|
||||
Ret = ForRecursive(Cmd, List, Buffer, _stpcpy(BufPos, w32fd.cFileName));
|
||||
} while (!Exiting(Cmd) && FindNextFile(hFind, &w32fd));
|
||||
FindClose(hFind);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -449,18 +456,18 @@ ExecuteFor(PARSED_COMMAND *Cmd)
|
|||
TCHAR Buffer[CMDLINE_LENGTH]; /* Buffer to hold the variable value */
|
||||
LPTSTR BufferPtr = Buffer;
|
||||
LPFOR_CONTEXT lpNew;
|
||||
BOOL Success = TRUE;
|
||||
INT Ret;
|
||||
LPTSTR List = DoDelayedExpansion(Cmd->For.List);
|
||||
|
||||
if (!List)
|
||||
return FALSE;
|
||||
return 1;
|
||||
|
||||
/* Create our FOR context */
|
||||
lpNew = cmd_alloc(sizeof(FOR_CONTEXT));
|
||||
if (!lpNew)
|
||||
{
|
||||
cmd_free(List);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
lpNew->prev = fc;
|
||||
lpNew->firstvar = Cmd->For.Variable;
|
||||
|
@ -472,21 +479,21 @@ ExecuteFor(PARSED_COMMAND *Cmd)
|
|||
|
||||
if (Cmd->For.Switches & FOR_F)
|
||||
{
|
||||
Success = ForF(Cmd, List, Buffer);
|
||||
Ret = ForF(Cmd, List, Buffer);
|
||||
}
|
||||
else if (Cmd->For.Switches & FOR_LOOP)
|
||||
{
|
||||
ForLoop(Cmd, List, Buffer);
|
||||
Ret = ForLoop(Cmd, List, Buffer);
|
||||
}
|
||||
else if (Cmd->For.Switches & FOR_RECURSIVE)
|
||||
{
|
||||
DWORD Len = GetFullPathName(Cmd->For.Params ? Cmd->For.Params : _T("."),
|
||||
MAX_PATH, Buffer, NULL);
|
||||
ForRecursive(Cmd, List, Buffer, &Buffer[Len]);
|
||||
Ret = ForRecursive(Cmd, List, Buffer, &Buffer[Len]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ForDir(Cmd, List, Buffer, Buffer);
|
||||
Ret = ForDir(Cmd, List, Buffer, Buffer);
|
||||
}
|
||||
|
||||
/* Remove our context, unless someone already did that */
|
||||
|
@ -495,7 +502,7 @@ ExecuteFor(PARSED_COMMAND *Cmd)
|
|||
|
||||
cmd_free(lpNew);
|
||||
cmd_free(List);
|
||||
return Success;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -63,7 +63,7 @@ INT cmd_if (LPTSTR param)
|
|||
return 1;
|
||||
}
|
||||
|
||||
BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
||||
INT ExecuteIf(PARSED_COMMAND *Cmd)
|
||||
{
|
||||
INT result = FALSE; /* when set cause 'then' clause to be executed */
|
||||
LPTSTR param;
|
||||
|
@ -73,13 +73,13 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
{
|
||||
Left = DoDelayedExpansion(Cmd->If.LeftArg);
|
||||
if (!Left)
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
Right = DoDelayedExpansion(Cmd->If.RightArg);
|
||||
if (!Right)
|
||||
{
|
||||
cmd_free(Left);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Cmd->If.Operator == IF_CMDEXTVERSION)
|
||||
|
@ -91,7 +91,7 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
{
|
||||
error_syntax(Right);
|
||||
cmd_free(Right);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
result = (2 >= n);
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
{
|
||||
error_syntax(Right);
|
||||
cmd_free(Right);
|
||||
return FALSE;
|
||||
return 1;
|
||||
}
|
||||
result = (nErrorLevel >= n);
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
/* full condition was false, do the "else" command if there is one */
|
||||
if (Cmd->Subcommands->Next)
|
||||
return ExecuteCommand(Cmd->Subcommands->Next);
|
||||
return TRUE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue