Module: wine Branch: master Commit: 6a520c0b6d6eb92c92f8172e58f41e01d7c59032 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=6a520c0b6d6eb92c92f8172e...
Author: James Hawkins truiken@gmail.com Date: Mon Aug 21 16:27:38 2006 -0700
msi: Add handling for MsiEvaluateCondition's substring operators.
---
dlls/msi/cond.y | 67 ++++++++++++++++++++++++++++++++++------- dlls/msi/tests/package.c | 75 +++++++++------------------------------------- 2 files changed, 70 insertions(+), 72 deletions(-)
diff --git a/dlls/msi/cond.y b/dlls/msi/cond.y index 6226e29..fda2c69 100644 --- a/dlls/msi/cond.y +++ b/dlls/msi/cond.y @@ -396,8 +396,61 @@ static WCHAR *strstriW( const WCHAR *str return r; }
+static BOOL str_is_number( LPCWSTR str ) +{ + int i; + + for (i = 0; i < lstrlenW( str ); i++) + if (!isdigitW(str[i])) + return FALSE; + + return TRUE; +} + +static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b ) +{ + int lhs, rhs; + + /* substring operators return 0 if LHS is missing */ + if (!a || !*a) + return 0; + + /* substring operators return 1 if RHS is missing */ + if (!b || !*b) + return 1; + + /* if both strings contain only numbers, use integer comparison */ + lhs = atoiW(a); + rhs = atoiW(b); + if (str_is_number(a) && str_is_number(b)) + return compare_int( lhs, operator, rhs ); + + switch (operator) + { + case COND_SS: + return strstrW( a, b ) ? 1 : 0; + case COND_ISS: + return strstriW( a, b ) ? 1 : 0; + case COND_LHS: + return 0 == strncmpW( a, b, lstrlenW( b ) ); + case COND_RHS: + return 0 == lstrcmpW( a + (lstrlenW( a ) - lstrlenW( b )), b ); + case COND_ILHS: + return 0 == strncmpiW( a, b, lstrlenW( b ) ); + case COND_IRHS: + return 0 == lstrcmpiW( a + (lstrlenW( a ) - lstrlenW( b )), b ); + default: + ERR("invalid substring operator\n"); + return 0; + } + return 0; +} + static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b ) { + if (operator >= COND_SS && operator <= COND_RHS) + return compare_substring( a, operator, b ); + /* null and empty string are equivalent */ if (!a) a = szEmpty; if (!b) b = szEmpty; @@ -417,8 +470,6 @@ static INT compare_string( LPCWSTR a, IN return -1 != lstrcmpW( a, b ); case COND_LE: return 1 != lstrcmpW( a, b ); - case COND_SS: /* substring */ - return strstrW( a, b ) ? 1 : 0; case COND_ILT: return -1 == lstrcmpiW( a, b ); case COND_IGT: @@ -431,16 +482,8 @@ static INT compare_string( LPCWSTR a, IN return -1 != lstrcmpiW( a, b ); case COND_ILE: return 1 != lstrcmpiW( a, b ); - case COND_ISS: - return strstriW( a, b ) ? 1 : 0; - case COND_LHS: - case COND_RHS: - case COND_ILHS: - case COND_IRHS: - ERR("unimplemented string comparison\n"); - break; default: - ERR("invalid integer operator\n"); + ERR("invalid string operator\n"); return 0; } return 0; @@ -508,10 +551,10 @@ static int COND_GetOperator( COND_input { {'>','=',0}, COND_GE }, { {'>','<',0}, COND_SS }, { {'<','<',0}, COND_LHS }, - { {'>',0}, COND_GT }, { {'<','>',0}, COND_NE }, { {'<','=',0}, COND_LE }, { {'>','>',0}, COND_RHS }, + { {'>',0}, COND_GT }, { {'<',0}, COND_LT }, { {0}, 0 } }; diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index a2d5459..01e6eaa 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -1043,10 +1043,7 @@ static void test_condition(void) MsiSetProperty(hpkg, "one", "1234"); MsiSetProperty(hpkg, "two", "1"); r = MsiEvaluateCondition(hpkg, "one >< two"); - todo_wine - { - ok( r == MSICONDITION_FALSE, "wrong return val\n"); - } + ok( r == MSICONDITION_FALSE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "one 1234"); MsiSetProperty(hpkg, "two", "1"); @@ -1056,10 +1053,7 @@ static void test_condition(void) MsiSetProperty(hpkg, "one", "hithere"); MsiSetProperty(hpkg, "two", "hi"); r = MsiEvaluateCondition(hpkg, "one << two"); - todo_wine - { - ok( r == MSICONDITION_TRUE, "wrong return val\n"); - } + ok( r == MSICONDITION_TRUE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "hi"); MsiSetProperty(hpkg, "two", "hithere"); @@ -1069,10 +1063,7 @@ static void test_condition(void) MsiSetProperty(hpkg, "one", "hi"); MsiSetProperty(hpkg, "two", "hi"); r = MsiEvaluateCondition(hpkg, "one << two"); - todo_wine - { - ok( r == MSICONDITION_TRUE, "wrong return val\n"); - } + ok( r == MSICONDITION_TRUE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "abcdhithere"); MsiSetProperty(hpkg, "two", "hi"); @@ -1087,10 +1078,7 @@ static void test_condition(void) MsiSetProperty(hpkg, "one", "hithere"); MsiSetProperty(hpkg, "two", ""); r = MsiEvaluateCondition(hpkg, "one << two"); - todo_wine - { - ok( r == MSICONDITION_TRUE, "wrong return val\n"); - } + ok( r == MSICONDITION_TRUE, "wrong return val\n");
MsiSetProperty(hpkg, "one", ""); MsiSetProperty(hpkg, "two", ""); @@ -1105,90 +1093,57 @@ static void test_condition(void) MsiSetProperty(hpkg, "one", "1234 one"); MsiSetProperty(hpkg, "two", "1"); r = MsiEvaluateCondition(hpkg, "one << two"); - todo_wine - { - ok( r == MSICONDITION_TRUE, "wrong return val\n"); - } + ok( r == MSICONDITION_TRUE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "hithere"); MsiSetProperty(hpkg, "two", "there"); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_TRUE, "wrong return val\n"); - } + ok( r == MSICONDITION_TRUE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "hithere"); MsiSetProperty(hpkg, "two", "hi"); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_FALSE, "wrong return val\n"); - } + ok( r == MSICONDITION_FALSE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "there"); MsiSetProperty(hpkg, "two", "hithere"); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_FALSE, "wrong return val\n"); - } + ok( r == MSICONDITION_FALSE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "there"); MsiSetProperty(hpkg, "two", "there"); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_TRUE, "wrong return val\n"); - } + ok( r == MSICONDITION_TRUE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "abcdhithere"); MsiSetProperty(hpkg, "two", "hi"); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_FALSE, "wrong return val\n"); - } + ok( r == MSICONDITION_FALSE, "wrong return val\n");
MsiSetProperty(hpkg, "one", ""); MsiSetProperty(hpkg, "two", "there"); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_FALSE, "wrong return val\n"); - } + ok( r == MSICONDITION_FALSE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "there"); MsiSetProperty(hpkg, "two", ""); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_TRUE, "wrong return val\n"); - } + ok( r == MSICONDITION_TRUE, "wrong return val\n");
MsiSetProperty(hpkg, "one", ""); MsiSetProperty(hpkg, "two", ""); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_FALSE, "wrong return val\n"); - } + ok( r == MSICONDITION_FALSE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "1234"); MsiSetProperty(hpkg, "two", "4"); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_FALSE, "wrong return val\n"); - } + ok( r == MSICONDITION_FALSE, "wrong return val\n");
MsiSetProperty(hpkg, "one", "one 1234"); MsiSetProperty(hpkg, "two", "4"); r = MsiEvaluateCondition(hpkg, "one >> two"); - todo_wine - { - ok( r == MSICONDITION_TRUE, "wrong return val\n"); - } + ok( r == MSICONDITION_TRUE, "wrong return val\n");
MsiCloseHandle( hpkg ); DeleteFile(msifile);