cmd: Add support for LSS comparison operator in if statements.
This commit is contained in:
parent
17607b8020
commit
154710a093
|
@ -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, ¶mStart, FALSE, FALSE));
|
||||||
|
if (!*operator) goto syntax_err;
|
||||||
|
}
|
||||||
p += strlenW(operator);
|
p += strlenW(operator);
|
||||||
|
|
||||||
strcpyW(rightOperand, WCMD_parameter(p, 0, ¶mStart, TRUE, FALSE));
|
strcpyW(rightOperand, WCMD_parameter(p, 0, ¶mStart, 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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue