diff --git a/reactos/base/shell/cmd/batch.c b/reactos/base/shell/cmd/batch.c index 1eb60cb6ded..ffcd1a975ea 100644 --- a/reactos/base/shell/cmd/batch.c +++ b/reactos/base/shell/cmd/batch.c @@ -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 */ diff --git a/reactos/base/shell/cmd/batch.h b/reactos/base/shell/cmd/batch.h index a8545a8e9cf..28022b16f3d 100644 --- a/reactos/base/shell/cmd/batch.h +++ b/reactos/base/shell/cmd/batch.h @@ -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 diff --git a/reactos/base/shell/cmd/call.c b/reactos/base/shell/cmd/call.c index 833ec834ddc..3418ccd6e2f 100644 --- a/reactos/base/shell/cmd/call.c +++ b/reactos/base/shell/cmd/call.c @@ -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); diff --git a/reactos/base/shell/cmd/cmd.c b/reactos/base/shell/cmd/cmd.c index 3d3be277242..280deb511ba 100644 --- a/reactos/base/shell/cmd/cmd.c +++ b/reactos/base/shell/cmd/cmd.c @@ -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); diff --git a/reactos/base/shell/cmd/cmd.h b/reactos/base/shell/cmd/cmd.h index 485e5127ed5..5944eb117c2 100644 --- a/reactos/base/shell/cmd/cmd.h +++ b/reactos/base/shell/cmd/cmd.h @@ -374,7 +374,7 @@ typedef struct _PARSED_COMMAND TCHAR Variable; LPTSTR Params; LPTSTR List; - struct tagBATCHCONTEXT *Context; + struct tagFORCONTEXT *Context; } For; }; } PARSED_COMMAND; diff --git a/reactos/base/shell/cmd/for.c b/reactos/base/shell/cmd/for.c index becdb71d618..5489605260c 100644 --- a/reactos/base/shell/cmd/for.c +++ b/reactos/base/shell/cmd/for.c @@ -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; }