Separate batch file contexts and FOR contexts into two different structs, since they don't actually have anything in common any more

svn path=/trunk/; revision=39846
This commit is contained in:
Jeffrey Morlan 2009-03-02 19:08:25 +00:00
parent 6b888f2d5b
commit 484ee2fa7e
6 changed files with 39 additions and 42 deletions

View file

@ -225,8 +225,7 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, BOOL forcenew)
}
/* Kill any and all FOR contexts */
while (bc && bc->forvar)
ExitBatch (NULL);
fc = NULL;
if (bc == NULL || forcenew)
{
@ -261,8 +260,6 @@ BOOL Batch (LPTSTR fullname, LPTSTR firstword, LPTSTR param, BOOL forcenew)
bc->bEcho = bEcho; /* Preserve echo across batch calls */
bc->shiftlevel = 0;
bc->forvar = _T('\0');
bc->forvarcount = 0;
bc->params = BatchParams (firstword, param);
//
// Allocate enough memory to hold the params and copy them over without modifications
@ -311,9 +308,6 @@ VOID AddBatchRedirection(REDIRECTION **RedirList)
* If no batch file is current or no further executable lines are found
* return NULL.
*
* Here we also look out for FOR bcontext structures which trigger the
* FOR expansion code.
*
* Set eflag to 0 if line is not to be echoed else 1
*/

View file

@ -17,17 +17,24 @@ typedef struct tagBATCHCONTEXT
INT shiftlevel;
BOOL bEcho; /* Preserve echo flag across batch calls */
REDIRECTION *RedirList;
TCHAR forvar;
UINT forvarcount;
LPTSTR *forvalues;
} BATCH_CONTEXT, *LPBATCH_CONTEXT;
typedef struct tagFORCONTEXT
{
struct tagFORCONTEXT *prev;
TCHAR firstvar;
UINT varcount;
LPTSTR *values;
} FOR_CONTEXT, *LPFOR_CONTEXT;
/* The stack of current batch contexts.
* NULL when no batch is active
*/
extern LPBATCH_CONTEXT bc;
extern LPFOR_CONTEXT fc;
extern BOOL bEcho; /* The echo flag */
#define BATCH_BUFFSIZE 8192

View file

@ -83,8 +83,6 @@ INT cmd_call (LPTSTR param)
bc->hBatchFile = INVALID_HANDLE_VALUE;
bc->params = NULL;
bc->shiftlevel = 0;
bc->forvar = 0; /* HBP004 */
bc->forvarcount = 0;
bc->RedirList = NULL;
ParseCommandLine (param);

View file

@ -1273,13 +1273,13 @@ SubstituteForVars(TCHAR *Src, TCHAR *Dest)
if (Src[0] == _T('%') && Src[1] != _T('\0'))
{
/* This might be a variable. Search the list of contexts for it */
BATCH_CONTEXT *Ctx = bc;
while (Ctx && (UINT)(Src[1] - Ctx->forvar) >= Ctx->forvarcount)
FOR_CONTEXT *Ctx = fc;
while (Ctx && (UINT)(Src[1] - Ctx->firstvar) >= Ctx->varcount)
Ctx = Ctx->prev;
if (Ctx)
{
/* Found it */
LPTSTR Value = Ctx->forvalues[Src[1] - Ctx->forvar];
LPTSTR Value = Ctx->values[Src[1] - Ctx->firstvar];
if (Dest + _tcslen(Value) > DestEnd)
return FALSE;
Dest = _stpcpy(Dest, Value);

View file

@ -374,7 +374,7 @@ typedef struct _PARSED_COMMAND
TCHAR Variable;
LPTSTR Params;
LPTSTR List;
struct tagBATCHCONTEXT *Context;
struct tagFORCONTEXT *Context;
} For;
};
} PARSED_COMMAND;

View file

@ -48,6 +48,10 @@ INT cmd_for (LPTSTR param)
return 1;
}
/* The stack of current FOR contexts.
* NULL when no FOR command is active */
LPFOR_CONTEXT fc = NULL;
/* Get the next element of the FOR's list */
static BOOL GetNextElement(TCHAR **pStart, TCHAR **pEnd)
{
@ -81,8 +85,8 @@ static void RunInstance(PARSED_COMMAND *Cmd)
/* Check if this FOR should be terminated early */
static BOOL Exiting(PARSED_COMMAND *Cmd)
{
/* Someone might have removed our context by calling ExitBatch */
return bCtrlBreak || bc != Cmd->For.Context;
/* Someone might have removed our context */
return bCtrlBreak || fc != Cmd->For.Context;
}
/* Read the contents of a text file into memory,
@ -230,10 +234,10 @@ static BOOL ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
/* Count how many variables will be set: one for each token,
* plus maybe one for the remainder */
bc->forvarcount = RemainderVar;
fc->varcount = RemainderVar;
for (i = 1; i < 32; i++)
bc->forvarcount += (Tokens >> i & 1);
bc->forvalues = Variables;
fc->varcount += (Tokens >> i & 1);
fc->values = Variables;
if (*List == StringQuote || *List == CommandQuote)
{
@ -443,34 +447,27 @@ ExecuteFor(PARSED_COMMAND *Cmd)
{
TCHAR Buffer[CMDLINE_LENGTH]; /* Buffer to hold the variable value */
LPTSTR BufferPtr = Buffer;
LPBATCH_CONTEXT lpNew;
LPFOR_CONTEXT lpNew;
BOOL Success = TRUE;
LPTSTR List = DoDelayedExpansion(Cmd->For.List);
if (!List)
return FALSE;
/* Create our pseudo-batch-context */
lpNew = cmd_alloc(sizeof(BATCH_CONTEXT));
/* Create our FOR context */
lpNew = cmd_alloc(sizeof(FOR_CONTEXT));
if (!lpNew)
{
cmd_free(List);
return FALSE;
}
lpNew->prev = fc;
lpNew->firstvar = Cmd->For.Variable;
lpNew->varcount = 1;
lpNew->values = &BufferPtr;
Cmd->For.Context = lpNew;
lpNew->prev = bc;
bc = lpNew;
bc->hBatchFile = INVALID_HANDLE_VALUE;
bc->raw_params = NULL;
bc->params = NULL;
bc->shiftlevel = 0;
bc->forvar = Cmd->For.Variable;
bc->forvarcount = 1;
bc->forvalues = &BufferPtr;
if (bc->prev)
bc->bEcho = bc->prev->bEcho;
else
bc->bEcho = bEcho;
bc->RedirList = NULL;
fc = lpNew;
if (Cmd->For.Switches & FOR_F)
{
@ -492,9 +489,10 @@ ExecuteFor(PARSED_COMMAND *Cmd)
}
/* Remove our context, unless someone already did that */
if (bc == lpNew)
ExitBatch(NULL);
if (fc == lpNew)
fc = lpNew->prev;
cmd_free(lpNew);
cmd_free(List);
return Success;
}