1
0
mirror of https://github.com/wine-mirror/wine synced 2024-06-29 06:14:34 +00:00

cmd: Introduce token-based syntax parser for building command nodes.

Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
Eric Pouech 2024-04-22 09:04:51 +02:00 committed by Alexandre Julliard
parent 9a7408e771
commit 2ec70835fc
53 changed files with 505 additions and 58 deletions

View File

@ -15884,6 +15884,12 @@ msgstr ""
"صيغة الرقم غير سليمة حيث أنها يمكن أن تكون عشرية (12),\n"
" أو ست عشرية (0x34) أو ثماني (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "خطأ بنيوي\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "حجم المؤشر"

View File

@ -14479,6 +14479,12 @@ msgstr ""
"El númberu tien un formatu incorreutu. Ha ser\n"
"decimal (12), hexadecimal (0x34) o octal (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Error de la sintaxis\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Tamañu del cursor"

View File

@ -14575,6 +14575,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14681,6 +14681,12 @@ msgstr ""
"El nombre és mal format - ha de ser un de decimal (12)\n"
" hexadecimal (0x34) o octal (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Error de sintaxi\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Mida de cursor"

View File

@ -15398,6 +15398,12 @@ msgstr ""
"Špatný formát čísla musí být desítkové (12),\n"
"šestnáctkové (0x34) či osmičkové (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Chyba syntaxe\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Velikost kurzoru"

View File

@ -15793,6 +15793,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Syntaks fejl\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Markør størrelse"

View File

@ -14663,6 +14663,12 @@ msgstr ""
"Zahl ungültig formatiert - muss dezimal (12),\n"
" hexadezimal (0x34) oder oktal (056) sein.\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Syntaxfehler\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Cursorgröße"

View File

@ -14331,6 +14331,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14575,6 +14575,10 @@ msgstr ""
"Badly formed number - must be one of decimal (12),\n"
" hexadecimal (0x34) or octal (056).\n"
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr "Syntax error: unexpected %1\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Cursor size"

View File

@ -14575,6 +14575,10 @@ msgstr ""
"Badly formed number - must be one of decimal (12),\n"
" hexadecimal (0x34) or octal (056).\n"
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr "Syntax error: unexpected %1\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Cursor size"

View File

@ -14940,6 +14940,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Kursor-grando"

View File

@ -15258,6 +15258,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Error de sintaxis\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Tamaño del cursor"

View File

@ -14516,6 +14516,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14555,6 +14555,12 @@ msgstr ""
"Luvun muoto ei kelpaa täytyy olla desimaaliluku (12),\n"
" heksadesimaaliluku (0x34) tai oktaaliluku (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Syntaksivirhe\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Kursorin koko"

View File

@ -15175,6 +15175,12 @@ msgstr ""
"Nombre mal formé : doit être décimal (12),\n"
" hexadécimal (0x34) ou octal (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Erreur de syntaxe\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Taille du curseur"

View File

@ -15339,6 +15339,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error"
msgid "Syntax error: unexpected %1\n"
msgstr "שגיאת תחביר"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "גודל הסמן"

View File

@ -14071,6 +14071,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -15350,6 +15350,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Sintaksna greška\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Veličina pokazivača"

View File

@ -15784,6 +15784,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Szintaktikai hiba\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Kurzor mérete"

View File

@ -15860,6 +15860,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Errore di sintassi\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Dimensione del cursore"

View File

@ -14575,6 +14575,12 @@ msgstr ""
"数値の形式に誤りがあります - 10 進数 (12)、16 進数 (0x34)、\n"
"8 進数 (056) のいずれかとする必要があります。\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "構文エラー\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "カーソルの大きさ"

View File

@ -14178,6 +14178,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "სინტაქსური შეცდომა\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "კურსორის ზომა"

View File

@ -14532,6 +14532,12 @@ msgstr ""
"잘못된 형식의 숫자 - 10진수(12)나,\n"
"16진수(0x34)나 8진수(056)중의 하나이어야 합니다.\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "문법 오류\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "커서 크기"

