MSI: start implemention of MsiEvaluateConditionA/W

Mike McCormack mike at codeweavers.com
Mon Mar 15 08:52:29 CST 2004


ChangeLog:
* start implement of MsiEvaluateConditionA/W

-------------- next part --------------
? dlls/msi/cond.y
Index: dlls/msi/.cvsignore
===================================================================
RCS file: /home/wine/wine/dlls/msi/.cvsignore,v
retrieving revision 1.1
diff -u -r1.1 .cvsignore
--- dlls/msi/.cvsignore	13 Aug 2003 01:27:48 -0000	1.1
+++ dlls/msi/.cvsignore	15 Mar 2004 14:01:37 -0000
@@ -2,5 +2,7 @@
 msi.dll.dbg.c
 msi.spec.c
 msi.spec.def
-y.tab.c
-y.tab.h
+cond.tab.c
+cond.tab.h
+sql.tab.c
+sql.tab.h
Index: dlls/msi/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/msi/Makefile.in,v
retrieving revision 1.4
diff -u -r1.4 Makefile.in
--- dlls/msi/Makefile.in	27 Jan 2004 00:11:16 -0000	1.4
+++ dlls/msi/Makefile.in	15 Mar 2004 14:01:37 -0000
@@ -21,18 +21,23 @@
 
 #RC_SRCS= msi_rc.rc
 
-EXTRA_SRCS = sql.y 
-EXTRA_OBJS = y.tab.o
+EXTRA_SRCS = sql.y cond.y
+EXTRA_OBJS = sql.tab.o cond.tab.o
 
 @MAKE_DLL_RULES@
 
-y.tab.c y.tab.h: sql.y
-	$(YACC) -d -t $(SRCDIR)/sql.y
+sql.tab.c sql.tab.h: sql.y
+	$(YACC) -p SQL_ -b sql -d -t $(SRCDIR)/sql.y
+
+cond.tab.c cond.tab.h: cond.y
+	$(YACC) -p COND_ -b cond -d -t $(SRCDIR)/cond.y
 
 # hack to allow parallel make
-y.tab.h: y.tab.c
-y.tab.o: y.tab.h
+sql.tab.h: sql.tab.c
+sql.tab.o: sql.tab.h
+cond.tab.h: cond.tab.c
+cond.tab.o: cond.tab.h
 
-tokenize.o: y.tab.h
+tokenize.o: sql.tab.h
 
 ### Dependencies:
Index: dlls/msi/msi.spec
===================================================================
RCS file: /home/wine/wine/dlls/msi/msi.spec,v
retrieving revision 1.8
diff -u -r1.8 msi.spec
--- dlls/msi/msi.spec	17 Feb 2004 21:05:44 -0000	1.8
+++ dlls/msi/msi.spec	15 Mar 2004 14:01:38 -0000
@@ -43,8 +43,8 @@
 43 stdcall MsiEnumFeaturesW(wstr long ptr ptr)
 44 stdcall MsiEnumProductsA(long ptr)
 45 stdcall MsiEnumProductsW(long ptr)
-46 stub MsiEvaluateConditionA
-47 stub MsiEvaluateConditionW
+46 stdcall MsiEvaluateConditionA(long str)
+47 stdcall MsiEvaluateConditionW(long wstr)
 48 stub MsiGetLastErrorRecord
 49 stub MsiGetActiveDatabase
 50 stdcall MsiGetComponentStateA(long str ptr ptr)
Index: dlls/msi/sql.y
===================================================================
RCS file: /home/wine/wine/dlls/msi/sql.y,v
retrieving revision 1.4
diff -u -r1.4 sql.y
--- dlls/msi/sql.y	14 Oct 2003 01:19:28 -0000	1.4
+++ dlls/msi/sql.y	15 Mar 2004 14:01:38 -0000
@@ -36,17 +36,17 @@
 #define YYLEX_PARAM info
 #define YYPARSE_PARAM info
 
-extern int yyerror(const char *str);
+extern int SQL_error(const char *str);
 
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
 
-typedef struct tag_yyinput
+typedef struct tag_SQL_input
 {
     MSIDATABASE *db;
     LPCWSTR command;
     DWORD n, len;
     MSIVIEW **view;  /* view structure for the resulting query */
-} yyinput;
+} SQL_input;
 
 struct string_list
 {
@@ -54,9 +54,9 @@
     struct string_list *next;
 };
 
