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
31 #include "wine/debug.h"
32 #include "wine/unicode.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
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
);
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
94 COND_input
* cond
= (COND_input
*) info
;
104 | boolean_term COND_OR expression
115 | boolean_factor COND_AND term
137 | value comparison_op value
141 | COND_LPAR expression COND_RPAR
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
);
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
);
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
);
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
);
223 COND_input
* cond
= (COND_input
*) info
;
224 $$
= COND_GetString
(cond
);
228 | COND_PERCENT identifier
230 UINT len
= GetEnvironmentVariableW
( $2, NULL
, 0 );
233 $$
= HeapAlloc
( GetProcessHeap
(), 0, len
*sizeof
(WCHAR
) );
235 GetEnvironmentVariableW
( $2, $$
, len
);
237 HeapFree
( GetProcessHeap
(), 0, $2 );
244 COND_input
* cond
= (COND_input
*) info
;
245 LPWSTR szNum
= COND_GetString
(cond
);
249 HeapFree
( GetProcessHeap
(), 0, szNum
);
255 static INT comp_lt
(INT a
, INT b
)
260 static INT comp_gt
(INT a
, INT b
)
265 static INT comp_le
(INT a
, INT b
)
270 static INT comp_ge
(INT a
, INT b
)
275 static INT comp_eq
(INT a
, INT b
)
280 static INT comp_ne
(INT a
, INT 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
)
306 cond
->start
= cond
->n
;
307 ch
= cond
->str
[cond
->n
];
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
++];
332 if
( COND_IsNumber
( ch
) )
334 ch
= cond
->str
[cond
->n
];
335 while
( COND_IsNumber
( ch
) )
336 ch
= cond
->str
[cond
->n
++];
343 static LPWSTR COND_GetString
( COND_input
*cond
)
348 len
= cond
->n
- cond
->start
;
349 str
= HeapAlloc
( GetProcessHeap
(), 0, (len
+1) * sizeof
(WCHAR
) );
351 strncpyW
( str
, &cond
->str
[cond
->start
], len
);
355 static int COND_error
(char *str
)
360 MSICONDITION WINAPI MsiEvaluateConditionW
( MSIHANDLE hInstall
, LPCWSTR szCondition
)
365 cond.hInstall
= hInstall
;
366 cond.str
= szCondition
;
369 cond.result
= MSICONDITION_ERROR
;
371 if
( !COND_parse
( &cond
) )
374 r
= MSICONDITION_ERROR
;
379 MSICONDITION WINAPI MsiEvaluateConditionA
( MSIHANDLE hInstall
, LPCSTR szCondition
)
381 LPWSTR szwCond
= NULL
;
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
);
394 HeapFree
( GetProcessHeap
(), 0, szwCond
);