Allocate the correct nr of bytes for lpszCookies in HTTP_HttpOpenRequestA.
[wine.git] / dlls / msi / cond.y
blob8e7013636c934f6de857e86449ea13c2ee8c7111
1 %{
3 /*
4 * Implementation of the Microsoft Installer (msi.dll)
6 * Copyright 2003 Mike McCormack for CodeWeavers
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "config.h"
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <stdlib.h>
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
34 #include "msi.h"
35 #include "msiquery.h"
37 #define YYLEX_PARAM info
38 #define YYPARSE_PARAM info
40 static int COND_error(char *str);
42 WINE_DEFAULT_DEBUG_CHANNEL(msi);
44 typedef struct tag_yyinput
46 MSIHANDLE hInstall;
47 LPCWSTR str;
48 INT n;
49 INT start;
50 MSICONDITION result;
51 } COND_input;
53 static LPWSTR COND_GetString( COND_input *info );
54 static int COND_lex( void *COND_lval, COND_input *info);
56 typedef INT (*comp_int)(INT a, INT b);
58 static INT comp_lt(INT a, INT b);
59 static INT comp_gt(INT a, INT b);
60 static INT comp_le(INT a, INT b);
61 static INT comp_ge(INT a, INT b);
62 static INT comp_eq(INT a, INT b);
63 static INT comp_ne(INT a, INT b);
67 %pure-parser
69 %union
71 LPWSTR string;
72 INT value;
73 comp_int fn_comp_int;
76 %token COND_SPACE COND_EOF COND_SPACE
77 %token COND_OR COND_AND COND_NOT
78 %token COND_LT COND_GT COND_LE COND_GE COND_EQ COND_NE
79 %token COND_LPAR COND_RPAR
80 %token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM
81 %token COND_IDENT COND_NUMBER
83 %nonassoc COND_EOF COND_ERROR
85 %type <value> expression boolean_term boolean_factor term value symbol integer
86 %type <string> identifier
87 %type <fn_comp_int> comparison_op
91 condition:
92 expression
94 COND_input* cond = (COND_input*) info;
95 cond->result = $1;
99 expression:
100 boolean_term
102 $$ = $1;
104 | boolean_term COND_OR expression
106 $$ = $1 || $3;
110 boolean_term:
111 boolean_factor
113 $$ = $1;
115 | boolean_factor COND_AND term
117 $$ = $1 && $3;
121 boolean_factor:
122 term
124 $$ = $1;
126 | COND_NOT term
128 $$ = ! $2;
132 term:
133 value
135 $$ = $1;
137 | value comparison_op value
139 $$ = $2( $1, $3 );
141 | COND_LPAR expression COND_RPAR
143 $$ = $2;
147 comparison_op:
148 COND_LT
150 $$ = comp_lt;
152 | COND_GT
154 $$ = comp_gt;
156 | COND_LE
158 $$ = comp_le;
160 | COND_GE
162 $$ = comp_ge;
164 | COND_EQ
166 $$ = comp_eq;
168 | COND_NE
170 $$ = comp_ne;
174 value:
175 symbol
177 $$ = $1;
179 | integer
181 $$ = $1;
185 symbol:
186 COND_DOLLARS identifier
188 COND_input* cond = (COND_input*) info;
189 INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
191 MsiGetComponentStateW(cond->hInstall, $2, &install, &action );
192 $$ = action;
194 | COND_QUESTION identifier
196 COND_input* cond = (COND_input*) info;
197 INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
199 MsiGetComponentStateW(cond->hInstall, $2, &install, &action );
200 $$ = install;
202 | COND_AMPER identifier
204 COND_input* cond = (COND_input*) info;
205 INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
207 MsiGetFeatureStateW(cond->hInstall, $2, &install, &action );
208 $$ = action;
210 | COND_EXCLAM identifier
212 COND_input* cond = (COND_input*) info;
213 INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
215 MsiGetFeatureStateW(cond->hInstall, $2, &install, &action );
216 $$ = install;
220 identifier:
221 COND_IDENT
223 COND_input* cond = (COND_input*) info;
224 $$ = COND_GetString(cond);
225 if( !$$ )
226 YYABORT;
228 | COND_PERCENT identifier
230 UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
231 if( len++ )
233 $$ = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
234 if( $$ )
235 GetEnvironmentVariableW( $2, $$, len );
237 HeapFree( GetProcessHeap(), 0, $2 );
241 integer:
242 COND_NUMBER
244 COND_input* cond = (COND_input*) info;
245 LPWSTR szNum = COND_GetString(cond);
246 if( !szNum )
247 YYABORT;
248 $$ = atoiW( szNum );
249 HeapFree( GetProcessHeap(), 0, szNum );
255 static INT comp_lt(INT a, INT b)
257 return (a < b);
260 static INT comp_gt(INT a, INT b)
262 return (a > b);
265 static INT comp_le(INT a, INT b)
267 return (a <= b);
270 static INT comp_ge(INT a, INT b)
272 return (a >= b);
275 static INT comp_eq(INT a, INT b)
277 return (a == b);
280 static INT comp_ne(INT a, INT b)
282 return (a != b);
286 static int COND_IsAlpha( WCHAR x )
288 return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
289 ( ( x >= 'a' ) && ( x <= 'z' ) ) );
292 static int COND_IsNumber( WCHAR x )
294 return( ( x >= '0' ) && ( x <= '9' ) );
297 static int COND_IsIdent( WCHAR x )
299 return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) );
302 static int COND_lex( void *COND_lval, COND_input *cond )
304 WCHAR ch;
306 cond->start = cond->n;
307 ch = cond->str[cond->n];
308 if( !ch )
309 return COND_EOF;
310 cond->n++;
312 switch( ch )
314 case '(': return COND_LPAR;
315 case ')': return COND_RPAR;
316 case '&': return COND_AMPER;
317 case '!': return COND_EXCLAM;
318 case '$': return COND_DOLLARS;
319 case '?': return COND_QUESTION;
320 case '%': return COND_PERCENT;
321 case ' ': return COND_SPACE;
324 if( COND_IsAlpha( ch ) )
326 ch = cond->str[cond->n];
327 while( COND_IsIdent( ch ) )
328 ch = cond->str[cond->n++];
329 return COND_IDENT;
332 if( COND_IsNumber( ch ) )
334 ch = cond->str[cond->n];
335 while( COND_IsNumber( ch ) )
336 ch = cond->str[cond->n++];
337 return COND_NUMBER;
340 return COND_ERROR;
343 static LPWSTR COND_GetString( COND_input *cond )
345 int len;
346 LPWSTR str;
348 len = cond->n - cond->start;
349 str = HeapAlloc( GetProcessHeap(), 0, (len+1) * sizeof (WCHAR) );
350 if( str )
351 strncpyW( str, &cond->str[cond->start], len );
352 return str;
355 static int COND_error(char *str)
357 return 0;
360 MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
362 COND_input cond;
363 MSICONDITION r;
365 cond.hInstall = hInstall;
366 cond.str = szCondition;
367 cond.n = 0;
368 cond.start = 0;
369 cond.result = MSICONDITION_ERROR;
371 if( !COND_parse( &cond ) )
372 r = cond.result;
373 else
374 r = MSICONDITION_ERROR;
376 return r;
379 MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
381 LPWSTR szwCond = NULL;
382 MSICONDITION r;
384 if( szCondition )
386 UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 );
387 szwCond = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
388 MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len );
391 r = MsiEvaluateConditionW( hInstall, szwCond );
393 if( szwCond )
394 HeapFree( GetProcessHeap(), 0, szwCond );
396 return r;