-static LPWSTR yygetstring( yyinput *info );
-static INT yygetint( yyinput *sql );
-static int yylex( void *yylval, yyinput *info);
+static LPWSTR SQL_getstring( SQL_input *info );
+static INT SQL_getint( SQL_input *sql );
+static int SQL_lex( void *SQL_lval, SQL_input *info);
 
 static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in, 
                         struct string_list *columns );
@@ -131,7 +131,7 @@
 oneselect:
     unorderedsel TK_ORDER TK_BY selcollist
         {
-            yyinput* sql = (yyinput*) info;
+            SQL_input* sql = (SQL_input*) info;
 
             if( !$1 )
                 YYABORT;
@@ -142,7 +142,7 @@
         }
   | unorderedsel
         {
-            yyinput* sql = (yyinput*) info;
+            SQL_input* sql = (SQL_input*) info;
 
             *sql->view = $1;
         }
@@ -151,7 +151,7 @@
 unorderedsel:
     TK_SELECT selcollist from 
         {
-            yyinput* sql = (yyinput*) info;
+            SQL_input* sql = (SQL_input*) info;
             if( !$3 )
                 YYABORT;
             if( $2 )
@@ -161,7 +161,7 @@
         }
   | TK_SELECT TK_DISTINCT selcollist from 
         {
-            yyinput* sql = (yyinput*) info;
+            SQL_input* sql = (SQL_input*) info;
             MSIVIEW *view = $4;
 
             if( !view )
@@ -208,7 +208,7 @@
 from:
     TK_FROM table
         { 
-            yyinput* sql = (yyinput*) info;
+            SQL_input* sql = (SQL_input*) info;
 
             $$ = NULL;
             TRACE("From table: %s\n",debugstr_w($2));
@@ -216,7 +216,7 @@
         }
   | TK_FROM table TK_WHERE expr
         { 
-            yyinput* sql = (yyinput*) info;
+            SQL_input* sql = (SQL_input*) info;
             MSIVIEW *view = NULL;
             UINT r;
 
@@ -293,8 +293,8 @@
         }
   | TK_INTEGER
         {
-            yyinput* sql = (yyinput*) info;
-            $$ = EXPR_ival( yygetint(sql) );
+            SQL_input* sql = (SQL_input*) info;
+            $$ = EXPR_ival( SQL_getint(sql) );
         }
   | TK_STRING
         {
@@ -330,19 +330,19 @@
 string_or_id:
     TK_ID
         {
-            yyinput* sql = (yyinput*) info;
-            $$ = yygetstring(sql);
+            SQL_input* sql = (SQL_input*) info;
+            $$ = SQL_getstring(sql);
         }
   | TK_STRING
         {
-            yyinput* sql = (yyinput*) info;
-            $$ = yygetstring(sql);
+            SQL_input* sql = (SQL_input*) info;
+            $$ = SQL_getstring(sql);
         }
     ;
 
 %%
 
-int yylex( void *yylval, yyinput *sql)
+int SQL_lex( void *SQL_lval, SQL_input *sql)
 {
     int token;
 
@@ -364,7 +364,7 @@
     return token;
 }
 
-LPWSTR yygetstring( yyinput *sql )
+LPWSTR SQL_getstring( SQL_input *sql )
 {
     LPCWSTR p = &sql->command[sql->n];
     LPWSTR str;
@@ -385,14 +385,14 @@
     return str;
 }
 
-INT yygetint( yyinput *sql )
+INT SQL_getint( SQL_input *sql )
 {
     LPCWSTR p = &sql->command[sql->n];
 
     return atoiW( p );
 }
 
-int yyerror(const char *str)
+int SQL_error(const char *str)
 {
     return 0;
 }
@@ -493,7 +493,7 @@
 
 UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview )
 {
-    yyinput sql;
+    SQL_input sql;
     int r;
 
     *phview = NULL;
@@ -504,7 +504,7 @@
     sql.len = 0;
     sql.view = phview;
 
-    r = yyparse(&sql);
+    r = SQL_parse(&sql);
 
     TRACE("Parse returned %d\n", r);
     if( r )
Index: dlls/msi/tokenize.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/tokenize.c,v
retrieving revision 1.3
diff -u -r1.3 tokenize.c
--- dlls/msi/tokenize.c	30 Oct 2003 22:46:59 -0000	1.3
+++ dlls/msi/tokenize.c	15 Mar 2004 14:01:38 -0000
@@ -25,7 +25,7 @@
 #include "wine/debug.h"
 #include "winnls.h"
 #include "query.h"
-#include "y.tab.h"
+#include "sql.tab.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
 
--- /dev/null	1994-07-18 08:46:18.000000000 +0900
+++ dlls/msi/cond.y	2004-03-15 23:32:25.000000000 +0900
@@ -0,0 +1,378 @@
+%{
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "msi.h"
+#include "msiquery.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+static int COND_error(char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_yyinput
+{
+    MSIHANDLE hInstall;
+    LPCWSTR str;
+    INT    n;
+    INT    start;
+    MSICONDITION result;
+} COND_input;
+
+static LPWSTR COND_GetString( COND_input *info );
+static int COND_lex( void *COND_lval, COND_input *info);
+
+typedef INT (*comp_int)(INT a, INT b);
+
+static INT comp_lt(INT a, INT b);
+static INT comp_gt(INT a, INT b);
+static INT comp_le(INT a, INT b);
+static INT comp_ge(INT a, INT b);
+static INT comp_eq(INT a, INT b);
+static INT comp_ne(INT a, INT b);
+
+%}
+
+%pure-parser
+
+%union
+{
+    LPWSTR    string;
+    INT       value;
+    comp_int  fn_comp_int;
+}
+
+%token COND_SPACE COND_EOF COND_SPACE
+%token COND_OR COND_AND COND_NOT
+%token COND_LT COND_GT COND_LE COND_GE COND_EQ COND_NE
+%token COND_LPAR COND_RPAR
+%token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM
+%token COND_IDENT COND_NUMBER
+
+%nonassoc COND_EOF COND_ERROR
+
+%type <value> expression, boolean_term, boolean_factor, term, value, symbol, integer
+%type <string> identifier
+%type <fn_comp_int> comparison_op
+
+%%
+
+condition:
+    expression
+        {
+            COND_input* cond = (COND_input*) info;
+            cond->result = $1;
+        }
+    ;
+
+expression:
+    boolean_term 
+        {
+            $$ = $1;
+        }
+  | boolean_term COND_OR expression
+        {
+            $$ = $1 || $3;
+        }
+    ;
+
+boolean_term:
+    boolean_factor
+        {
+            $$ = $1;
+        }
+  | boolean_factor COND_AND term
+        {
+            $$ = $1 && $3;
+        }
+    ;
+
+boolean_factor:
+    term
+        {
+            $$ = $1;
+        }
+  | COND_NOT term
+        {
+            $$ = ! $2;
+        }
+    ;
+
+term:
+    value
+        {
+            $$ = $1;
+        }
+  | value comparison_op value
+        {
+            $$ = $2( $1, $3 );
+        }
+  | COND_LPAR expression COND_RPAR
+        {
+            $$ = $2;
+        }
+    ;
+
+comparison_op:
+    COND_LT
+        {
+            $$ = comp_lt;
+        }
+  | COND_GT
+        {
+            $$ = comp_gt;
+        }
+  | COND_LE
+        {
+            $$ = comp_le;
+        }
+  | COND_GE
+        {
+            $$ = comp_ge;
+        }
+  | COND_EQ
+        {
+            $$ = comp_eq;
+        }
+  | COND_NE
+        {
+            $$ = comp_ne;
+        }
+    ;
+
+value:
+    symbol
+        {
+            $$ = $1;
+        }
+  | integer
+        {
+            $$ = $1;
+        }
+    ;
+
+symbol:
+    COND_DOLLARS identifier
+        {
+            COND_input* cond = (COND_input*) info;
+            INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+      
+            MsiGetComponentStateW(cond->hInstall, $2, &install, &action );
+            $$ = action;
+        }
+  | COND_QUESTION identifier
+        {
+            COND_input* cond = (COND_input*) info;
+            INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+      
+            MsiGetComponentStateW(cond->hInstall, $2, &install, &action );
+            $$ = install;
+        }
+  | COND_AMPER identifier
+        {
+            COND_input* cond = (COND_input*) info;
+            INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+      
+            MsiGetFeatureStateW(cond->hInstall, $2, &install, &action );
+            $$ = action;
+        }
+  | COND_EXCLAM identifier
+        {
+            COND_input* cond = (COND_input*) info;
+            INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+      
+            MsiGetFeatureStateW(cond->hInstall, $2, &install, &action );
+            $$ = install;
+        }
+    ;
+
+identifier:
+    COND_IDENT
+        {
+            COND_input* cond = (COND_input*) info;
+            $$ = COND_GetString(cond);
+            if( !$$ )
+                YYABORT;
+        }
+  | COND_PERCENT identifier
+        {
+            UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
+            if( len++ )
+            {
+                $$ = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
+                if( $$ )
+                    GetEnvironmentVariableW( $2, $$, len );
+            }
+            HeapFree( GetProcessHeap(), 0, $2 );
+        }
+    ;
+
+integer:
+    COND_NUMBER
+        {
+            COND_input* cond = (COND_input*) info;
+            LPWSTR szNum = COND_GetString(cond);
+            if( !szNum )
+                YYABORT;
+            $$ = atoiW( szNum );
+            HeapFree( GetProcessHeap(), 0, szNum );
+        }
+    ;
+
+%%
+
+static INT comp_lt(INT a, INT b)
+{
+    return (a < b);
+}
+
+static INT comp_gt(INT a, INT b)
+{
+    return (a > b);
+}
+
+static INT comp_le(INT a, INT b)
+{
+    return (a <= b);
+}
+
+static INT comp_ge(INT a, INT b)
+{
+    return (a >= b);
+}
+
+static INT comp_eq(INT a, INT b)
+{
+    return (a == b);
+}
+
+static INT comp_ne(INT a, INT b)
+{
+    return (a != b);
+}
+
+
+static int COND_IsAlpha( WCHAR x )
+{
+    return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
+            ( ( x >= 'a' ) && ( x <= 'z' ) ) );
+}
+
+static int COND_IsNumber( WCHAR x )
+{
+    return( ( x >= '0' ) && ( x <= '9' ) );
+}
+
+static int COND_IsIdent( WCHAR x )
+{
+    return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) );
+}
+
+static int COND_lex( void *COND_lval, COND_input *cond )
+{
+    WCHAR ch;
+
+    cond->start = cond->n;
+    ch = cond->str[cond->n];
+    if( !ch )
+        return COND_EOF;
+    cond->n++;
+
+    switch( ch )
+    {
+    case '(': return COND_LPAR;
+    case ')': return COND_RPAR;
+    case '&': return COND_AMPER;
+    case '!': return COND_EXCLAM;
+    case '$': return COND_DOLLARS;
+    case '?': return COND_QUESTION;
+    case '%': return COND_PERCENT;
+    case ' ': return COND_SPACE;
+    }
+
+    if( COND_IsAlpha( ch ) )
+    {
+        ch = cond->str[cond->n];
+        while( COND_IsIdent( ch ) )
+            ch = cond->str[cond->n++];
+        return COND_IDENT;
+    }
+
+    if( COND_IsNumber( ch ) )
+    {
+        ch = cond->str[cond->n];
+        while( COND_IsNumber( ch ) )
+            ch = cond->str[cond->n++];
+        return COND_NUMBER;
+    }
+
+    return COND_ERROR;
+}
+
+static LPWSTR COND_GetString( COND_input *cond )
+{
+    int len;
+    LPWSTR str;
+
+    len = cond->n - cond->start;
+    str = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof (WCHAR) );
+    if( str )
+        strncpyW( str, &cond->str[cond->start], len );
+    return str;
+}
+
+static int COND_error(char *str)
+{
+    return 0;
+}
+
+MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
+{
+    COND_input cond;
+    MSICONDITION r;
+
+    cond.hInstall = hInstall;
+    cond.str   = szCondition;
+    cond.n     = 0;
+    cond.start = 0;
+    cond.result = MSICONDITION_ERROR;
+    
+    if( !COND_parse( &cond ) )
+        r = cond.result;
+    else
+        r = MSICONDITION_ERROR;
+
+    return r;
+}
+
+MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
+{
+    LPWSTR szwCond = NULL;
+    MSICONDITION r;
+
+    if( szCondition )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 );
+        szwCond = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len );
+    }
+
+    r = MsiEvaluateConditionW( hInstall, szwCond );
+
+    if( szwCond )
+        HeapFree( GetProcessHeap(), 0, szwCond );
+
+    return r;
+}
+


More information about the wine-patches mailing list