Start implementation of MsiEvaluateConditionA/W.

This commit is contained in:
Mike McCormack 2004-03-16 03:23:43 +00:00 committed by Alexandre Julliard
parent c068f67051
commit af54ef9ce1
6 changed files with 440 additions and 36 deletions

View File

@ -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

View File

@ -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:

397
dlls/msi/cond.y Normal file
View File

@ -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;
}

View File

@ -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)

View File

@ -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 )

View File

@ -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);