mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 04:48:36 +00:00
cmd: Move depth count inside builder.
(and temporarly using parenthesis count to store curDepth). Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
parent
fc4b9c645a
commit
2f5456316c
|
@ -2030,85 +2030,6 @@ static WCHAR *find_chr(WCHAR *in, WCHAR *last, const WCHAR *delims)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* WCMD_addCommand
|
|
||||||
*
|
|
||||||
* Adds a command to the current command list
|
|
||||||
*/
|
|
||||||
static CMD_COMMAND *WCMD_createCommand(WCHAR *command, int *commandLen,
|
|
||||||
WCHAR *redirs, int *redirLen,
|
|
||||||
WCHAR **copyTo, int **copyToLen,
|
|
||||||
int curDepth)
|
|
||||||
{
|
|
||||||
CMD_COMMAND *thisEntry = NULL;
|
|
||||||
|
|
||||||
/* Allocate storage for command */
|
|
||||||
thisEntry = xalloc(sizeof(CMD_COMMAND));
|
|
||||||
|
|
||||||
/* Copy in the command */
|
|
||||||
if (command) {
|
|
||||||
WCHAR *pos;
|
|
||||||
WCHAR *last = redirs + *redirLen;
|
|
||||||
CMD_REDIRECTION **insrt;
|
|
||||||
|
|
||||||
thisEntry->command = xalloc((*commandLen + 1) * sizeof(WCHAR));
|
|
||||||
memcpy(thisEntry->command, command, *commandLen * sizeof(WCHAR));
|
|
||||||
thisEntry->command[*commandLen] = 0x00;
|
|
||||||
|
|
||||||
if (redirs) redirs[*redirLen] = 0;
|
|
||||||
/* Create redirects, keeping order (eg "2>foo 1>&2") */
|
|
||||||
insrt = &thisEntry->redirects;
|
|
||||||
*insrt = NULL;
|
|
||||||
for (pos = redirs; pos; insrt = &(*insrt)->next)
|
|
||||||
{
|
|
||||||
WCHAR *p = find_chr(pos, last, L"<>");
|
|
||||||
WCHAR *filename;
|
|
||||||
|
|
||||||
if (!p) break;
|
|
||||||
|
|
||||||
if (*p == L'<')
|
|
||||||
{
|
|
||||||
filename = WCMD_parameter(p + 1, 0, NULL, FALSE, FALSE);
|
|
||||||
*insrt = redirection_create_file(REDIR_READ_FROM, 0, filename);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned fd = 1;
|
|
||||||
unsigned op = REDIR_WRITE_TO;
|
|
||||||
|
|
||||||
if (p > redirs && p[-1] >= L'2' && p[-1] <= L'9') fd = p[-1] - L'0';
|
|
||||||
if (*++p == L'>') {p++; op = REDIR_WRITE_APPEND;}
|
|
||||||
if (*p == L'&' && (p[1] >= L'0' && p[1] <= L'9'))
|
|
||||||
{
|
|
||||||
*insrt = redirection_create_clone(fd, p[1] - '0');
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filename = WCMD_parameter(p, 0, NULL, FALSE, FALSE);
|
|
||||||
*insrt = redirection_create_file(op, fd, filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pos = p + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset the lengths */
|
|
||||||
*commandLen = 0;
|
|
||||||
*redirLen = 0;
|
|
||||||
*copyToLen = commandLen;
|
|
||||||
*copyTo = command;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
thisEntry->command = NULL;
|
|
||||||
thisEntry->redirects = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in other fields */
|
|
||||||
thisEntry->pipeFile[0] = 0x00;
|
|
||||||
thisEntry->bracketDepth = curDepth;
|
|
||||||
return thisEntry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* WCMD_IsEndQuote
|
* WCMD_IsEndQuote
|
||||||
*
|
*
|
||||||
|
@ -2364,6 +2285,7 @@ struct node_builder
|
||||||
union token_parameter parameter;
|
union token_parameter parameter;
|
||||||
} *stack;
|
} *stack;
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
unsigned opened_parenthesis;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* debugstr_token(enum builder_token tkn, union token_parameter tkn_pmt)
|
static const char* debugstr_token(enum builder_token tkn, union token_parameter tkn_pmt)
|
||||||
|
@ -2528,6 +2450,90 @@ static BOOL node_builder_generate(struct node_builder *builder, CMD_NODE **node)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* WCMD_addCommand
|
||||||
|
*
|
||||||
|
* Adds a command to the current command list
|
||||||
|
*/
|
||||||
|
static void lexer_push_command(struct node_builder *builder,
|
||||||
|
WCHAR *command, int *commandLen,
|
||||||
|
WCHAR *redirs, int *redirLen,
|
||||||
|
WCHAR **copyTo, int **copyToLen)
|
||||||
|
{
|
||||||
|
union token_parameter tkn_pmt;
|
||||||
|
CMD_COMMAND *thisEntry = NULL;
|
||||||
|
|
||||||
|
/* Allocate storage for command */
|
||||||
|
thisEntry = xalloc(sizeof(CMD_COMMAND));
|
||||||
|
|
||||||
|
/* Copy in the command */
|
||||||
|
if (command)
|
||||||
|
{
|
||||||
|
WCHAR *pos;
|
||||||
|
WCHAR *last = redirs + *redirLen;
|
||||||
|
CMD_REDIRECTION **insrt;
|
||||||
|
|
||||||
|
thisEntry->command = xalloc((*commandLen + 1) * sizeof(WCHAR));
|
||||||
|
memcpy(thisEntry->command, command, *commandLen * sizeof(WCHAR));
|
||||||
|
thisEntry->command[*commandLen] = 0x00;
|
||||||
|
|
||||||
|
if (redirs) redirs[*redirLen] = 0;
|
||||||
|
/* Create redirects, keeping order (eg "2>foo 1>&2") */
|
||||||
|
insrt = &thisEntry->redirects;
|
||||||
|
*insrt = NULL;
|
||||||
|
for (pos = redirs; pos; insrt = &(*insrt)->next)
|
||||||
|
{
|
||||||
|
WCHAR *p = find_chr(pos, last, L"<>");
|
||||||
|
WCHAR *filename;
|
||||||
|
|
||||||
|
if (!p) break;
|
||||||
|
|
||||||
|
if (*p == L'<')
|
||||||
|
{
|
||||||
|
filename = WCMD_parameter(p + 1, 0, NULL, FALSE, FALSE);
|
||||||
|
*insrt = redirection_create_file(REDIR_READ_FROM, 0, filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned fd = 1;
|
||||||
|
unsigned op = REDIR_WRITE_TO;
|
||||||
|
|
||||||
|
if (p > redirs && p[-1] >= L'2' && p[-1] <= L'9') fd = p[-1] - L'0';
|
||||||
|
if (*++p == L'>') {p++; op = REDIR_WRITE_APPEND;}
|
||||||
|
if (*p == L'&' && (p[1] >= L'0' && p[1] <= L'9'))
|
||||||
|
{
|
||||||
|
*insrt = redirection_create_clone(fd, p[1] - '0');
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filename = WCMD_parameter(p, 0, NULL, FALSE, FALSE);
|
||||||
|
*insrt = redirection_create_file(op, fd, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos = p + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the lengths */
|
||||||
|
*commandLen = 0;
|
||||||
|
*redirLen = 0;
|
||||||
|
*copyToLen = commandLen;
|
||||||
|
*copyTo = command;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thisEntry->command = NULL;
|
||||||
|
thisEntry->redirects = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in other fields */
|
||||||
|
thisEntry->pipeFile[0] = 0x00;
|
||||||
|
thisEntry->bracketDepth = builder->opened_parenthesis;
|
||||||
|
tkn_pmt.command = thisEntry;
|
||||||
|
node_builder_push_token_parameter(builder, TKN_COMMAND, tkn_pmt);
|
||||||
|
}
|
||||||
|
|
||||||
static WCHAR *fetch_next_line(BOOL feed, BOOL first_line, HANDLE from, WCHAR* buffer)
|
static WCHAR *fetch_next_line(BOOL feed, BOOL first_line, HANDLE from, WCHAR* buffer)
|
||||||
{
|
{
|
||||||
/* display prompt */
|
/* display prompt */
|
||||||
|
@ -2614,8 +2620,6 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
int curRedirsLen = 0;
|
int curRedirsLen = 0;
|
||||||
WCHAR *curCopyTo;
|
WCHAR *curCopyTo;
|
||||||
int *curLen;
|
int *curLen;
|
||||||
int curDepth = 0;
|
|
||||||
union token_parameter tkn_pmt;
|
|
||||||
enum builder_token cmd_tkn = TKN_AMP;
|
enum builder_token cmd_tkn = TKN_AMP;
|
||||||
static WCHAR *extraSpace = NULL; /* Deliberately never freed */
|
static WCHAR *extraSpace = NULL; /* Deliberately never freed */
|
||||||
BOOL inOneLine = FALSE;
|
BOOL inOneLine = FALSE;
|
||||||
|
@ -2657,7 +2661,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
curCopyTo = curString;
|
curCopyTo = curString;
|
||||||
curLen = &curStringLen;
|
curLen = &curStringLen;
|
||||||
lastWasRedirect = FALSE; /* Required e.g. for spaces between > and filename */
|
lastWasRedirect = FALSE; /* Required e.g. for spaces between > and filename */
|
||||||
lineCurDepth = curDepth; /* What was the curdepth at the beginning of the line */
|
lineCurDepth = builder.opened_parenthesis; /* What was the curdepth at the beginning of the line */
|
||||||
|
|
||||||
/* Parse every character on the line being processed */
|
/* Parse every character on the line being processed */
|
||||||
while (*curPos != 0x00) {
|
while (*curPos != 0x00) {
|
||||||
|
@ -2723,7 +2727,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
if (resetAtEndOfLine) {
|
if (resetAtEndOfLine) {
|
||||||
WINE_TRACE("Resetting curdepth at end of line to %d\n", lineCurDepth);
|
WINE_TRACE("Resetting curdepth at end of line to %d\n", lineCurDepth);
|
||||||
resetAtEndOfLine = FALSE;
|
resetAtEndOfLine = FALSE;
|
||||||
curDepth = lineCurDepth;
|
builder.opened_parenthesis = lineCurDepth;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2832,11 +2836,9 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
|
|
||||||
node_builder_push_token(&builder, cmd_tkn);
|
node_builder_push_token(&builder, cmd_tkn);
|
||||||
/* Add the current command */
|
/* Add the current command */
|
||||||
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
|
lexer_push_command(&builder, curString, &curStringLen,
|
||||||
curRedirs, &curRedirsLen,
|
curRedirs, &curRedirsLen,
|
||||||
&curCopyTo, &curLen,
|
&curCopyTo, &curLen);
|
||||||
curDepth);
|
|
||||||
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(curPos+1) == '|') {
|
if (*(curPos+1) == '|') {
|
||||||
|
@ -2849,8 +2851,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
/* If in an IF or ELSE statement, put subsequent chained
|
/* If in an IF or ELSE statement, put subsequent chained
|
||||||
commands at a higher depth as if brackets were supplied
|
commands at a higher depth as if brackets were supplied
|
||||||
but remember to reset to the original depth at EOL */
|
but remember to reset to the original depth at EOL */
|
||||||
if ((inIf || inElse) && curDepth == lineCurDepth) {
|
if ((inIf || inElse) && builder.opened_parenthesis == lineCurDepth) {
|
||||||
curDepth++;
|
builder.opened_parenthesis++;
|
||||||
resetAtEndOfLine = TRUE;
|
resetAtEndOfLine = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2881,7 +2883,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
|
|
||||||
/* Ignore open brackets inside the for set */
|
/* Ignore open brackets inside the for set */
|
||||||
if (*curLen == 0 && !inIn) {
|
if (*curLen == 0 && !inIn) {
|
||||||
curDepth++;
|
builder.opened_parenthesis++;
|
||||||
|
|
||||||
/* If in quotes, ignore brackets */
|
/* If in quotes, ignore brackets */
|
||||||
} else if (inQuotes) {
|
} else if (inQuotes) {
|
||||||
|
@ -2906,13 +2908,10 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
|
|
||||||
node_builder_push_token(&builder, cmd_tkn);
|
node_builder_push_token(&builder, cmd_tkn);
|
||||||
/* Add the current command */
|
/* Add the current command */
|
||||||
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
|
lexer_push_command(&builder, curString, &curStringLen,
|
||||||
curRedirs, &curRedirsLen,
|
curRedirs, &curRedirsLen,
|
||||||
&curCopyTo, &curLen,
|
&curCopyTo, &curLen);
|
||||||
curDepth);
|
builder.opened_parenthesis++;
|
||||||
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
|
|
||||||
|
|
||||||
curDepth++;
|
|
||||||
} else {
|
} else {
|
||||||
curCopyTo[(*curLen)++] = *curPos;
|
curCopyTo[(*curLen)++] = *curPos;
|
||||||
}
|
}
|
||||||
|
@ -2947,11 +2946,9 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
|
|
||||||
node_builder_push_token(&builder, cmd_tkn);
|
node_builder_push_token(&builder, cmd_tkn);
|
||||||
/* Add the current command */
|
/* Add the current command */
|
||||||
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
|
lexer_push_command(&builder, curString, &curStringLen,
|
||||||
curRedirs, &curRedirsLen,
|
curRedirs, &curRedirsLen,
|
||||||
&curCopyTo, &curLen,
|
&curCopyTo, &curLen);
|
||||||
curDepth);
|
|
||||||
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(curPos+1) == '&') {
|
if (*(curPos+1) == '&') {
|
||||||
|
@ -2963,8 +2960,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
/* If in an IF or ELSE statement, put subsequent chained
|
/* If in an IF or ELSE statement, put subsequent chained
|
||||||
commands at a higher depth as if brackets were supplied
|
commands at a higher depth as if brackets were supplied
|
||||||
but remember to reset to the original depth at EOL */
|
but remember to reset to the original depth at EOL */
|
||||||
if ((inIf || inElse) && curDepth == lineCurDepth) {
|
if ((inIf || inElse) && builder.opened_parenthesis == lineCurDepth) {
|
||||||
curDepth++;
|
builder.opened_parenthesis++;
|
||||||
resetAtEndOfLine = TRUE;
|
resetAtEndOfLine = TRUE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2972,7 +2969,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ')': if (!inQuotes && curDepth > 0) {
|
case ')': if (!inQuotes && builder.opened_parenthesis > 0) {
|
||||||
lastWasRedirect = FALSE;
|
lastWasRedirect = FALSE;
|
||||||
|
|
||||||
/* Add the current command if there is one */
|
/* Add the current command if there is one */
|
||||||
|
@ -2980,23 +2977,19 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
|
|
||||||
node_builder_push_token(&builder, cmd_tkn);
|
node_builder_push_token(&builder, cmd_tkn);
|
||||||
/* Add the current command */
|
/* Add the current command */
|
||||||
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
|
lexer_push_command(&builder, curString, &curStringLen,
|
||||||
curRedirs, &curRedirsLen,
|
curRedirs, &curRedirsLen,
|
||||||
&curCopyTo, &curLen,
|
&curCopyTo, &curLen);
|
||||||
curDepth);
|
|
||||||
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add an empty entry to the command list */
|
/* Add an empty entry to the command list */
|
||||||
cmd_tkn = TKN_AMP;
|
cmd_tkn = TKN_AMP;
|
||||||
node_builder_push_token(&builder, cmd_tkn);
|
node_builder_push_token(&builder, cmd_tkn);
|
||||||
tkn_pmt.command = WCMD_createCommand(NULL, &curStringLen,
|
lexer_push_command(&builder, NULL, &curStringLen,
|
||||||
curRedirs, &curRedirsLen,
|
curRedirs, &curRedirsLen,
|
||||||
&curCopyTo, &curLen,
|
&curCopyTo, &curLen);
|
||||||
curDepth);
|
|
||||||
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
|
|
||||||
|
|
||||||
curDepth--;
|
builder.opened_parenthesis--;
|
||||||
|
|
||||||
/* Leave inIn if necessary */
|
/* Leave inIn if necessary */
|
||||||
if (inIn) inIn = FALSE;
|
if (inIn) inIn = FALSE;
|
||||||
|
@ -3028,24 +3021,22 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
|
|
||||||
node_builder_push_token(&builder, cmd_tkn);
|
node_builder_push_token(&builder, cmd_tkn);
|
||||||
/* Add an entry to the command list */
|
/* Add an entry to the command list */
|
||||||
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
|
lexer_push_command(&builder, curString, &curStringLen,
|
||||||
curRedirs, &curRedirsLen,
|
curRedirs, &curRedirsLen,
|
||||||
&curCopyTo, &curLen,
|
&curCopyTo, &curLen);
|
||||||
curDepth);
|
|
||||||
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
|
|
||||||
|
|
||||||
/* If we had a single line if or else, and we pretended to add
|
/* If we had a single line if or else, and we pretended to add
|
||||||
brackets, end them now */
|
brackets, end them now */
|
||||||
if (resetAtEndOfLine) {
|
if (resetAtEndOfLine) {
|
||||||
WINE_TRACE("Resetting curdepth at end of line to %d\n", lineCurDepth);
|
WINE_TRACE("Resetting curdepth at end of line to %d\n", lineCurDepth);
|
||||||
resetAtEndOfLine = FALSE;
|
resetAtEndOfLine = FALSE;
|
||||||
curDepth = lineCurDepth;
|
builder.opened_parenthesis = lineCurDepth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have reached the end of the string, see if bracketing or
|
/* If we have reached the end of the string, see if bracketing or
|
||||||
final caret is outstanding */
|
final caret is outstanding */
|
||||||
if (*curPos == 0x00 && curDepth > 0 && readFrom != INVALID_HANDLE_VALUE) {
|
if (*curPos == 0x00 && builder.opened_parenthesis > 0 && readFrom != INVALID_HANDLE_VALUE) {
|
||||||
|
|
||||||
WINE_TRACE("Need to read more data as outstanding brackets or carets\n");
|
WINE_TRACE("Need to read more data as outstanding brackets or carets\n");
|
||||||
inOneLine = FALSE;
|
inOneLine = FALSE;
|
||||||
|
@ -3065,7 +3056,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
|
||||||
}
|
}
|
||||||
|
|
||||||
*output = NULL;
|
*output = NULL;
|
||||||
ret = curDepth <= lineCurDepth && node_builder_generate(&builder, output);
|
ret = builder.opened_parenthesis <= lineCurDepth && node_builder_generate(&builder, output);
|
||||||
node_builder_dispose(&builder);
|
node_builder_dispose(&builder);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue