mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 05:45:50 +00:00
Rearrange some code in cmd parser, avoiding excessive stack space usage (Bug 4536)
svn path=/trunk/; revision=41853
This commit is contained in:
parent
8cda4903ab
commit
3c8f7c0167
1 changed files with 61 additions and 69 deletions
|
@ -528,78 +528,14 @@ static PARSED_COMMAND *ParseRem(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PARSED_COMMAND *ParseCommandPart(void)
|
static DECLSPEC_NOINLINE PARSED_COMMAND *ParseCommandPart(REDIRECTION *RedirList)
|
||||||
{
|
{
|
||||||
TCHAR ParsedLine[CMDLINE_LENGTH];
|
TCHAR ParsedLine[CMDLINE_LENGTH];
|
||||||
TCHAR *Pos;
|
|
||||||
DWORD TailOffset;
|
|
||||||
PARSED_COMMAND *Cmd;
|
PARSED_COMMAND *Cmd;
|
||||||
PARSED_COMMAND *(*Func)(void);
|
PARSED_COMMAND *(*Func)(void);
|
||||||
REDIRECTION *RedirList = NULL;
|
|
||||||
int Type;
|
|
||||||
|
|
||||||
while (IsSeparator(CurChar))
|
TCHAR *Pos = _stpcpy(ParsedLine, CurrentToken) + 1;
|
||||||
{
|
DWORD TailOffset = Pos - ParsedLine;
|
||||||
if (CurChar == _T('\n'))
|
|
||||||
return NULL;
|
|
||||||
ParseChar();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CurChar)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (CurChar == _T(':'))
|
|
||||||
{
|
|
||||||
/* "Ignore" the rest of the line.
|
|
||||||
* (Line continuations will still be parsed, though.) */
|
|
||||||
while (ParseToken(0, NULL) != TOK_END)
|
|
||||||
;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurChar == _T('@'))
|
|
||||||
{
|
|
||||||
ParseChar();
|
|
||||||
Cmd = cmd_alloc(sizeof(PARSED_COMMAND));
|
|
||||||
Cmd->Type = C_QUIET;
|
|
||||||
Cmd->Next = NULL;
|
|
||||||
/* @ acts like a unary operator with low precedence,
|
|
||||||
* so call the top-level parser */
|
|
||||||
Cmd->Subcommands = ParseCommandOp(C_OP_LOWEST);
|
|
||||||
Cmd->Redirections = NULL;
|
|
||||||
return Cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the head of the command */
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
Type = ParseToken(_T('('), STANDARD_SEPS);
|
|
||||||
if (Type == TOK_NORMAL)
|
|
||||||
{
|
|
||||||
Pos = _stpcpy(ParsedLine, CurrentToken) + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (Type == TOK_REDIRECTION)
|
|
||||||
{
|
|
||||||
if (!ParseRedirection(&RedirList))
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if (Type == TOK_BEGIN_BLOCK)
|
|
||||||
{
|
|
||||||
return ParseBlock(RedirList);
|
|
||||||
}
|
|
||||||
else if (Type == TOK_END_BLOCK && !RedirList)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ParseError();
|
|
||||||
FreeRedirection(RedirList);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TailOffset = Pos - ParsedLine;
|
|
||||||
|
|
||||||
/* Check for special forms */
|
/* Check for special forms */
|
||||||
if ((Func = ParseFor, _tcsicmp(ParsedLine, _T("for")) == 0) ||
|
if ((Func = ParseFor, _tcsicmp(ParsedLine, _T("for")) == 0) ||
|
||||||
|
@ -624,7 +560,7 @@ static PARSED_COMMAND *ParseCommandPart(void)
|
||||||
/* Now get the tail */
|
/* Now get the tail */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
Type = ParseToken(0, NULL);
|
int Type = ParseToken(0, NULL);
|
||||||
if (Type == TOK_NORMAL)
|
if (Type == TOK_NORMAL)
|
||||||
{
|
{
|
||||||
if (Pos + _tcslen(CurrentToken) >= &ParsedLine[CMDLINE_LENGTH])
|
if (Pos + _tcslen(CurrentToken) >= &ParsedLine[CMDLINE_LENGTH])
|
||||||
|
@ -657,12 +593,68 @@ static PARSED_COMMAND *ParseCommandPart(void)
|
||||||
return Cmd;
|
return Cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PARSED_COMMAND *ParsePrimary(void)
|
||||||
|
{
|
||||||
|
REDIRECTION *RedirList = NULL;
|
||||||
|
int Type;
|
||||||
|
|
||||||
|
while (IsSeparator(CurChar))
|
||||||
|
{
|
||||||
|
if (CurChar == _T('\n'))
|
||||||
|
return NULL;
|
||||||
|
ParseChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CurChar)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (CurChar == _T(':'))
|
||||||
|
{
|
||||||
|
/* "Ignore" the rest of the line.
|
||||||
|
* (Line continuations will still be parsed, though.) */
|
||||||
|
while (ParseToken(0, NULL) != TOK_END)
|
||||||
|
;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CurChar == _T('@'))
|
||||||
|
{
|
||||||
|
ParseChar();
|
||||||
|
PARSED_COMMAND *Cmd = cmd_alloc(sizeof(PARSED_COMMAND));
|
||||||
|
Cmd->Type = C_QUIET;
|
||||||
|
Cmd->Next = NULL;
|
||||||
|
/* @ acts like a unary operator with low precedence,
|
||||||
|
* so call the top-level parser */
|
||||||
|
Cmd->Subcommands = ParseCommandOp(C_OP_LOWEST);
|
||||||
|
Cmd->Redirections = NULL;
|
||||||
|
return Cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process leading redirections and get the head of the command */
|
||||||
|
while ((Type = ParseToken(_T('('), STANDARD_SEPS)) == TOK_REDIRECTION)
|
||||||
|
{
|
||||||
|
if (!ParseRedirection(&RedirList))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type == TOK_NORMAL)
|
||||||
|
return ParseCommandPart(RedirList);
|
||||||
|
else if (Type == TOK_BEGIN_BLOCK)
|
||||||
|
return ParseBlock(RedirList);
|
||||||
|
else if (Type == TOK_END_BLOCK && !RedirList)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ParseError();
|
||||||
|
FreeRedirection(RedirList);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static PARSED_COMMAND *ParseCommandOp(int OpType)
|
static PARSED_COMMAND *ParseCommandOp(int OpType)
|
||||||
{
|
{
|
||||||
PARSED_COMMAND *Cmd, *Left, *Right;
|
PARSED_COMMAND *Cmd, *Left, *Right;
|
||||||
|
|
||||||
if (OpType == C_OP_HIGHEST)
|
if (OpType == C_OP_HIGHEST)
|
||||||
Cmd = ParseCommandPart();
|
Cmd = ParsePrimary();
|
||||||
else
|
else
|
||||||
Cmd = ParseCommandOp(OpType + 1);
|
Cmd = ParseCommandOp(OpType + 1);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue