cmd: Add support for LSS comparison operator in if statements.

This commit is contained in:
Frédéric Delanoy 2012-10-25 23:48:02 +02:00 committed by Alexandre Julliard
parent 17607b8020
commit 154710a093
2 changed files with 81 additions and 32 deletions

View File

@ -104,6 +104,7 @@ static const WCHAR onW[] = {'O','N','\0'};
static const WCHAR offW[] = {'O','F','F','\0'}; static const WCHAR offW[] = {'O','F','F','\0'};
static const WCHAR parmY[] = {'/','Y','\0'}; static const WCHAR parmY[] = {'/','Y','\0'};
static const WCHAR parmNoY[] = {'/','-','Y','\0'}; static const WCHAR parmNoY[] = {'/','-','Y','\0'};
static const WCHAR eqeqW[] = {'=','=','\0'};
static HINSTANCE hinst; static HINSTANCE hinst;
struct env_stack *saved_environment; struct env_stack *saved_environment;
@ -2332,6 +2333,52 @@ void WCMD_popd (void) {
LocalFree (temp); LocalFree (temp);
} }
/*******************************************************************
* evaluate_if_comparison
*
* Evaluates an "if" comparison operation
*
* PARAMS
* leftOperand [I] left operand, non NULL
* operator [I] "if" binary comparison operator, non NULL
* rightOperand [I] right operand, non NULL
* caseInsensitive [I] 0 for case sensitive comparison, anything else for insensitive
*
* RETURNS
* Success: 1 if operator applied to the operands evaluates to TRUE
* 0 if operator applied to the operands evaluates to FALSE
* Failure: -1 if operator is not recognized
*/
static int evaluate_if_comparison(const WCHAR *leftOperand, const WCHAR *operator,
const WCHAR *rightOperand, int caseInsensitive)
{
WCHAR *endptr_leftOp, *endptr_rightOp;
long int leftOperand_int, rightOperand_int;
BOOL int_operands;
static const WCHAR lssW[] = {'l','s','s','\0'};
/* == is a special case, as it always compares strings */
if (!lstrcmpiW(operator, eqeqW))
return caseInsensitive ? lstrcmpiW(leftOperand, rightOperand) == 0
: lstrcmpW (leftOperand, rightOperand) == 0;
/* Check if we have plain integers (in decimal, octal or hexadecimal notation) */
leftOperand_int = strtolW(leftOperand, &endptr_leftOp, 0);
rightOperand_int = strtolW(rightOperand, &endptr_rightOp, 0);
int_operands = (!*endptr_leftOp) && (!*endptr_rightOp);
/* Perform actual (integer or string) comparison */
if (!lstrcmpiW(operator, lssW)) {
if (int_operands)
return leftOperand_int < rightOperand_int;
else
return caseInsensitive ? lstrcmpiW(leftOperand, rightOperand) < 0
: lstrcmpW (leftOperand, rightOperand) < 0;
}
return -1;
}
/**************************************************************************** /****************************************************************************
* WCMD_if * WCMD_if
* *
@ -2355,7 +2402,6 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList)
static const WCHAR errlvlW[] = {'e','r','r','o','r','l','e','v','e','l','\0'}; static const WCHAR errlvlW[] = {'e','r','r','o','r','l','e','v','e','l','\0'};
static const WCHAR existW[] = {'e','x','i','s','t','\0'}; static const WCHAR existW[] = {'e','x','i','s','t','\0'};
static const WCHAR defdW[] = {'d','e','f','i','n','e','d','\0'}; static const WCHAR defdW[] = {'d','e','f','i','n','e','d','\0'};
static const WCHAR eqeqW[] = {'=','=','\0'};
static const WCHAR parmI[] = {'/','I','\0'}; static const WCHAR parmI[] = {'/','I','\0'};
int caseInsensitive = (strstrW(quals, parmI) != NULL); int caseInsensitive = (strstrW(quals, parmI) != NULL);
@ -2394,18 +2440,21 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList)
while (*p == ' ' || *p == '\t') while (*p == ' ' || *p == '\t')
p++; p++;
if (strncmpW(p, eqeqW, strlenW(eqeqW))) if (!strncmpW(p, eqeqW, strlenW(eqeqW)))
goto syntax_err; strcpyW(operator, eqeqW);
else {
strcpyW(operator, eqeqW); strcpyW(operator, WCMD_parameter(p, 0, &paramStart, FALSE, FALSE));
if (!*operator) goto syntax_err;
}
p += strlenW(operator); p += strlenW(operator);
strcpyW(rightOperand, WCMD_parameter(p, 0, &paramStart, TRUE, FALSE)); strcpyW(rightOperand, WCMD_parameter(p, 0, &paramStart, TRUE, FALSE));
if (!*rightOperand) if (!*rightOperand)
goto syntax_err; goto syntax_err;
test = caseInsensitive ? lstrcmpiW(leftOperand, rightOperand) == 0 test = evaluate_if_comparison(leftOperand, operator, rightOperand, caseInsensitive);
: lstrcmpW (leftOperand, rightOperand) == 0; if (test == -1)
goto syntax_err;
p = paramStart + strlenW(rightOperand); p = paramStart + strlenW(rightOperand);
WCMD_parameter(p, 0, &command, FALSE, FALSE); WCMD_parameter(p, 0, &command, FALSE, FALSE);

View File

@ -441,25 +441,25 @@ quake
--- comparison operators --- comparison operators
------ for strings ------ for strings
LSS string can be used as operand for LSS comparison LSS string can be used as operand for LSS comparison
@todo_wine@floats are handled as strings floats are handled as strings
@todo_wine@numbers in quotes are handled as strings numbers in quotes are handled as strings
@todo_wine@negative numbers as well@or_broken@NT4 negative numbers as well@or_broken@NT4
@todo_wine@if /i seems to work for LSS if /i seems to work for LSS
@todo_wine@A LSS B A LSS B
@todo_wine@AB LSS B AB LSS B
@todo_wine@AA LSS B AA LSS B
@todo_wine@A LSS AB A LSS AB
@todo_wine@AA LSS AB AA LSS AB
@todo_wine@A LSS BA A LSS BA
@todo_wine@B LSS BA B LSS BA
@todo_wine@AB LSS BA AB LSS BA
@todo_wine@AA LSS BA AA LSS BA
@todo_wine@A LSS AA A LSS AA
@todo_wine@b LSS B@or_broken@NT4 b LSS B@or_broken@NT4
@todo_wine@a LSS B@or_broken@NT4 a LSS B@or_broken@NT4
@todo_wine@a LSS B insensitive a LSS B insensitive
@todo_wine@A LSS b A LSS b
@todo_wine@A LSS b insensitive A LSS b insensitive
@todo_wine@A LEQ A @todo_wine@A LEQ A
@todo_wine@A LEQ B @todo_wine@A LEQ B
@todo_wine@B LEQ B @todo_wine@B LEQ B
@ -540,12 +540,12 @@ also in negative form
hexa handled hexa handled
also in negative form also in negative form
11 LSS 101 11 LSS 101
@todo_wine@0 LSS 1 0 LSS 1
@todo_wine@0 LSS 10 0 LSS 10
@todo_wine@1 LSS 10 1 LSS 10
@todo_wine@9 LSS 10 9 LSS 10
@todo_wine@0 LSS 9 0 LSS 9
@todo_wine@1 LSS 9 1 LSS 9
@todo_wine@0 LEQ 0 @todo_wine@0 LEQ 0
@todo_wine@0 LEQ 1 @todo_wine@0 LEQ 1
@todo_wine@1 LEQ 1 @todo_wine@1 LEQ 1