Start implementation of MsiEvaluateConditionA/W.
This commit is contained in:
parent
c068f67051
commit
af54ef9ce1
|
@ -1,6 +1,8 @@
|
|||
Makefile
|
||||
cond.tab.c
|
||||
cond.tab.h
|
||||
msi.dll.dbg.c
|
||||
msi.spec.c
|
||||
msi.spec.def
|
||||
y.tab.c
|
||||
y.tab.h
|
||||
sql.tab.c
|
||||
sql.tab.h
|
||||
|
|
|
@ -21,18 +21,23 @@ C_SRCS = \
|
|||
|
||||
#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
|
||||
$(BISON) -p SQL_ -d $(SRCDIR)/sql.y
|
||||
|
||||
cond.tab.c cond.tab.h: cond.y
|
||||
$(BISON) -p COND_ -d $(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:
|
||||
|
|
|
@ -0,0 +1,397 @@
|
|||
%{
|
||||
|
||||
/*
|
||||
* Implementation of the Microsoft Installer (msi.dll)
|
||||
*
|
||||
* Copyright 2003 Mike McCormack for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|||
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 @@ static struct expr * EXPR_sval( LPWSTR string );
|
|||
oneselect:
|
||||
unorderedsel TK_ORDER TK_BY selcollist
|
||||
{
|
||||
yyinput* sql = (yyinput*) info;
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
|
||||
if( !$1 )
|
||||
YYABORT;
|
||||
|
@ -142,7 +142,7 @@ oneselect:
|
|||
}
|
||||
| unorderedsel
|
||||
{
|
||||
yyinput* sql = (yyinput*) info;
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
|
||||
*sql->view = $1;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ oneselect:
|
|||
unorderedsel:
|
||||
TK_SELECT selcollist from
|
||||
{
|
||||
yyinput* sql = (yyinput*) info;
|
||||
SQL_input* sql = (SQL_input*) info;
|
||||
if( !$3 )
|
||||
YYABORT;
|
||||
if( $2 )
|
||||
|
@ -161,7 +161,7 @@ unorderedsel:
|
|||
}
|
||||
| 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 @@ selcollist:
|
|||
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 @@ from:
|
|||
}
|
||||
| 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 @@ val:
|
|||
}
|
||||
| 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 @@ table:
|
|||
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 @@ int yylex( void *yylval, yyinput *sql)
|
|||
return token;
|
||||
}
|
||||
|
||||
LPWSTR yygetstring( yyinput *sql )
|
||||
LPWSTR SQL_getstring( SQL_input *sql )
|
||||
{
|
||||
LPCWSTR p = &sql->command[sql->n];
|
||||
LPWSTR str;
|
||||
|
@ -385,14 +385,14 @@ LPWSTR yygetstring( yyinput *sql )
|
|||
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 @@ static struct expr * EXPR_sval( LPWSTR string )
|
|||
|
||||
UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview )
|
||||
{
|
||||
yyinput sql;
|
||||
SQL_input sql;
|
||||
int r;
|
||||
|
||||
*phview = NULL;
|
||||
|
@ -504,7 +504,7 @@ UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview )
|
|||
sql.len = 0;
|
||||
sql.view = phview;
|
||||
|
||||
r = yyparse(&sql);
|
||||
r = SQL_parse(&sql);
|
||||
|
||||
TRACE("Parse returned %d\n", r);
|
||||
if( r )
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue