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