https://git.reactos.org/?p=reactos.git;a=commitdiff;h=17e094cd34648d48d3804…
commit 17e094cd34648d48d3804f9419b78718fb2c207e
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Jul 19 21:30:50 2020 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Sep 23 00:22:48 2020 +0200
[CMD] SET: Diverse fixes for the arithmetic-expression parser (/A option).
- Detect whether a division by zero is done, and fail if so.
- Detect whether an invalid number is provided:
* If _tcstol() fails with errno == ERANGE, we've got an overflow or
underflow.
* If the next character where _tcstol() is not a whitespace but is a
character compatible with the first character of an identifier, the
number is invalid.
- Add + to the list of existing unary operators (!,~,-), and parse them
where many of these are present. Indeed, expressions like: +3, -+-+3,
!!-+3 (or with other unary ops, etc.) are valid.
- Operators constituted of more than one characters, can contain
whitespace separating their constituting characters.
Thus, "a + = 3" is equivalent to "a += 3" (and the same for -=, *=,
/=, %=, &=, |= and ^=), and "a < < 3" is equivalent to "a << 3" (and
the same for >>, <<= and >>=).
- After evaluating everything, if unparsed data remains, fail and bail out.
- Return Windows' CMD-compatible errorlevels.
See https://ss64.com/nt/set.html for more details.
Fixes some cmd_winetests.
---
base/shell/cmd/set.c | 171 +++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 147 insertions(+), 24 deletions(-)
diff --git a/base/shell/cmd/set.c b/base/shell/cmd/set.c
index beded9515fc..1adf091ad84 100644
--- a/base/shell/cmd/set.c
+++ b/base/shell/cmd/set.c
@@ -112,14 +112,22 @@ INT cmd_set(LPTSTR param)
if (!_tcsnicmp(param, _T("/A"), 2))
{
BOOL Success;
+
+ /* Save error level since seta_eval() modifies it, as
+ * we need to set it later according to specific rules. */
+ INT nOldErrorLevel = nErrorLevel;
+
StripQuotes(param);
Success = seta_eval(skip_ws(param + 2));
if (!Success)
{
+#if 0
/* Might seem random but this is what windows xp does -- This is a message ID */
retval = 9165;
+#endif
+ retval = nErrorLevel;
+ nErrorLevel = nOldErrorLevel;
}
- // return !Success;
else
{
retval = 0;
@@ -287,12 +295,33 @@ calc(INT* lval, TCHAR op, INT rval)
case '*':
*lval *= rval;
break;
+
case '/':
+ {
+ if (rval == 0)
+ {
+ // FIXME: Localize
+ ConErrPuts(_T("Division by zero error.\n"));
+ nErrorLevel = 0x400023D1; // 1073750993;
+ return FALSE;
+ }
*lval /= rval;
break;
+ }
+
case '%':
+ {
+ if (rval == 0)
+ {
+ // FIXME: Localize
+ ConErrPuts(_T("Division by zero error.\n"));
+ nErrorLevel = 0x400023D1; // 1073750993;
+ return FALSE;
+ }
*lval %= rval;
break;
+ }
+
case '+':
*lval += rval;
break;
@@ -308,8 +337,10 @@ calc(INT* lval, TCHAR op, INT rval)
case '|':
*lval |= rval;
break;
+
default:
ConErrResPuts(STRING_INVALID_OPERAND);
+ nErrorLevel = 0x400023CE; // 1073750990;
return FALSE;
}
return TRUE;
@@ -322,23 +353,47 @@ static BOOL
seta_unaryTerm(LPCTSTR* p_, INT* result)
{
LPCTSTR p = *p_;
+ INT rval;
if (*p == _T('('))
{
- INT rval;
p = skip_ws(p + 1);
if (!seta_stmt(&p, &rval))
return FALSE;
if (*p++ != _T(')'))
{
ConErrResPuts(STRING_EXPECTED_CLOSE_PAREN);
+ nErrorLevel = 0x400023CC; // 1073750988;
return FALSE;
}
*result = rval;
}
- else if (isdigit(*p))
+ else if (_istdigit(*p))
{
- *result = _tcstol(p, (LPTSTR*)&p, 0);
+ errno = 0;
+ rval = _tcstol(p, (LPTSTR*)&p, 0);
+
+ /* Check for overflow / underflow */
+ if (errno == ERANGE)
+ {
+ // FIXME: Localize
+ ConErrPuts(_T("Invalid number. Numbers are limited to 32-bits of precision.\n"));
+ nErrorLevel = 0x400023D0; // 1073750992;
+ return FALSE;
+ }
+ /*
+ * _tcstol() stopped at the first non-digit character. If it's not a whitespace,
+ * or if it's the start of a possible identifier, this means the number being
+ * interpreted was invalid.
+ */
+ else if (*p && !_istspace(*p) && __iscsymf(*p))
+ {
+ // FIXME: Localize
+ ConErrPuts(_T("Invalid number. Numeric constants are either decimal (42), hexadecimal (0x2A), or octal (052).\n"));
+ nErrorLevel = 0x400023CF; // 1073750991;
+ return FALSE;
+ }
+ *result = rval;
}
else if (__iscsymf(*p))
{
@@ -350,6 +405,7 @@ seta_unaryTerm(LPCTSTR* p_, INT* result)
else
{
ConErrResPuts(STRING_EXPECTED_NUMBER_OR_VARIABLE);
+ nErrorLevel = 0x400023CD; // 1073750989;
return FALSE;
}
*p_ = skip_ws(p);
@@ -363,24 +419,36 @@ seta_mulTerm(LPCTSTR* p_, INT* result)
TCHAR op = 0;
INT rval;
- if (_tcschr(_T("!~-"), *p))
+ if (_tcschr(_T("!~-+"), *p))
{
op = *p;
p = skip_ws(p + 1);
+
+ if (!seta_mulTerm(&p, &rval))
+ return FALSE;
+
+ switch (op)
+ {
+ case '!':
+ rval = !rval;
+ break;
+ case '~':
+ rval = ~rval;
+ break;
+ case '-':
+ rval = -rval;
+ break;
+#if 0
+ case '+':
+ rval = rval;
+ break;
+#endif
+ }
}
- if (!seta_unaryTerm(&p, &rval))
- return FALSE;
- switch (op)
+ else
{
- case '!':
- rval = !rval;
- break;
- case '~':
- rval = ~rval;
- break;
- case '-':
- rval = -rval;
- break;
+ if (!seta_unaryTerm(&p, &rval))
+ return FALSE;
}
*result = rval;
@@ -442,12 +510,18 @@ seta_bitAndTerm(LPCTSTR* p_, INT* result)
return FALSE;
/* Handle << >> operators */
- while (*p && _tcschr(_T("<>"), *p) && p[0] == p[1])
+ while (*p && _tcschr(_T("<>"), *p))
{
INT rval;
TCHAR op = *p;
- p = skip_ws(p + 2);
+ /* Check whether the next non-whitespace character is the same operator */
+ p = skip_ws(p + 1);
+ if (*p != op)
+ break;
+
+ /* Skip it */
+ p = skip_ws(p + 1);
/* Evaluate the immediate right-hand side */
if (!seta_logShiftTerm(&p, &rval))
@@ -473,6 +547,7 @@ seta_bitAndTerm(LPCTSTR* p_, INT* result)
default:
ConErrResPuts(STRING_INVALID_OPERAND);
+ nErrorLevel = 0x400023CE; // 1073750990;
return FALSE;
}
}
@@ -512,17 +587,56 @@ seta_assignment(LPCTSTR* p_, INT* result)
if (identlen)
{
p = skip_ws(p);
+
/* Handle = assignment */
if (*p == _T('='))
- op = *p, p = skip_ws(p + 1);
+ {
+ op = *p;
+ p = skip_ws(p + 1);
+ }
/* Handle *= /= %= += -= &= ^= |= assignments */
- else if (_tcschr(_T("*/%+-&^|"), *p) && p[1] == _T('='))
- op = *p, p = skip_ws(p + 2);
+ else if (_tcschr(_T("*/%+-&^|"), *p))
+ {
+ op = *p;
+
+ /* Find the '=', there may be some spaces before it */
+ p = skip_ws(p + 1);
+ if (*p != _T('='))
+ {
+ op = 0;
+ goto evaluate;
+ }
+
+ /* Skip it */
+ p = skip_ws(p + 1);
+ }
/* Handle <<= >>= assignments */
- else if (_tcschr(_T("<>"), *p) && *p == p[1] && p[2] == _T('='))
- op = *p, p = skip_ws(p + 3);
+ else if (_tcschr(_T("<>"), *p))
+ {
+ op = *p;
+
+ /* Check whether the next non-whitespace character is the same operator */
+ p = skip_ws(p + 1);
+ if (*p != op)
+ {
+ op = 0;
+ goto evaluate;
+ }
+
+ /* Find the '=', there may be some spaces before it */
+ p = skip_ws(p + 1);
+ if (*p != _T('='))
+ {
+ op = 0;
+ goto evaluate;
+ }
+
+ /* Skip it */
+ p = skip_ws(p + 1);
+ }
}
+evaluate:
/* Allow to chain multiple assignments, such as: a=b=1 */
if (ident && op)
{
@@ -613,11 +727,20 @@ seta_eval(LPCTSTR p)
if (!*p)
{
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
+ nErrorLevel = 1;
return FALSE;
}
if (!seta_stmt(&p, &rval))
return FALSE;
+ /* If unparsed data remains, fail and bail out */
+ if (*p)
+ {
+ ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT); // Actually syntax error / missing operand.
+ nErrorLevel = 0x400023CE; // 1073750990;
+ return FALSE;
+ }
+
/* Echo the result of the evaluation only in interactive (non-batch) mode */
if (!bc)
ConOutPrintf(_T("%i"), rval);
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=63316df5202f6f038cc47…
commit 63316df5202f6f038cc47841ed81544fc18263e0
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Wed Jul 1 02:15:52 2020 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Wed Sep 23 00:22:46 2020 +0200
[CMD] Change ERRORLEVEL behaviour for commands ASSOC, PATH, PROMPT and SET.
Commands APPEND/DPATH and FTYPE are also concerned by this; however
we do not implement them in our CMD.EXE yet.
These commands set the ERRORLEVEL differently, whether or not they are
run manually from the command-line/from a .BAT file, or from a .CMD file:
- From command-line/.BAT file, these commands set the ERRORLEVEL only if
an error occurs. So, if two commands are run consecutively and the first
one fails, the ERRORLEVEL will remain set even if the second command
succeeds.
- However, when being run from a .CMD file, these command will always
set the ERRORLEVEL. In the example case described above, the second
command that succeeds will reset the ERRORLEVEL to 0.
This behaviour is determined from the top-level batch/script file being
run. This means that, if a .BAT file is first started, then starts a
.CMD file, the commands will still behave the .BAT way; on the opposite,
if a .CMD file is first started, then starts a .BAT file, these commands
will still behave the .CMD way.
To implement this we introduce one global BATCH_TYPE enum variable that
is initialized to the corresponding batch/script file type when the
top-level script is loaded. It is reset to "none" when that script
terminates.
See https://ss64.com/nt/errorlevel.html for more details,
section "Old style .bat Batch files vs .cmd Batch scripts",
and https://groups.google.com/forum/#!msg/microsoft.public.win2000.cmdprompt.ad…
(comment by Mark Zbikowski).
---
base/shell/cmd/assoc.c | 33 +++++++++++++++++++++++++--------
base/shell/cmd/batch.c | 43 ++++++++++++++++++++++++++++++++++++++-----
base/shell/cmd/batch.h | 16 ++++++++++++++++
base/shell/cmd/path.c | 34 +++++++++++++++++++++++++---------
base/shell/cmd/prompt.c | 17 ++++++++++++++---
base/shell/cmd/set.c | 49 ++++++++++++++++++++++++++++++++++---------------
6 files changed, 152 insertions(+), 40 deletions(-)
diff --git a/base/shell/cmd/assoc.c b/base/shell/cmd/assoc.c
index a9ce5c6682a..3e5611e6b1f 100644
--- a/base/shell/cmd/assoc.c
+++ b/base/shell/cmd/assoc.c
@@ -192,6 +192,7 @@ RemoveAssociation(
INT CommandAssoc(LPTSTR param)
{
+ INT retval = 0;
LPTSTR lpEqualSign;
/* Print help */
@@ -201,12 +202,10 @@ INT CommandAssoc(LPTSTR param)
return 0;
}
- nErrorLevel = 0;
-
if (_tcslen(param) == 0)
{
PrintAllAssociations();
- return 0;
+ goto Quit;
}
lpEqualSign = _tcschr(param, _T('='));
@@ -218,7 +217,8 @@ INT CommandAssoc(LPTSTR param)
{
WARN("Cannot allocate memory for extension!\n");
error_out_of_memory();
- return 1;
+ retval = 1;
+ goto Quit;
}
_tcsncpy(extension, param, lpEqualSign - param);
@@ -228,26 +228,43 @@ INT CommandAssoc(LPTSTR param)
* in the string, then delete the key. */
if (_tcslen(fileType) == 0)
{
- RemoveAssociation(extension);
+ retval = RemoveAssociation(extension);
}
else
/* Otherwise, add the key and print out the association */
{
- AddAssociation(extension, fileType);
+ retval = AddAssociation(extension, fileType);
PrintAssociation(extension);
}
cmd_free(extension);
+
+ if (retval)
+ retval = 1; /* Fixup the error value */
}
else
{
/* No equal sign, print all associations */
- INT retval = PrintAssociation(param);
+ retval = PrintAssociation(param);
if (retval == 0) /* If nothing printed out */
+ {
ConOutResPrintf(STRING_ASSOC_ERROR, param);
+ retval = 1; /* Fixup the error value */
+ }
}
- return 0;
+Quit:
+ if (BatType != CMD_TYPE)
+ {
+ if (retval != 0)
+ nErrorLevel = retval;
+ }
+ else
+ {
+ nErrorLevel = retval;
+ }
+
+ return retval;
}
#endif /* INCLUDE_CMD_ASSOC */
diff --git a/base/shell/cmd/batch.c b/base/shell/cmd/batch.c
index e9a1e5aa76e..5015bd338ea 100644
--- a/base/shell/cmd/batch.c
+++ b/base/shell/cmd/batch.c
@@ -63,6 +63,7 @@
/* The stack of current batch contexts.
* NULL when no batch is active.
*/
+BATCH_TYPE BatType = NONE;
PBATCH_CONTEXT bc = NULL;
BOOL bEcho = TRUE; /* The echo flag */
@@ -209,7 +210,10 @@ VOID ExitBatch(VOID)
/* If there is no more batch contexts, notify the signal handler */
if (!bc)
+ {
CheckCtrlBreak(BREAK_OUTOFBATCH);
+ BatType = NONE;
+ }
}
/*
@@ -258,7 +262,8 @@ INT Batch(LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
INT ret = 0;
INT i;
HANDLE hFile = NULL;
- BOOL bSameFn = FALSE;
+ BOOLEAN bSameFn = FALSE;
+ BOOLEAN bTopLevel;
BATCH_CONTEXT new;
PFOR_CONTEXT saved_fc;
@@ -286,6 +291,13 @@ INT Batch(LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
}
}
+ /*
+ * Remember whether this is a top-level batch context, i.e. if there is
+ * no batch context existing prior (bc == NULL originally), and we are
+ * going to create one below.
+ */
+ bTopLevel = !bc;
+
if (bc != NULL && Cmd == bc->current)
{
/* Then we are transferring to another batch */
@@ -353,14 +365,28 @@ INT Batch(LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
return 1;
}
- /* Check if this is a "CALL :label" */
- if (*firstword == _T(':'))
- ret = cmd_goto(firstword);
-
/* If we are calling from inside a FOR, hide the FOR variables */
saved_fc = fc;
fc = NULL;
+ /* Perform top-level batch initialization */
+ if (bTopLevel)
+ {
+ /* Default the top-level batch context type to .BAT */
+ BatType = BAT_TYPE;
+
+ /* If this is a .CMD file, adjust the type */
+ TCHAR *dot = _tcsrchr(bc->BatchFilePath, _T('.'));
+ if (dot && (!_tcsicmp(dot, _T(".cmd"))))
+ {
+ BatType = CMD_TYPE;
+ }
+ }
+
+ /* Check if this is a "CALL :label" */
+ if (*firstword == _T(':'))
+ ret = cmd_goto(firstword);
+
/* If we have created a new context, don't return
* until this batch file has completed. */
while (bc == &new && !bExit)
@@ -393,6 +419,13 @@ INT Batch(LPTSTR fullname, LPTSTR firstword, LPTSTR param, PARSED_COMMAND *Cmd)
FreeCommand(Cmd);
}
+ /* Perform top-level batch cleanup */
+ if (!bc || bTopLevel)
+ {
+ /* Reset the top-level batch context type */
+ BatType = NONE;
+ }
+
/* Restore the FOR variables */
fc = saved_fc;
diff --git a/base/shell/cmd/batch.h b/base/shell/cmd/batch.h
index d40b640e421..25b8857b1c3 100644
--- a/base/shell/cmd/batch.h
+++ b/base/shell/cmd/batch.h
@@ -4,6 +4,21 @@
#pragma once
+/*
+ * This batch type enumeration allows us to adjust the behaviour of some commands
+ * depending on whether they are run from within a .BAT or a .CMD file.
+ * The behaviour is selected when the top-level batch file is loaded,
+ * and it remains the same for any child batch file that may be loaded later.
+ *
+ * See https://ss64.com/nt/errorlevel.html for more details.
+ */
+typedef enum _BATCH_TYPE
+{
+ NONE,
+ BAT_TYPE, /* Old-style DOS batch file */
+ CMD_TYPE /* New-style NT OS/2 batch file */
+} BATCH_TYPE;
+
typedef struct _BATCH_CONTEXT
{
struct _BATCH_CONTEXT *prev;
@@ -34,6 +49,7 @@ typedef struct _FOR_CONTEXT
* The stack of current batch contexts.
* NULL when no batch is active.
*/
+extern BATCH_TYPE BatType;
extern PBATCH_CONTEXT bc;
extern PFOR_CONTEXT fc;
diff --git a/base/shell/cmd/path.c b/base/shell/cmd/path.c
index 6235b459362..2286a13e674 100644
--- a/base/shell/cmd/path.c
+++ b/base/shell/cmd/path.c
@@ -35,14 +35,14 @@
INT cmd_path(LPTSTR param)
{
+ INT retval = 0;
+
if (!_tcsncmp(param, _T("/?"), 2))
{
ConOutResPaging(TRUE, STRING_PATH_HELP1);
return 0;
}
- nErrorLevel = 0;
-
/* If param is empty, display the PATH environment variable */
if (!param || !*param)
{
@@ -53,7 +53,9 @@ INT cmd_path(LPTSTR param)
if (!pszBuffer)
{
WARN("Cannot allocate memory for pszBuffer!\n");
- return 1;
+ error_out_of_memory();
+ retval = 1;
+ goto Quit;
}
dwBuffer = GetEnvironmentVariable(_T("PATH"), pszBuffer, ENV_BUFFER_SIZE);
@@ -61,7 +63,8 @@ INT cmd_path(LPTSTR param)
{
cmd_free(pszBuffer);
ConErrResPrintf(STRING_SET_ENV_ERROR, _T("PATH"));
- return 0;
+ retval = 0;
+ goto Quit;
}
else if (dwBuffer > ENV_BUFFER_SIZE)
{
@@ -70,8 +73,10 @@ INT cmd_path(LPTSTR param)
if (!pszBuffer)
{
WARN("Cannot reallocate memory for pszBuffer!\n");
+ error_out_of_memory();
cmd_free(pszOldBuffer);
- return 1;
+ retval = 1;
+ goto Quit;
}
GetEnvironmentVariable(_T("PATH"), pszBuffer, dwBuffer);
}
@@ -79,7 +84,8 @@ INT cmd_path(LPTSTR param)
ConOutPrintf(_T("PATH=%s\n"), pszBuffer);
cmd_free(pszBuffer);
- return 0;
+ retval = 0;
+ goto Quit;
}
/* Skip leading '=' */
@@ -89,11 +95,21 @@ INT cmd_path(LPTSTR param)
/* Set PATH environment variable */
if (!SetEnvironmentVariable(_T("PATH"), param))
{
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ }
+
+Quit:
+ if (BatType != CMD_TYPE)
+ {
+ if (retval != 0)
+ nErrorLevel = retval;
+ }
+ else
+ {
+ nErrorLevel = retval;
}
- return 0;
+ return retval;
}
#endif
diff --git a/base/shell/cmd/prompt.c b/base/shell/cmd/prompt.c
index ce47cd70499..d835ea5f1e3 100644
--- a/base/shell/cmd/prompt.c
+++ b/base/shell/cmd/prompt.c
@@ -243,10 +243,11 @@ VOID PrintPrompt(VOID)
INT cmd_prompt(LPTSTR param)
{
+ INT retval = 0;
+
if (!_tcsncmp(param, _T("/?"), 2))
{
ConOutResPaging(TRUE, STRING_PROMPT_HELP1);
-
#ifdef FEATURE_DIRECTORY_STACK
ConOutResPaging(FALSE, STRING_PROMPT_HELP2);
#endif
@@ -263,10 +264,20 @@ INT cmd_prompt(LPTSTR param)
if (!SetEnvironmentVariable(_T("PROMPT"),
(param && param[0] != _T('\0') ? param : NULL)))
{
- return 1;
+ retval = 1;
+ }
+
+ if (BatType != CMD_TYPE)
+ {
+ if (retval != 0)
+ nErrorLevel = retval;
+ }
+ else
+ {
+ nErrorLevel = retval;
}
- return 0;
+ return retval;
}
#endif
diff --git a/base/shell/cmd/set.c b/base/shell/cmd/set.c
index 0128314ca57..beded9515fc 100644
--- a/base/shell/cmd/set.c
+++ b/base/shell/cmd/set.c
@@ -71,6 +71,7 @@ GetQuotedString(TCHAR *p)
INT cmd_set(LPTSTR param)
{
+ INT retval = 0;
LPTSTR p;
LPTSTR lpEnv;
LPTSTR lpOutput;
@@ -103,7 +104,8 @@ INT cmd_set(LPTSTR param)
FreeEnvironmentStrings(lpEnv);
}
- return 0;
+ retval = 0;
+ goto Quit;
}
/* The /A does *NOT* have to be followed by a whitespace */
@@ -115,9 +117,14 @@ INT cmd_set(LPTSTR param)
if (!Success)
{
/* Might seem random but this is what windows xp does -- This is a message ID */
- nErrorLevel = 9165;
+ retval = 9165;
+ }
+ // return !Success;
+ else
+ {
+ retval = 0;
}
- return !Success;
+ goto Quit;
}
if (!_tcsnicmp(param, _T("/P"), 2))
@@ -128,8 +135,8 @@ INT cmd_set(LPTSTR param)
if (!p)
{
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
*p++ = _T('\0');
@@ -138,10 +145,11 @@ INT cmd_set(LPTSTR param)
if (!*value || !SetEnvironmentVariable(param, value))
{
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
- return 0;
+ retval = 0;
+ goto Quit;
}
param = GetQuotedString(param);
@@ -154,15 +162,15 @@ INT cmd_set(LPTSTR param)
{
/* Handle set =val case */
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
*p++ = _T('\0');
if (!SetEnvironmentVariable(param, *p ? p : NULL))
{
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
}
else
@@ -220,12 +228,23 @@ INT cmd_set(LPTSTR param)
if (!bFound)
{
ConErrResPrintf(STRING_SET_ENV_ERROR, param);
- nErrorLevel = 1;
- return 1;
+ retval = 1;
+ goto Quit;
}
}
- return 0;
+Quit:
+ if (BatType != CMD_TYPE)
+ {
+ if (retval != 0)
+ nErrorLevel = retval;
+ }
+ else
+ {
+ nErrorLevel = retval;
+ }
+
+ return retval;
}
static INT