View File

@ -14581,6 +14581,12 @@ msgstr ""
"Blogai sudarytas skaičius privalo būti dešimtainis (12),\n"
" šešioliktainis (0x34) arba aštuntainis (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Sintaksės klaida\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Žymeklio dydis"

View File

@ -14070,6 +14070,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -15380,6 +15380,12 @@ msgstr ""
"Ugyldig tallformat - må være enten desimal (12),\n"
"heksadesimal (0x34) eller oktal (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Syntaksfeil\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Pekerstørrelse"

View File

@ -14630,6 +14630,12 @@ msgstr ""
"Misvormd nummer - moet of decimaal (12),\n"
" hexadecimaal (0x34) of octaal (056) zijn.\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Formuleringsfout\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Cursorgrootte"

View File

@ -14056,6 +14056,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14056,6 +14056,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14615,6 +14615,12 @@ msgstr ""
"Zły format liczbowy - musi on być jednym z formatów dziesiętnych (12),\n"
" szesnastkowych (0x34) lub ósemkowych (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Błąd składni\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Rozmiar kursora"

View File

@ -14781,6 +14781,12 @@ msgstr ""
"Número malformado - deve ser decimal (12),\n"
" hexadecimal (0x34) ou octal (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Erro de sintaxe\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Cursor"

View File

@ -15555,6 +15555,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Erro de sintaxe\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Tamanho do Cursor"

View File

@ -14144,6 +14144,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -15629,6 +15629,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Eroare de sintaxă\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Dimensiune cursor"

View File

@ -15012,6 +15012,12 @@ msgstr ""
"Неверный формат числа - должен быть десятичный (12),\n"
" шестнадцатеричный (0x34) или восьмеричный (056) формат.\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Синтаксическая ошибка\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Размер курсора"

View File

@ -14677,6 +14677,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "වාග් රීති දෝෂයක්\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "කර්සරය ප්රමාණය"

View File

@ -15096,6 +15096,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -15814,6 +15814,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Napaka skladnje\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Velikost kazalca"

View File

@ -15125,6 +15125,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error"
msgid "Syntax error: unexpected %1\n"
msgstr "Грешка у синтакси"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -15266,6 +15266,12 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error"
msgid "Syntax error: unexpected %1\n"
msgstr "Greška u sintaksi"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -15509,6 +15509,12 @@ msgstr ""
"Felaktigt talformat - måste vara en av decimal (12),\n"
" hexadecimal (0x34) eller oktal (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Syntaxfel\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Markörstorlek"

View File

@ -14044,6 +14044,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14056,6 +14056,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14607,6 +14607,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14601,6 +14601,12 @@ msgstr ""
"Hatalı numara biçimi - ondalık (12), onaltılı (0x34) veya sekizli (056) "
"olmalıdır.\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Sözdizimi hatası\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "İmleç boyutu"

View File

@ -14874,6 +14874,12 @@ msgstr ""
"Неправильно сформоване число - має бути або десятковим (12),\n"
" або шістнадцятковим (0x34), або вісімковим (056).\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "Синтаксична помилка\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "Розмір курсора"

View File

@ -14501,6 +14501,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -13971,6 +13971,10 @@ msgid ""
" hexadecimal (0x34) or octal (056).\n"
msgstr ""
#: programs/cmd/cmd.rc:411
msgid "Syntax error: unexpected %1\n"
msgstr ""
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr ""

View File

@ -14369,6 +14369,12 @@ msgstr ""
"数字的格式错误 - 必须是十进制 (12),\n"
" 十六进制 (0x34) 或者八进制 (056)。\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "语法错误\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "光标尺寸"

View File

@ -14435,6 +14435,12 @@ msgstr ""
"錯誤的數字形式 - 必須是十進位 (12)、\n"
" 十六進位 (0x34) 或八進位 (056) 之一。\n"
#: programs/cmd/cmd.rc:411
#, fuzzy
#| msgid "Syntax error\n"
msgid "Syntax error: unexpected %1\n"
msgstr "語法錯誤\n"
#: programs/conhost/conhost.rc:54
msgid "Cursor size"
msgstr "游標大小"

