2006-02-16 23:23:37 +00:00
|
|
|
/*
|
|
|
|
* SET.C - set internal command.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* History:
|
|
|
|
*
|
|
|
|
* 06/14/97 (Tim Norman)
|
2007-08-01 10:17:13 +00:00
|
|
|
* changed static var in set() to a cmd_alloc'd space to pass to putenv.
|
2006-02-16 23:23:37 +00:00
|
|
|
* need to find a better way to do this, since it seems it is wasting
|
|
|
|
* memory when variables are redefined.
|
|
|
|
*
|
|
|
|
* 07/08/1998 (John P. Price)
|
|
|
|
* removed call to show_environment in set command.
|
|
|
|
* moved test for syntax before allocating memory in set command.
|
|
|
|
* misc clean up and optimization.
|
|
|
|
*
|
|
|
|
* 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
|
|
|
* added config.h include
|
|
|
|
*
|
|
|
|
* 28-Jul-1998 (John P Price <linux-guru@gcfl.net>)
|
|
|
|
* added set_env function to set env. variable without needing set command
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 09-Dec-1998 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Added help text ("/?").
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 24-Jan-1999 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Fixed Win32 environment handling.
|
|
|
|
* Unicode and redirection safe!
|
|
|
|
*
|
2007-05-05 11:32:25 +00:00
|
|
|
* 25-Feb-1999 (Eric Kohl)
|
2006-02-16 23:23:37 +00:00
|
|
|
* Fixed little bug.
|
|
|
|
*
|
2013-06-30 13:23:30 +00:00
|
|
|
* 30-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
|
2013-06-29 23:50:13 +00:00
|
|
|
* Remove all hardcoded strings in En.rc
|
2006-02-16 23:23:37 +00:00
|
|
|
*/
|
|
|
|
|
2013-01-24 23:00:42 +00:00
|
|
|
#include "precomp.h"
|
2006-02-16 23:23:37 +00:00
|
|
|
|
|
|
|
#ifdef INCLUDE_CMD_SET
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Initial size of environment variable buffer */
|
2006-02-16 23:23:37 +00:00
|
|
|
#define ENV_BUFFER_SIZE 1024
|
|
|
|
|
|
|
|
static BOOL
|
2020-07-26 18:32:30 +00:00
|
|
|
seta_eval(LPCTSTR expr);
|
2006-02-16 23:23:37 +00:00
|
|
|
|
|
|
|
static LPCTSTR
|
2020-07-26 18:32:30 +00:00
|
|
|
skip_ws(LPCTSTR p)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
while (*p && *p <= _T(' '))
|
2020-07-26 18:32:30 +00:00
|
|
|
++p;
|
2013-06-29 23:50:13 +00:00
|
|
|
return p;
|
2008-08-25 23:48:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Used to check for and handle:
|
|
|
|
* SET "var=value", SET /P "var=prompt", and SET /P var="prompt" */
|
|
|
|
static LPTSTR
|
|
|
|
GetQuotedString(TCHAR *p)
|
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
TCHAR *end;
|
|
|
|
if (*p == _T('"'))
|
|
|
|
{
|
|
|
|
p = (LPTSTR)skip_ws(p + 1);
|
|
|
|
/* If a matching quote is found, truncate the string */
|
|
|
|
end = _tcsrchr(p, _T('"'));
|
|
|
|
if (end)
|
|
|
|
*end = _T('\0');
|
|
|
|
}
|
|
|
|
return p;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
INT cmd_set(LPTSTR param)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
INT retval = 0;
|
2013-06-29 23:50:13 +00:00
|
|
|
LPTSTR p;
|
|
|
|
LPTSTR lpEnv;
|
|
|
|
LPTSTR lpOutput;
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
if (!_tcsncmp(param, _T("/?"), 2))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
ConOutResPaging(TRUE,STRING_SET_HELP);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
param = (LPTSTR)skip_ws(param);
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* If no parameters, show the environment */
|
2013-06-29 23:50:13 +00:00
|
|
|
if (param[0] == _T('\0'))
|
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
lpEnv = (LPTSTR)GetEnvironmentStrings();
|
2013-06-29 23:50:13 +00:00
|
|
|
if (lpEnv)
|
|
|
|
{
|
|
|
|
lpOutput = lpEnv;
|
|
|
|
while (*lpOutput)
|
|
|
|
{
|
2020-06-08 22:35:18 +00:00
|
|
|
/* Do not display the special '=X:' environment variables */
|
2013-06-29 23:50:13 +00:00
|
|
|
if (*lpOutput != _T('='))
|
2020-06-08 22:35:18 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
ConOutPuts(lpOutput);
|
2020-06-08 22:35:18 +00:00
|
|
|
ConOutChar(_T('\n'));
|
|
|
|
}
|
2013-06-29 23:50:13 +00:00
|
|
|
lpOutput += _tcslen(lpOutput) + 1;
|
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
FreeEnvironmentStrings(lpEnv);
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
retval = 0;
|
|
|
|
goto Quit;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* The /A does *NOT* have to be followed by a whitespace */
|
|
|
|
if (!_tcsnicmp(param, _T("/A"), 2))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
BOOL Success;
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
|
|
|
|
/* Save error level since seta_eval() modifies it, as
|
|
|
|
* we need to set it later according to specific rules. */
|
|
|
|
INT nOldErrorLevel = nErrorLevel;
|
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
StripQuotes(param);
|
2020-07-26 18:32:30 +00:00
|
|
|
Success = seta_eval(skip_ws(param + 2));
|
2013-06-30 16:10:54 +00:00
|
|
|
if (!Success)
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
#if 0
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Might seem random but this is what windows xp does -- This is a message ID */
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
retval = 9165;
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
#endif
|
|
|
|
retval = nErrorLevel;
|
|
|
|
nErrorLevel = nOldErrorLevel;
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
retval = 0;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
goto Quit;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!_tcsnicmp(param, _T("/P"), 2))
|
|
|
|
{
|
|
|
|
TCHAR value[1023];
|
|
|
|
param = GetQuotedString((LPTSTR)skip_ws(param + 2));
|
|
|
|
p = _tcschr(param, _T('='));
|
|
|
|
if (!p)
|
|
|
|
{
|
|
|
|
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
retval = 1;
|
|
|
|
goto Quit;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*p++ = _T('\0');
|
|
|
|
ConOutPrintf(_T("%s"), GetQuotedString(p));
|
2020-07-26 18:32:30 +00:00
|
|
|
ConInString(value, ARRAYSIZE(value));
|
2013-06-29 23:50:13 +00:00
|
|
|
|
|
|
|
if (!*value || !SetEnvironmentVariable(param, value))
|
|
|
|
{
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
retval = 1;
|
|
|
|
goto Quit;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
retval = 0;
|
|
|
|
goto Quit;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
param = GetQuotedString(param);
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
p = _tcschr(param, _T('='));
|
2013-06-29 23:50:13 +00:00
|
|
|
if (p)
|
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Set or remove the environment variable */
|
2013-06-29 23:50:13 +00:00
|
|
|
if (p == param)
|
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Handle set =val case */
|
2013-06-29 23:50:13 +00:00
|
|
|
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
retval = 1;
|
|
|
|
goto Quit;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*p++ = _T('\0');
|
2024-07-08 19:25:30 +00:00
|
|
|
|
|
|
|
#ifdef FEATURE_DYNAMIC_TRACE
|
|
|
|
/* Check for dynamic TRACE ON/OFF */
|
|
|
|
if (!_tcsicmp(param, _T("CMDTRACE")))
|
|
|
|
g_bDynamicTrace = !_tcsicmp(p, _T("ON"));
|
|
|
|
#endif
|
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
if (!SetEnvironmentVariable(param, *p ? p : NULL))
|
|
|
|
{
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
retval = 1;
|
|
|
|
goto Quit;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Display all the environment variables with the given prefix */
|
[CMD] SET: Fix displaying the environment variables with a given prefix.
- Restore any truncated space in the name prefix, before displaying
any error message.
- When trimming the name prefix from "special" characters (spaces, comma
and semicolon), so that e.g. "set ,; ,;FOO" displays all the variables
starting by "FOO", save also a pointer to the original name prefix, that
we will use for variables lookup as well.
This is done, because the SET command allows setting an environment variable
whose name actually contains these characters (e.g. "set ,; ,;FOO=42"),
however, by trimming the characters, doing "set ,; ,;FOO" would not allow
seeing such variables.
With the fix, it is now possible to show them.
2020-07-12 15:03:45 +00:00
|
|
|
LPTSTR pOrgParam = param;
|
|
|
|
BOOLEAN bFound = FALSE;
|
|
|
|
BOOLEAN bRestoreSpace;
|
2013-06-29 23:50:13 +00:00
|
|
|
|
[CMD] SET: Fix displaying the environment variables with a given prefix.
- Restore any truncated space in the name prefix, before displaying
any error message.
- When trimming the name prefix from "special" characters (spaces, comma
and semicolon), so that e.g. "set ,; ,;FOO" displays all the variables
starting by "FOO", save also a pointer to the original name prefix, that
we will use for variables lookup as well.
This is done, because the SET command allows setting an environment variable
whose name actually contains these characters (e.g. "set ,; ,;FOO=42"),
however, by trimming the characters, doing "set ,; ,;FOO" would not allow
seeing such variables.
With the fix, it is now possible to show them.
2020-07-12 15:03:45 +00:00
|
|
|
/*
|
|
|
|
* Trim the prefix from "special" characters (only when displaying the
|
|
|
|
* environment variables), so that e.g. "SET ,; ,;FOO" will display all
|
|
|
|
* the variables starting by "FOO".
|
|
|
|
* The SET command allows as well to set an environment variable whose name
|
|
|
|
* actually contains these characters (e.g. "SET ,; ,;FOO=42"); however,
|
|
|
|
* by trimming the characters, doing "SET ,; ,;FOO" would not allow seeing
|
|
|
|
* such variables.
|
|
|
|
* Thus, we also save a pointer to the original variable name prefix, that
|
|
|
|
* we will look it up as well below.
|
|
|
|
*/
|
2013-06-29 23:50:13 +00:00
|
|
|
while (_istspace(*param) || *param == _T(',') || *param == _T(';'))
|
[CMD] SET: Fix displaying the environment variables with a given prefix.
- Restore any truncated space in the name prefix, before displaying
any error message.
- When trimming the name prefix from "special" characters (spaces, comma
and semicolon), so that e.g. "set ,; ,;FOO" displays all the variables
starting by "FOO", save also a pointer to the original name prefix, that
we will use for variables lookup as well.
This is done, because the SET command allows setting an environment variable
whose name actually contains these characters (e.g. "set ,; ,;FOO=42"),
however, by trimming the characters, doing "set ,; ,;FOO" would not allow
seeing such variables.
With the fix, it is now possible to show them.
2020-07-12 15:03:45 +00:00
|
|
|
++param;
|
2013-06-29 23:50:13 +00:00
|
|
|
|
[CMD] SET: Fix displaying the environment variables with a given prefix.
- Restore any truncated space in the name prefix, before displaying
any error message.
- When trimming the name prefix from "special" characters (spaces, comma
and semicolon), so that e.g. "set ,; ,;FOO" displays all the variables
starting by "FOO", save also a pointer to the original name prefix, that
we will use for variables lookup as well.
This is done, because the SET command allows setting an environment variable
whose name actually contains these characters (e.g. "set ,; ,;FOO=42"),
however, by trimming the characters, doing "set ,; ,;FOO" would not allow
seeing such variables.
With the fix, it is now possible to show them.
2020-07-12 15:03:45 +00:00
|
|
|
/* Just remove the very last space, if present */
|
2013-06-29 23:50:13 +00:00
|
|
|
p = _tcsrchr(param, _T(' '));
|
[CMD] SET: Fix displaying the environment variables with a given prefix.
- Restore any truncated space in the name prefix, before displaying
any error message.
- When trimming the name prefix from "special" characters (spaces, comma
and semicolon), so that e.g. "set ,; ,;FOO" displays all the variables
starting by "FOO", save also a pointer to the original name prefix, that
we will use for variables lookup as well.
This is done, because the SET command allows setting an environment variable
whose name actually contains these characters (e.g. "set ,; ,;FOO=42"),
however, by trimming the characters, doing "set ,; ,;FOO" would not allow
seeing such variables.
With the fix, it is now possible to show them.
2020-07-12 15:03:45 +00:00
|
|
|
bRestoreSpace = (p != NULL);
|
2013-06-29 23:50:13 +00:00
|
|
|
if (!p)
|
|
|
|
p = param + _tcslen(param);
|
|
|
|
*p = _T('\0');
|
|
|
|
|
|
|
|
lpEnv = GetEnvironmentStrings();
|
|
|
|
if (lpEnv)
|
|
|
|
{
|
|
|
|
lpOutput = lpEnv;
|
|
|
|
while (*lpOutput)
|
|
|
|
{
|
[CMD] SET: Fix displaying the environment variables with a given prefix.
- Restore any truncated space in the name prefix, before displaying
any error message.
- When trimming the name prefix from "special" characters (spaces, comma
and semicolon), so that e.g. "set ,; ,;FOO" displays all the variables
starting by "FOO", save also a pointer to the original name prefix, that
we will use for variables lookup as well.
This is done, because the SET command allows setting an environment variable
whose name actually contains these characters (e.g. "set ,; ,;FOO=42"),
however, by trimming the characters, doing "set ,; ,;FOO" would not allow
seeing such variables.
With the fix, it is now possible to show them.
2020-07-12 15:03:45 +00:00
|
|
|
/* Look up for both the original and truncated variable name prefix */
|
|
|
|
if (!_tcsnicmp(lpOutput, pOrgParam, p - pOrgParam) ||
|
|
|
|
!_tcsnicmp(lpOutput, param, p - param))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
ConOutPuts(lpOutput);
|
2013-07-02 23:07:15 +00:00
|
|
|
ConOutChar(_T('\n'));
|
2013-06-29 23:50:13 +00:00
|
|
|
bFound = TRUE;
|
|
|
|
}
|
|
|
|
lpOutput += _tcslen(lpOutput) + 1;
|
|
|
|
}
|
|
|
|
FreeEnvironmentStrings(lpEnv);
|
|
|
|
}
|
|
|
|
|
[CMD] SET: Fix displaying the environment variables with a given prefix.
- Restore any truncated space in the name prefix, before displaying
any error message.
- When trimming the name prefix from "special" characters (spaces, comma
and semicolon), so that e.g. "set ,; ,;FOO" displays all the variables
starting by "FOO", save also a pointer to the original name prefix, that
we will use for variables lookup as well.
This is done, because the SET command allows setting an environment variable
whose name actually contains these characters (e.g. "set ,; ,;FOO=42"),
however, by trimming the characters, doing "set ,; ,;FOO" would not allow
seeing such variables.
With the fix, it is now possible to show them.
2020-07-12 15:03:45 +00:00
|
|
|
/* Restore the truncated space for correctly
|
|
|
|
* displaying the error message, if any. */
|
|
|
|
if (bRestoreSpace)
|
|
|
|
*p = _T(' ');
|
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
if (!bFound)
|
|
|
|
{
|
2020-07-05 21:39:06 +00:00
|
|
|
ConErrResPrintf(STRING_SET_ENV_ERROR, param);
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
retval = 1;
|
|
|
|
goto Quit;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[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.admin/XHeUq8oe2wk/LIEViGNmkK0J
(comment by Mark Zbikowski).
2020-07-01 00:15:52 +00:00
|
|
|
Quit:
|
|
|
|
if (BatType != CMD_TYPE)
|
|
|
|
{
|
|
|
|
if (retval != 0)
|
|
|
|
nErrorLevel = retval;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nErrorLevel = retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static INT
|
2013-06-29 23:50:13 +00:00
|
|
|
ident_len(LPCTSTR p)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
LPCTSTR p2 = p;
|
2020-07-26 18:32:30 +00:00
|
|
|
if (__iscsymf(*p))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
++p2;
|
2020-07-26 18:32:30 +00:00
|
|
|
while (__iscsym(*p2))
|
2013-06-29 23:50:13 +00:00
|
|
|
++p2;
|
|
|
|
}
|
|
|
|
return (INT)(p2-p);
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
#define PARSE_IDENT(ident, identlen, p) \
|
|
|
|
do { \
|
2013-06-30 12:27:18 +00:00
|
|
|
identlen = ident_len(p); \
|
2020-07-26 18:32:30 +00:00
|
|
|
ident = (LPTSTR)alloca((identlen + 1) * sizeof(TCHAR)); \
|
|
|
|
memmove(ident, p, identlen * sizeof(TCHAR)); \
|
2013-06-30 12:27:18 +00:00
|
|
|
ident[identlen] = 0; \
|
2020-07-26 18:32:30 +00:00
|
|
|
p += identlen; \
|
|
|
|
} while (0)
|
2006-02-16 23:23:37 +00:00
|
|
|
|
2015-04-05 16:28:10 +00:00
|
|
|
static INT
|
|
|
|
seta_identval(LPCTSTR ident)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
LPCTSTR identVal = GetEnvVarOrSpecial(ident);
|
|
|
|
if (!identVal)
|
2015-04-05 16:28:10 +00:00
|
|
|
return 0;
|
|
|
|
else
|
2020-07-26 18:32:30 +00:00
|
|
|
return _tcstol(identVal, NULL, 0);
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
calc(INT* lval, TCHAR op, INT rval)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
switch (op)
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
case '*':
|
|
|
|
*lval *= rval;
|
|
|
|
break;
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
case '/':
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
{
|
|
|
|
if (rval == 0)
|
|
|
|
{
|
2024-07-11 00:12:12 +00:00
|
|
|
ConErrResPuts(STRING_ERROR_DIVISION_BY_ZERO);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
nErrorLevel = 0x400023D1; // 1073750993;
|
|
|
|
return FALSE;
|
|
|
|
}
|
2013-06-29 23:50:13 +00:00
|
|
|
*lval /= rval;
|
|
|
|
break;
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
case '%':
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
{
|
|
|
|
if (rval == 0)
|
|
|
|
{
|
2024-07-11 00:12:12 +00:00
|
|
|
ConErrResPuts(STRING_ERROR_DIVISION_BY_ZERO);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
nErrorLevel = 0x400023D1; // 1073750993;
|
|
|
|
return FALSE;
|
|
|
|
}
|
2013-06-29 23:50:13 +00:00
|
|
|
*lval %= rval;
|
|
|
|
break;
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
}
|
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
case '+':
|
|
|
|
*lval += rval;
|
|
|
|
break;
|
|
|
|
case '-':
|
|
|
|
*lval -= rval;
|
|
|
|
break;
|
|
|
|
case '&':
|
|
|
|
*lval &= rval;
|
|
|
|
break;
|
|
|
|
case '^':
|
|
|
|
*lval ^= rval;
|
|
|
|
break;
|
|
|
|
case '|':
|
|
|
|
*lval |= rval;
|
|
|
|
break;
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
default:
|
2020-07-26 18:32:30 +00:00
|
|
|
ConErrResPuts(STRING_INVALID_OPERAND);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
nErrorLevel = 0x400023CE; // 1073750990;
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2020-07-26 18:32:30 +00:00
|
|
|
seta_stmt(LPCTSTR* p_, INT* result);
|
2006-02-16 23:23:37 +00:00
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_unaryTerm(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
LPCTSTR p = *p_;
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
INT rval;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
if (*p == _T('('))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
p = skip_ws(p + 1);
|
|
|
|
if (!seta_stmt(&p, &rval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
2020-07-26 18:32:30 +00:00
|
|
|
if (*p++ != _T(')'))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
ConErrResPuts(STRING_EXPECTED_CLOSE_PAREN);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
nErrorLevel = 0x400023CC; // 1073750988;
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
*result = rval;
|
|
|
|
}
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
else if (_istdigit(*p))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
errno = 0;
|
|
|
|
rval = _tcstol(p, (LPTSTR*)&p, 0);
|
|
|
|
|
|
|
|
/* Check for overflow / underflow */
|
|
|
|
if (errno == ERANGE)
|
|
|
|
{
|
2024-07-11 00:12:12 +00:00
|
|
|
ConErrResPuts(STRING_ERROR_INVALID_NUMBER2);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
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))
|
|
|
|
{
|
2024-07-11 00:12:12 +00:00
|
|
|
ConErrResPuts(STRING_ERROR_INVALID_NUMBER1);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
nErrorLevel = 0x400023CF; // 1073750991;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
*result = rval;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
else if (__iscsymf(*p))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
LPTSTR ident;
|
|
|
|
INT identlen;
|
2020-07-26 18:32:30 +00:00
|
|
|
PARSE_IDENT(ident, identlen, p);
|
|
|
|
*result = seta_identval(ident);
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
ConErrResPuts(STRING_EXPECTED_NUMBER_OR_VARIABLE);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
nErrorLevel = 0x400023CD; // 1073750989;
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
*p_ = skip_ws(p);
|
2013-06-29 23:50:13 +00:00
|
|
|
return TRUE;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_mulTerm(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
LPCTSTR p = *p_;
|
|
|
|
TCHAR op = 0;
|
|
|
|
INT rval;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
if (_tcschr(_T("!~-+"), *p))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
op = *p;
|
2020-07-26 18:32:30 +00:00
|
|
|
p = skip_ws(p + 1);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
else
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
if (!seta_unaryTerm(&p, &rval))
|
|
|
|
return FALSE;
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
*result = rval;
|
|
|
|
*p_ = p;
|
|
|
|
return TRUE;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_ltorTerm(LPCTSTR* p_, INT* result, LPCTSTR ops, BOOL (*subTerm)(LPCTSTR*,INT*))
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
LPCTSTR p = *p_;
|
|
|
|
INT lval;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
/* Evaluate the left-hand side */
|
|
|
|
if (!subTerm(&p, &lval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
while (*p && _tcschr(ops, *p))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
INT rval;
|
|
|
|
TCHAR op = *p;
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
p = skip_ws(p + 1);
|
2013-06-29 23:50:13 +00:00
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Evaluate the immediate right-hand side */
|
|
|
|
if (!subTerm(&p, &rval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* This becomes the new left-hand side for the next iteration */
|
|
|
|
if (!calc(&lval, op, rval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*result = lval;
|
|
|
|
*p_ = p;
|
|
|
|
return TRUE;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_addTerm(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
return seta_ltorTerm(p_, result, _T("*/%"), seta_mulTerm);
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_logShiftTerm(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
return seta_ltorTerm(p_, result, _T("+-"), seta_addTerm);
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_bitAndTerm(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
LPCTSTR p = *p_;
|
|
|
|
INT lval;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
/* Evaluate the left-hand side */
|
|
|
|
if (!seta_logShiftTerm(&p, &lval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
/* Handle << >> operators */
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
while (*p && _tcschr(_T("<>"), *p))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
INT rval;
|
|
|
|
TCHAR op = *p;
|
|
|
|
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
/* 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);
|
2013-06-29 23:50:13 +00:00
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Evaluate the immediate right-hand side */
|
|
|
|
if (!seta_logShiftTerm(&p, &rval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* This becomes the new left-hand side for the next iteration */
|
|
|
|
switch (op)
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
case '<':
|
2015-04-05 16:28:10 +00:00
|
|
|
{
|
|
|
|
/* Shift left has to be a positive number, 0-31 otherwise 0 is returned,
|
|
|
|
* which differs from the compiler (for example gcc) so being explicit. */
|
|
|
|
if (rval < 0 || rval >= (8 * sizeof(lval)))
|
|
|
|
lval = 0;
|
|
|
|
else
|
|
|
|
lval <<= rval;
|
2013-06-29 23:50:13 +00:00
|
|
|
break;
|
2015-04-05 16:28:10 +00:00
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
case '>':
|
|
|
|
lval >>= rval;
|
|
|
|
break;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
default:
|
2020-07-26 18:32:30 +00:00
|
|
|
ConErrResPuts(STRING_INVALID_OPERAND);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
nErrorLevel = 0x400023CE; // 1073750990;
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*result = lval;
|
|
|
|
*p_ = p;
|
|
|
|
return TRUE;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_bitExclOrTerm(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
return seta_ltorTerm(p_, result, _T("&"), seta_bitAndTerm);
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_bitOrTerm(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
return seta_ltorTerm(p_, result, _T("^"), seta_bitExclOrTerm);
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_expr(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
return seta_ltorTerm(p_, result, _T("|"), seta_bitOrTerm);
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_assignment(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
LPCTSTR p = *p_;
|
|
|
|
LPTSTR ident;
|
|
|
|
TCHAR op = 0;
|
|
|
|
INT identlen, exprval;
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
PARSE_IDENT(ident, identlen, p);
|
|
|
|
if (identlen)
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
p = skip_ws(p);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Handle = assignment */
|
|
|
|
if (*p == _T('='))
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
{
|
|
|
|
op = *p;
|
|
|
|
p = skip_ws(p + 1);
|
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Handle *= /= %= += -= &= ^= |= assignments */
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
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);
|
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Handle <<= >>= assignments */
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
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);
|
|
|
|
}
|
2013-06-29 23:50:13 +00:00
|
|
|
}
|
|
|
|
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
evaluate:
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Allow to chain multiple assignments, such as: a=b=1 */
|
|
|
|
if (ident && op)
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
|
|
|
INT identval;
|
|
|
|
LPTSTR buf;
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
if (!seta_assignment(&p, &exprval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
identval = seta_identval(ident);
|
2015-04-05 16:28:10 +00:00
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
switch (op)
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Handle = assignment */
|
2013-06-29 23:50:13 +00:00
|
|
|
case '=':
|
|
|
|
identval = exprval;
|
|
|
|
break;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
/* Handle <<= assignment */
|
2013-06-29 23:50:13 +00:00
|
|
|
case '<':
|
2015-04-05 16:28:10 +00:00
|
|
|
{
|
|
|
|
/* Shift left has to be a positive number, 0-31 otherwise 0 is returned,
|
|
|
|
* which differs from the compiler (for example gcc) so being explicit. */
|
|
|
|
if (exprval < 0 || exprval >= (8 * sizeof(identval)))
|
|
|
|
identval = 0;
|
|
|
|
else
|
|
|
|
identval <<= exprval;
|
2013-06-29 23:50:13 +00:00
|
|
|
break;
|
2015-04-05 16:28:10 +00:00
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
/* Handle >>= assignment */
|
2013-06-29 23:50:13 +00:00
|
|
|
case '>':
|
|
|
|
identval >>= exprval;
|
|
|
|
break;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
/* Other assignments */
|
2013-06-29 23:50:13 +00:00
|
|
|
default:
|
2020-07-26 18:32:30 +00:00
|
|
|
if (!calc(&identval, op, exprval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
buf = (LPTSTR)alloca(32 * sizeof(TCHAR));
|
|
|
|
_sntprintf(buf, 32, _T("%i"), identval);
|
|
|
|
SetEnvironmentVariable(ident, buf); // TODO FIXME - check return value
|
2013-06-29 23:50:13 +00:00
|
|
|
exprval = identval;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Restore p in case we found an identifier but not an operator */
|
2013-06-29 23:50:13 +00:00
|
|
|
p = *p_;
|
2020-07-26 18:32:30 +00:00
|
|
|
if (!seta_expr(&p, &exprval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*result = exprval;
|
|
|
|
*p_ = p;
|
|
|
|
return TRUE;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_stmt(LPCTSTR* p_, INT* result)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
LPCTSTR p = *p_;
|
|
|
|
INT rval;
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
if (!seta_assignment(&p, &rval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
/* Loop over each statement */
|
|
|
|
while (*p == _T(','))
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
p = skip_ws(p + 1);
|
2013-06-29 23:50:13 +00:00
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
if (!seta_assignment(&p, &rval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*result = rval;
|
|
|
|
*p_ = p;
|
|
|
|
return TRUE;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
2013-06-29 23:50:13 +00:00
|
|
|
seta_eval(LPCTSTR p)
|
2006-02-16 23:23:37 +00:00
|
|
|
{
|
2013-06-29 23:50:13 +00:00
|
|
|
INT rval;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
|
|
|
if (!*p)
|
2013-06-29 23:50:13 +00:00
|
|
|
{
|
2020-07-26 18:32:30 +00:00
|
|
|
ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
nErrorLevel = 1;
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2020-07-26 18:32:30 +00:00
|
|
|
if (!seta_stmt(&p, &rval))
|
2013-06-29 23:50:13 +00:00
|
|
|
return FALSE;
|
2020-07-26 18:32:30 +00:00
|
|
|
|
[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.
2020-07-19 19:30:50 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2020-07-26 18:32:30 +00:00
|
|
|
/* Echo the result of the evaluation only in interactive (non-batch) mode */
|
|
|
|
if (!bc)
|
|
|
|
ConOutPrintf(_T("%i"), rval);
|
|
|
|
|
2013-06-29 23:50:13 +00:00
|
|
|
return TRUE;
|
2006-02-16 23:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|