CORE-13682
- Split SubstituteVars() into its main loop and a helper SubstituteVar()
that just substitutes only one variable.
- Use this new helper as the basis of the proper implementation of the
delayed expansion of variables.
- Fix a bug introduced in commit 495c82cc, when GetBatchVar() fails.
CORE-11857 CORE-13736
It will be followed with a separate fix for the FOR-loop code.
Fixes some cmd_winetests.
A NULL pointer can be returned for a valid existing batch/FOR variable,
in which case the enhanced-variable getter should return an empty string.
This situation can happen e.g. when forcing a FOR-loop to tokenize a
text line with not enough tokens in it.
They are currently specified for documentation purposes (i.e. what
Windows 8+ CMD.EXE can report) but not used yet, since ReactOS does not
support them.
- Display the names of the files being TYPEd only if more than one file
has been specified on the command-line, or if a file specification
(with wildcards) is present (even just for one).
These names are displayed on STDERR while the files are TYPEd on
STDOUT, therefore allowing concatenating files by just redirecting
STDOUT to a destination, without corrupting it with the displayed file
names. Also, add a /N option to force not displaying these file names.
- When file specifications (with wildcards) are being processed, silently
ignore any directories matching them. If no corresponding files have
been found, display a file-not-found error.
- When explicitly directory names are specified, don't do any special
treatment; the CreateFile() call will fail and return the appropriate
error.
- Fix the returned errorlevel values.
See https://ss64.com/nt/type.html for more information.
Fixes some cmd_winetests.
- When reading from a file, retrieve its original size so that
we can stop reading it once we are beyond its original ending.
This allows avoiding an infinite read loop in case the output of
the file is redirected back to it.
Fixes CORE-17208
- Move the FileGetString() helper to the only file where it is
actually used.
- 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.
That's an actual fact, done on original MS-DOS COMMAND.COM, FreeCOM,
Windows' CMD.EXE, etc., but is strangely undocumented on MSDN documentation.
See https://www.dostips.com/forum/viewtopic.php?t=4436
Fixes some cmd_winetests.
This functionality is: case insensitivity comparisons (/I);
CMDEXTVERSION and DEFINED unary operators; EQU, NEQ, LSS, LEQ, GTR, GEQ
generic string comparators.
- First, the option and the APIs called by it can work directly on
paths relative to the current directory. So there is no need to
call GetFullPathName(), with the risk of going over MAX_PATH if the
current path is quite long (or nested) but the RMDIR is called on a
(short-length) relative sub-directory.
- Append a path-separator (backslash), only if the specified directory
does not have one already, and, that it does not specify a current
directory via the "drive-root" method, e.g. "C:" without any trailing
backslash.
- In case there are errors during deletion of sub-directories or
sub-files, print the error but continue deleting the other sub-dirs
or files.
- Monitor the Ctrl-C breaker as well, and stop deleting if it has been
triggered.
- When removing file/directory read-only attribute, just remove this
attribute, but keep the other ones.
- When deleting the directory, first try to do it directly; if it fails
with access denied, check whether it was read-only, and if so, remove
this attribute and retry deletion, otherwise fails.
- When recursively deleting a drive root directory, ultimately resolve
the dir pattern and check whether it's indeed a drive root, e.g.
"C:\\", and if so, just return success. Indeed, calling
RemoveDirectory() on such drive roots will return ERROR_ACCESS_DENIED
otherwise, but we want to succeed even if, of course, we won't
actually "delete" the drive root.
Use kernel32!lstrcmp(i) instead of CRT!_tcs(i)cmp, so as to use the correct
current thread locale information when comparing user-specific strings.
As a result, the following comparison: 'b LSS B' will return TRUE,
instead of FALSE as it would be by using the CRT functions (and by
naively considering the lexicographical order in ANSI).
This behaviour has been introduced in Windows 2000 onwards.
For MKDIR, also properly support the case of ERROR_FILE_EXISTS and
ERROR_ALREADY_EXISTS last-errors by displaying the standard error
"A subdirectory or file XXX already exists.\n"
CORE-10495 CORE-13672
- Fix how the ERRORLEVEL and the last returned exit code are set by
EXIT and CALL commands, when batch contexts terminate, and when CMD
runs in single-command mode (with /C).
Addendum to commit 26ff2c8e, and reverts commit 7bd33ac4.
See also commit 8cf11060 (r40474).
More information can be found at:
https://ss64.com/nt/exit.htmlhttps://stackoverflow.com/a/34987886/13530036https://stackoverflow.com/a/34937706/13530036
- Move the actual execution of the CMD command-line (in /C or /K
single-command mode) from Initialize() to _tmain(), to put it on par
with the ProcessInput() interactive mode.
- Make ProcessInput() also return the last command's exit code.
We note two things, when CMD searches for the corresponding label in the
batch file:
- the first character of the line is always ignored, unless it's a colon;
- the escape caret ^ is supported and interpreted.
Fixes some cmd_winetests.
- The ':EOF' label feature is available only when extensions are enabled.
- Anything that follows the ':EOF' label, separated by at least one
whitespace character, is ignored, and the batch file terminates.
- To this purpose use the ParseErrorEx() that correctly sets the
bParseError flag, and return the partially-parsed command so that
it gets echoed as well for diagnostics purposes (Windows-compatible).
- Any other parameters specified after (or before) the '/?' switch for
the FOR and IF commands, are considered fatal syntax errors as well,
thus we employ the ParseErrorEx() as well.