msi [2/2]: Add handling for MsiEvaluateCondition's substring operators

James Hawkins truiken at gmail.com
Mon Aug 21 18:27:38 CDT 2006


Hi,

Changelog
* Add handling for MsiEvaluateCondition's substring operators.
* Move the COND_GT check after COND_RHS, else RHS will always be GT.

 dlls/msi/cond.y          |   67 ++++++++++++++++++++++++++++++++++-------
 dlls/msi/tests/package.c |   75 +++++++++-------------------------------------
 2 files changed, 70 insertions(+), 72 deletions(-)

-- 
James Hawkins
-------------- next part --------------
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);
-- 
1.4.2


More information about the wine-patches mailing list