View File

@ -407,4 +407,5 @@ Enter HELP <command> for further information on any of the above commands.\n"
WCMD_BADPAREN, "Mismatch in parentheses.\n"
WCMD_BADHEXOCT, "Badly formed number - must be one of decimal (12),\n hexadecimal (0x34) or octal (056).\n"
WCMD_FILENAMETOOLONG, "File name is too long.\n"
WCMD_BADTOKEN, "Syntax error: unexpected %1\n"
}

View File

@ -469,3 +469,4 @@ extern WCHAR version_string[];
#define WCMD_BADPAREN 1044
#define WCMD_BADHEXOCT 1045
#define WCMD_FILENAMETOOLONG 1046
#define WCMD_BADTOKEN 1047

View File

@ -2125,23 +2125,6 @@ static CMD_COMMAND *WCMD_createCommand(WCHAR *command, int *commandLen,
return thisEntry;
}
static void WCMD_appendCommand(CMD_OPERATOR op, CMD_COMMAND *command, CMD_NODE **node)
{
/* append as left to right operators */
if (*node)
{
CMD_NODE **last = node;
while ((*last)->op != CMD_SINGLE)
last = &(*last)->right;
*last = node_create_binary(op, *last, node_create_single(command));
}
else
{
*node = node_create_single(command);
}
}
/***************************************************************************
* WCMD_IsEndQuote
*
@ -2377,6 +2360,190 @@ syntax_error:
return NULL;
}
/* used to store additional information dedicated a given token */
union token_parameter
{
CMD_COMMAND *command;
void *none;
};
struct node_builder
{
unsigned num;
unsigned allocated;
struct token
{
enum builder_token
{
TKN_EOL, TKN_AMP, TKN_BARBAR, TKN_AMPAMP, TKN_BAR, TKN_COMMAND,
} token;
union token_parameter parameter;
} *stack;
unsigned pos;
};
static const char* debugstr_token(enum builder_token tkn, union token_parameter tkn_pmt)
{
static const char *tokens[] = {"EOL", "&", "||", "&&", "|", "CMD"};
if (tkn >= ARRAY_SIZE(tokens)) return "<<<>>>";
switch (tkn)
{
case TKN_COMMAND: return wine_dbg_sprintf("%s {{%ls}}", tokens[tkn], tkn_pmt.command->command);
default: return wine_dbg_sprintf("%s", tokens[tkn]);
}
}
static void node_builder_init(struct node_builder *builder)
{
memset(builder, 0, sizeof(*builder));
}
static void node_builder_dispose(struct node_builder *builder)
{
free(builder->stack);
}
static void node_builder_push_token_parameter(struct node_builder *builder, enum builder_token tkn, union token_parameter pmt)
{
if (builder->allocated <= builder->num)
{
unsigned sz = builder->allocated ? 2 * builder->allocated : 64;
builder->stack = xrealloc(builder->stack, sz * sizeof(builder->stack[0]));
builder->allocated = sz;
}
builder->stack[builder->num].token = tkn;
builder->stack[builder->num].parameter = pmt;
builder->num++;
}
static void node_builder_push_token(struct node_builder *builder, enum builder_token tkn)
{
union token_parameter pmt = {.none = NULL};
node_builder_push_token_parameter(builder, tkn, pmt);
}
static enum builder_token node_builder_peek_next_token(struct node_builder *builder, union token_parameter *pmt)
{
enum builder_token tkn;
if (builder->pos >= builder->num)
{
tkn = TKN_EOL;
if (pmt) pmt->none = NULL;
}
else
{
tkn = builder->stack[builder->pos].token;
if (pmt)
*pmt = builder->stack[builder->pos].parameter;
}
return tkn;
}
static void node_builder_consume(struct node_builder *builder)
{
builder->stack[builder->pos].parameter.none = NULL;
builder->pos++;
}
static void WCMD_appendCommand(CMD_OPERATOR op, CMD_COMMAND *command, CMD_NODE **node)
{
/* append as left to right operators */
if (*node)
{
CMD_NODE **last = node;
while ((*last)->op != CMD_SINGLE)
last = &(*last)->right;
*last = node_create_binary(op, *last, node_create_single(command));
}
else
{
*node = node_create_single(command);
}
}
static BOOL node_builder_parse(struct node_builder *builder, CMD_NODE **result)
{
unsigned bogus_line;
CMD_NODE *left = NULL;
union token_parameter pmt;
enum builder_token tkn;
BOOL done;
#define ERROR_IF(x) if (x) {bogus_line = __LINE__; goto error_handling;}
for (;;)
{
CMD_OPERATOR cmd_op;
done = FALSE;
/* we always get a pair of OP CMMAND */
tkn = node_builder_peek_next_token(builder, &pmt);
switch (tkn)
{
case TKN_EOL: done = TRUE; break;
case TKN_AMP: cmd_op = CMD_CONCAT; break;
case TKN_AMPAMP: cmd_op = CMD_ONSUCCESS; break;
case TKN_BAR: cmd_op = CMD_PIPE; break;
case TKN_BARBAR: cmd_op = CMD_ONFAILURE; break;
case TKN_COMMAND: ERROR_IF(TRUE);
default: ERROR_IF(TRUE);
}
if (done) break;
node_builder_consume(builder);
tkn = node_builder_peek_next_token(builder, &pmt);
ERROR_IF(tkn != TKN_COMMAND)
node_builder_consume(builder);
WCMD_appendCommand(cmd_op, pmt.command, &left);
} while (!done);
#undef ERROR_IF
*result = left;
return TRUE;
error_handling:
TRACE("Parser failed at line %u:token %s\n", bogus_line, debugstr_token(tkn, pmt));
node_dispose_tree(left);
return FALSE;
}
static BOOL node_builder_generate(struct node_builder *builder, CMD_NODE **node)
{
union token_parameter tkn_pmt;
enum builder_token tkn;
if (node_builder_parse(builder, node) &&
builder->pos + 1 >= builder->num) /* consumed all tokens? */
return TRUE;
/* print error on first unused token */
if (builder->pos < builder->num)
{
tkn = node_builder_peek_next_token(builder, &tkn_pmt);
switch (tkn)
{
case TKN_COMMAND:
WCMD_output_stderr(WCMD_LoadMessage(WCMD_BADTOKEN), tkn_pmt.command->command);
break;
default:
WCMD_output_stderr(WCMD_LoadMessage(WCMD_BADTOKEN), debugstr_token(tkn, tkn_pmt));
}
}
/* free remaining tokens */
for (;;)
{
tkn = node_builder_peek_next_token(builder, &tkn_pmt);
if (tkn == TKN_EOL) break;
if (tkn == TKN_COMMAND) command_dispose(tkn_pmt.command);
node_builder_consume(builder);
}
*node = NULL;
return FALSE;
}
/***************************************************************************
* WCMD_ReadAndParseLine
*
@ -2402,8 +2569,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
WCHAR *curCopyTo;
int *curLen;
int curDepth = 0;
CMD_COMMAND *single_cmd = NULL;
CMD_OPERATOR cmd_op = CMD_CONCAT;
union token_parameter tkn_pmt;
enum builder_token cmd_tkn = TKN_AMP;
static WCHAR *extraSpace = NULL; /* Deliberately never freed */
BOOL inOneLine = FALSE;
BOOL inFor = FALSE;
@ -2421,6 +2588,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
/* handling brackets as a normal character */
int lineCurDepth; /* Bracket depth when line was read in */
BOOL resetAtEndOfLine = FALSE; /* Do we need to reset curdepth at EOL */
struct node_builder builder;
BOOL ret;
*output = NULL;
/* Allocate working space for a command read from keyboard, file etc */
@ -2445,6 +2614,8 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
curPos = extraSpace;
TRACE("About to parse line (%ls)\n", extraSpace);
node_builder_init(&builder);
/* Handle truncated input - issue warning */
if (lstrlenW(extraSpace) == MAXSTRING -1) {
WCMD_output_asis_stderr(WCMD_LoadMessage(WCMD_TRUNCATEDLINE));
@ -2662,19 +2833,20 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
/* Add an entry to the command list */
if (curStringLen > 0) {
node_builder_push_token(&builder, cmd_tkn);
/* Add the current command */
single_cmd = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
WCMD_appendCommand(cmd_op, single_cmd, output);
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
}
if (*(curPos+1) == '|') {
curPos++; /* Skip other | */
cmd_op = CMD_ONFAILURE;
cmd_tkn = TKN_BARBAR;
} else {
cmd_op = CMD_PIPE;
cmd_tkn = TKN_BAR;
}
/* If in an IF or ELSE statement, put subsequent chained
@ -2735,12 +2907,13 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
inIn = TRUE;
}
node_builder_push_token(&builder, cmd_tkn);
/* Add the current command */
single_cmd = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
WCMD_appendCommand(cmd_op, single_cmd, output);
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
curDepth++;
} else {
@ -2766,19 +2939,20 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
/* Add an entry to the command list */
if (curStringLen > 0) {
node_builder_push_token(&builder, cmd_tkn);
/* Add the current command */
single_cmd = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
WCMD_appendCommand(cmd_op, single_cmd, output);
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
}
if (*(curPos+1) == '&') {
curPos++; /* Skip other & */
cmd_op = CMD_ONSUCCESS;
cmd_tkn = TKN_AMPAMP;
} else {
cmd_op = CMD_CONCAT;
cmd_tkn = TKN_AMP;
}
/* If in an IF or ELSE statement, put subsequent chained
commands at a higher depth as if brackets were supplied
@ -2798,21 +2972,23 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
/* Add the current command if there is one */
if (curStringLen) {
node_builder_push_token(&builder, cmd_tkn);
/* Add the current command */
single_cmd = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
WCMD_appendCommand(cmd_op, single_cmd, output);
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
}
/* Add an empty entry to the command list */
cmd_op = CMD_CONCAT;
single_cmd = WCMD_createCommand(NULL, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
WCMD_appendCommand(cmd_op, single_cmd, output);
cmd_tkn = TKN_AMP;
node_builder_push_token(&builder, cmd_tkn);
tkn_pmt.command = WCMD_createCommand(NULL, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
node_builder_push_token_parameter(&builder, TKN_COMMAND, tkn_pmt);
curDepth--;
@ -2844,12 +3020,13 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
Do not add command to list if escape char ^ was last */
if (*curPos == 0x00 && !lastWasCaret && *curLen > 0) {
node_builder_push_token(&builder, cmd_tkn);
/* Add an entry to the command list */
single_cmd = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&curCopyTo, &curLen,
curDepth);
WCMD_appendCommand(cmd_op, single_cmd, output);
tkn_pmt.command = WCMD_createCommand(curString, &curStringLen,
curRedirs, &curRedirsLen,
&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
brackets, end them now */
@ -2869,7 +3046,7 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
WINE_TRACE("Need to read more data as outstanding brackets or carets\n");
inOneLine = FALSE;
ignoreBracket = FALSE;
cmd_op = CMD_CONCAT;
cmd_tkn = TKN_AMP;
inQuotes = 0;
memset(extraSpace, 0x00, (MAXSTRING+1) * sizeof(WCHAR));
extraData = extraSpace;
@ -2913,10 +3090,12 @@ WCHAR *WCMD_ReadAndParseLine(const WCHAR *optionalcmd, CMD_NODE **output, HANDLE
}
}
if (curDepth > lineCurDepth) {
*output = NULL;
ret = curDepth <= lineCurDepth && node_builder_generate(&builder, output);
node_builder_dispose(&builder);
if (!ret)
{
WINE_TRACE("Brackets do not match, error out without executing.\n");
node_dispose_tree(*output);
*output = NULL;
errorlevel = 255;
}