mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 18:23:27 +08:00
[CMD] Make the command echoer Windows-CMD-compatible. CORE-14025
Add a MSCMD_ECHO_COMMAND_COMPAT define to be able to switch back to our older but less broken behaviour at compile-time. - Append a trailing space to commands when those have a parameter, as well as after a command-block closing parenthesis. - Space around redirection strings need to be switched around.
This commit is contained in:
parent
47ea3f1faa
commit
26cfadc352
@ -4,6 +4,9 @@
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/* Enable this define for "buggy" Windows' CMD command echoer compatibility */
|
||||
#define MSCMD_ECHO_COMMAND_COMPAT
|
||||
|
||||
/*
|
||||
* Parser debugging support. These flags are global so that their values can be
|
||||
* modified at runtime from a debugger. They correspond to the public Windows'
|
||||
@ -1127,48 +1130,85 @@ EchoCommand(PARSED_COMMAND *Cmd)
|
||||
switch (Cmd->Type)
|
||||
{
|
||||
case C_COMMAND:
|
||||
{
|
||||
if (SubstituteForVars(Cmd->Command.First, Buf))
|
||||
ConOutPrintf(_T("%s"), Buf);
|
||||
if (SubstituteForVars(Cmd->Command.Rest, Buf))
|
||||
{
|
||||
ConOutPrintf(_T("%s"), Buf);
|
||||
#ifdef MSCMD_ECHO_COMMAND_COMPAT
|
||||
/* NOTE: For Windows compatibility, add a trailing space after printing the command parameter, if present */
|
||||
if (*Buf) ConOutChar(_T(' '));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case C_QUIET:
|
||||
return;
|
||||
|
||||
case C_BLOCK:
|
||||
{
|
||||
BOOLEAN bIsFirstCmdCRLF;
|
||||
|
||||
ConOutChar(_T('('));
|
||||
|
||||
Sub = Cmd->Subcommands;
|
||||
if (Sub && !Sub->Next)
|
||||
{
|
||||
/* Single-command block: display all on one line */
|
||||
EchoCommand(Sub);
|
||||
}
|
||||
else if (Sub)
|
||||
{
|
||||
/* Multi-command block: display parenthesis on separate lines */
|
||||
|
||||
bIsFirstCmdCRLF = (Sub && Sub->Next);
|
||||
|
||||
#if defined(MSCMD_ECHO_COMMAND_COMPAT) && defined(MSCMD_PARSER_BUGS)
|
||||
/*
|
||||
* We will emulate Windows' CMD handling of "CRLF" and "&" multi-command
|
||||
* enumeration within parenthesized command blocks.
|
||||
*/
|
||||
bIsFirstCmdCRLF = bIsFirstCmdCRLF && (Sub->Type != C_MULTI);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Single-command block: display all on one line.
|
||||
* Multi-command block: display commands on separate lines.
|
||||
*/
|
||||
if (bIsFirstCmdCRLF)
|
||||
ConOutChar(_T('\n'));
|
||||
do
|
||||
{
|
||||
EchoCommand(Sub);
|
||||
|
||||
for (; Sub; Sub = Sub->Next)
|
||||
{
|
||||
EchoCommand(Sub);
|
||||
if (Sub->Next)
|
||||
#ifdef MSCMD_ECHO_COMMAND_COMPAT
|
||||
ConOutPuts(_T(" \n "));
|
||||
#else
|
||||
ConOutChar(_T('\n'));
|
||||
Sub = Sub->Next;
|
||||
} while (Sub);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bIsFirstCmdCRLF)
|
||||
ConOutChar(_T('\n'));
|
||||
|
||||
#ifdef MSCMD_ECHO_COMMAND_COMPAT
|
||||
/* NOTE: For Windows compatibility, add a trailing space after printing the closing parenthesis */
|
||||
ConOutPuts(_T(") "));
|
||||
#else
|
||||
ConOutChar(_T(')'));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case C_MULTI:
|
||||
case C_OR:
|
||||
case C_AND:
|
||||
case C_PIPE:
|
||||
{
|
||||
Sub = Cmd->Subcommands;
|
||||
EchoCommand(Sub);
|
||||
ConOutPrintf(_T(" %s "), OpString[Cmd->Type - C_OP_LOWEST]);
|
||||
EchoCommand(Sub->Next);
|
||||
break;
|
||||
}
|
||||
|
||||
case C_IF:
|
||||
{
|
||||
ConOutPuts(_T("if"));
|
||||
if (Cmd->If.Flags & IFFLAG_IGNORECASE)
|
||||
ConOutPuts(_T(" /I"));
|
||||
@ -1187,8 +1227,10 @@ EchoCommand(PARSED_COMMAND *Cmd)
|
||||
EchoCommand(Sub->Next);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case C_FOR:
|
||||
{
|
||||
ConOutPuts(_T("for"));
|
||||
if (Cmd->For.Switches & FOR_DIRS) ConOutPuts(_T(" /D"));
|
||||
if (Cmd->For.Switches & FOR_F) ConOutPuts(_T(" /F"));
|
||||
@ -1204,12 +1246,24 @@ EchoCommand(PARSED_COMMAND *Cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
for (Redir = Cmd->Redirections; Redir; Redir = Redir->Next)
|
||||
{
|
||||
if (SubstituteForVars(Redir->Filename, Buf))
|
||||
{
|
||||
ConOutPrintf(_T(" %c%s%s"), _T('0') + Redir->Number,
|
||||
#ifdef MSCMD_ECHO_COMMAND_COMPAT
|
||||
ConOutPrintf(_T("%c%s%s "),
|
||||
_T('0') + Redir->Number,
|
||||
RedirString[Redir->Mode], Buf);
|
||||
#else
|
||||
ConOutPrintf(_T(" %c%s%s"),
|
||||
_T('0') + Redir->Number,
|
||||
RedirString[Redir->Mode], Buf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1325,6 +1379,10 @@ do { \
|
||||
PRINTF(_T(" %%%c in (%s) do "), Cmd->For.Variable, Cmd->For.List);
|
||||
RECURSE(Cmd->Subcommands);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
for (Redir = Cmd->Redirections; Redir; Redir = Redir->Next)
|
||||
@ -1335,6 +1393,11 @@ do { \
|
||||
RedirString[Redir->Mode], Buf);
|
||||
}
|
||||
return Out;
|
||||
|
||||
#undef CHAR
|
||||
#undef STRING
|
||||
#undef PRINTF
|
||||
#undef RECURSE
|
||||
}
|
||||
|
||||
VOID
|
||||
|
Loading…
Reference in New Issue
Block a user