mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
Make delayed environment-variable expansions actually be delayed.
svn path=/trunk/; revision=39597
This commit is contained in:
parent
5d62c3b3a5
commit
122c236111
4 changed files with 64 additions and 25 deletions
|
@ -868,6 +868,7 @@ ExecuteCommand(PARSED_COMMAND *Cmd)
|
|||
{
|
||||
BOOL bNewBatch = TRUE;
|
||||
PARSED_COMMAND *Sub;
|
||||
LPTSTR ExpandedLine;
|
||||
BOOL Success = TRUE;
|
||||
|
||||
if (!PerformRedirection(Cmd->Redirections))
|
||||
|
@ -879,7 +880,14 @@ ExecuteCommand(PARSED_COMMAND *Cmd)
|
|||
if(bc)
|
||||
bNewBatch = FALSE;
|
||||
|
||||
Success = DoCommand(Cmd->Command.CommandLine);
|
||||
ExpandedLine = DoDelayedExpansion(Cmd->Command.CommandLine);
|
||||
if (!ExpandedLine)
|
||||
{
|
||||
Success = FALSE;
|
||||
break;
|
||||
}
|
||||
Success = DoCommand(ExpandedLine);
|
||||
cmd_free(ExpandedLine);
|
||||
|
||||
if(bNewBatch && bc)
|
||||
AddBatchRedirection(&Cmd->Redirections);
|
||||
|
@ -1097,8 +1105,11 @@ GetBatchVar ( LPCTSTR varName, UINT* varNameLen )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
BOOL bNoInteractive;
|
||||
BOOL bIsBatch;
|
||||
|
||||
BOOL
|
||||
SubstituteVars(TCHAR *Src, TCHAR *Dest, TCHAR Delim, BOOL bIsBatch)
|
||||
SubstituteVars(TCHAR *Src, TCHAR *Dest, TCHAR Delim)
|
||||
{
|
||||
#define APPEND(From, Length) { \
|
||||
if (Dest + (Length) > DestEnd) \
|
||||
|
@ -1250,15 +1261,27 @@ too_long:
|
|||
#undef APPEND1
|
||||
}
|
||||
|
||||
LPTSTR
|
||||
DoDelayedExpansion(LPTSTR Line)
|
||||
{
|
||||
TCHAR Buf[CMDLINE_LENGTH];
|
||||
if (!_tcschr(Line, _T('!')))
|
||||
return cmd_dup(Line);
|
||||
|
||||
/* FIXME: Delayed substitutions actually aren't quite the same as
|
||||
* immediate substitutions. In particular, it's possible to escape
|
||||
* the exclamation point using ^. */
|
||||
if (!SubstituteVars(Line, Buf, _T('!')))
|
||||
return NULL;
|
||||
return cmd_dup(Buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* do the prompt/input/process loop
|
||||
*
|
||||
*/
|
||||
|
||||
BOOL bNoInteractive;
|
||||
BOOL bIsBatch;
|
||||
|
||||
BOOL
|
||||
ReadLine (TCHAR *commandline, BOOL bMore)
|
||||
{
|
||||
|
@ -1299,15 +1322,7 @@ ReadLine (TCHAR *commandline, BOOL bMore)
|
|||
bIsBatch = TRUE;
|
||||
}
|
||||
|
||||
if (!SubstituteVars(ip, commandline, _T('%'), bIsBatch))
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: !vars! should be substituted later, after parsing. */
|
||||
if (!SubstituteVars(commandline, readline, _T('!'), bIsBatch))
|
||||
return FALSE;
|
||||
_tcscpy(commandline, readline);
|
||||
|
||||
return TRUE;
|
||||
return SubstituteVars(ip, commandline, _T('%'));
|
||||
}
|
||||
|
||||
static INT
|
||||
|
|
|
@ -102,6 +102,7 @@ BOOL ExecuteCommand(struct _PARSED_COMMAND *Cmd);
|
|||
LPCTSTR GetEnvVarOrSpecial ( LPCTSTR varName );
|
||||
VOID AddBreakHandler (VOID);
|
||||
VOID RemoveBreakHandler (VOID);
|
||||
LPTSTR DoDelayedExpansion(LPTSTR Line);
|
||||
BOOL DoCommand (LPTSTR line);
|
||||
BOOL ReadLine(TCHAR *commandline, BOOL bMore);
|
||||
int cmd_main (int argc, const TCHAR *argv[]);
|
||||
|
|
|
@ -67,15 +67,30 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
{
|
||||
INT result = FALSE; /* when set cause 'then' clause to be executed */
|
||||
LPTSTR param;
|
||||
LPTSTR Left = NULL, Right;
|
||||
|
||||
if (Cmd->If.LeftArg)
|
||||
{
|
||||
Left = DoDelayedExpansion(Cmd->If.LeftArg);
|
||||
if (!Left)
|
||||
return FALSE;
|
||||
}
|
||||
Right = DoDelayedExpansion(Cmd->If.RightArg);
|
||||
if (!Right)
|
||||
{
|
||||
cmd_free(Left);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Cmd->If.Operator == IF_CMDEXTVERSION)
|
||||
{
|
||||
/* IF CMDEXTVERSION n: check if Command Extensions version
|
||||
* is greater or equal to n */
|
||||
DWORD n = _tcstoul(Cmd->If.RightArg, ¶m, 10);
|
||||
DWORD n = _tcstoul(Right, ¶m, 10);
|
||||
if (*param != _T('\0'))
|
||||
{
|
||||
error_syntax(Cmd->If.RightArg);
|
||||
error_syntax(Right);
|
||||
cmd_free(Right);
|
||||
return FALSE;
|
||||
}
|
||||
result = (2 >= n);
|
||||
|
@ -83,7 +98,7 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
else if (Cmd->If.Operator == IF_DEFINED)
|
||||
{
|
||||
/* IF DEFINED var: check if environment variable exists */
|
||||
result = (GetEnvVarOrSpecial(Cmd->If.RightArg) != NULL);
|
||||
result = (GetEnvVarOrSpecial(Right) != NULL);
|
||||
}
|
||||
else if (Cmd->If.Operator == IF_ERRORLEVEL)
|
||||
{
|
||||
|
@ -91,7 +106,8 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
INT n = _tcstol(Cmd->If.RightArg, ¶m, 10);
|
||||
if (*param != _T('\0'))
|
||||
{
|
||||
error_syntax(Cmd->If.RightArg);
|
||||
error_syntax(Right);
|
||||
cmd_free(Right);
|
||||
return FALSE;
|
||||
}
|
||||
result = (nErrorLevel >= n);
|
||||
|
@ -102,9 +118,9 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
WIN32_FIND_DATA f;
|
||||
HANDLE hFind;
|
||||
|
||||
StripQuotes(Cmd->If.RightArg);
|
||||
StripQuotes(Right);
|
||||
|
||||
hFind = FindFirstFile(Cmd->If.RightArg, &f);
|
||||
hFind = FindFirstFile(Right, &f);
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
result = TRUE;
|
||||
|
@ -120,11 +136,11 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
if (Cmd->If.Operator == IF_STRINGEQ)
|
||||
{
|
||||
/* IF str1 == str2 */
|
||||
result = StringCmp(Cmd->If.LeftArg, Cmd->If.RightArg) == 0;
|
||||
result = StringCmp(Left, Right) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GenericCmp(StringCmp, Cmd->If.LeftArg, Cmd->If.RightArg);
|
||||
result = GenericCmp(StringCmp, Left, Right);
|
||||
switch (Cmd->If.Operator)
|
||||
{
|
||||
case IF_EQU: result = (result == 0); break;
|
||||
|
@ -137,6 +153,9 @@ BOOL ExecuteIf(PARSED_COMMAND *Cmd)
|
|||
}
|
||||
}
|
||||
|
||||
cmd_free(Left);
|
||||
cmd_free(Right);
|
||||
|
||||
if (result ^ ((Cmd->If.Flags & IFFLAG_NEGATE) != 0))
|
||||
{
|
||||
/* full condition was true, do the command */
|
||||
|
|
|
@ -54,7 +54,7 @@ BOOL
|
|||
PerformRedirection(REDIRECTION *RedirList)
|
||||
{
|
||||
REDIRECTION *Redir;
|
||||
TCHAR Filename[MAX_PATH];
|
||||
LPTSTR Filename;
|
||||
HANDLE hNew;
|
||||
UINT DupNumber;
|
||||
static SECURITY_ATTRIBUTES SecAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
|
||||
|
@ -78,8 +78,9 @@ PerformRedirection(REDIRECTION *RedirList)
|
|||
|
||||
for (Redir = RedirList; Redir; Redir = Redir->Next)
|
||||
{
|
||||
*Filename = _T('\0');
|
||||
_tcsncat(Filename, Redir->Filename, MAX_PATH - 1);
|
||||
Filename = DoDelayedExpansion(Redir->Filename);
|
||||
if (!Filename)
|
||||
goto redir_error;
|
||||
StripQuotes(Filename);
|
||||
|
||||
if (*Filename == _T('&'))
|
||||
|
@ -112,6 +113,8 @@ PerformRedirection(REDIRECTION *RedirList)
|
|||
{
|
||||
ConErrResPrintf(Redir->Type == REDIR_READ ? STRING_CMD_ERROR1 : STRING_CMD_ERROR3,
|
||||
Filename);
|
||||
cmd_free(Filename);
|
||||
redir_error:
|
||||
/* Undo all the redirections before this one */
|
||||
UndoRedirection(RedirList, Redir);
|
||||
return FALSE;
|
||||
|
@ -123,6 +126,7 @@ PerformRedirection(REDIRECTION *RedirList)
|
|||
SetHandle(Redir->Number, hNew);
|
||||
|
||||
TRACE("%d redirected to: %s\n", Redir->Number, debugstr_aw(Filename));
|
||||
cmd_free(Filename);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue