ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cond.tab.c
Go to the documentation of this file.
00001 
00002 /* A Bison parser, made by GNU Bison 2.4.1.  */
00003 
00004 /* Skeleton implementation for Bison's Yacc-like parsers in C
00005    
00006       Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
00007    Free Software Foundation, Inc.
00008    
00009    This program is free software: you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation, either version 3 of the License, or
00012    (at your option) any later version.
00013    
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018    
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 /* As a special exception, you may create a larger work that contains
00023    part or all of the Bison parser skeleton and distribute that work
00024    under terms of your choice, so long as that work isn't itself a
00025    parser generator using the skeleton or a modified version thereof
00026    as a parser skeleton.  Alternatively, if you modify or redistribute
00027    the parser skeleton itself, you may (at your option) remove this
00028    special exception, which will cause the skeleton and the resulting
00029    Bison output files to be licensed under the GNU General Public
00030    License without this special exception.
00031    
00032    This special exception was added by the Free Software Foundation in
00033    version 2.2 of Bison.  */
00034 
00035 /* C LALR(1) parser skeleton written by Richard Stallman, by
00036    simplifying the original so-called "semantic" parser.  */
00037 
00038 /* All symbols defined below should begin with yy or YY, to avoid
00039    infringing on user name space.  This should be done even for local
00040    variables, as they might otherwise be expanded by user macros.
00041    There are some unavoidable exceptions within include files to
00042    define necessary library symbols; they are noted "INFRINGES ON
00043    USER NAME SPACE" below.  */
00044 
00045 /* Identify Bison output.  */
00046 #define YYBISON 1
00047 
00048 /* Bison version.  */
00049 #define YYBISON_VERSION "2.4.1"
00050 
00051 /* Skeleton name.  */
00052 #define YYSKELETON_NAME "yacc.c"
00053 
00054 /* Pure parsers.  */
00055 #define YYPURE 1
00056 
00057 /* Push parsers.  */
00058 #define YYPUSH 0
00059 
00060 /* Pull parsers.  */
00061 #define YYPULL 1
00062 
00063 /* Using locations.  */
00064 #define YYLSP_NEEDED 0
00065 
00066 /* Substitute the variable and function names.  */
00067 #define yyparse         cond_parse
00068 #define yylex           cond_lex
00069 #define yyerror         cond_error
00070 #define yylval          cond_lval
00071 #define yychar          cond_char
00072 #define yydebug         cond_debug
00073 #define yynerrs         cond_nerrs
00074 
00075 
00076 /* Copy the first part of user declarations.  */
00077 
00078 /* Line 189 of yacc.c  */
00079 #line 1 "cond.y"
00080 
00081 
00082 /*
00083  * Implementation of the Microsoft Installer (msi.dll)
00084  *
00085  * Copyright 2003 Mike McCormack for CodeWeavers
00086  *
00087  * This library is free software; you can redistribute it and/or
00088  * modify it under the terms of the GNU Lesser General Public
00089  * License as published by the Free Software Foundation; either
00090  * version 2.1 of the License, or (at your option) any later version.
00091  *
00092  * This library is distributed in the hope that it will be useful,
00093  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00094  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00095  * Lesser General Public License for more details.
00096  *
00097  * You should have received a copy of the GNU Lesser General Public
00098  * License along with this library; if not, write to the Free Software
00099  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00100  */
00101 
00102 #define COBJMACROS
00103 
00104 #include "config.h"
00105 
00106 #include <stdarg.h>
00107 #include <stdio.h>
00108 #include <stdlib.h>
00109 
00110 #include "windef.h"
00111 #include "winbase.h"
00112 #include "winuser.h"
00113 #include "msi.h"
00114 #include "msiquery.h"
00115 #include "objbase.h"
00116 #include "oleauto.h"
00117 
00118 #include "msipriv.h"
00119 #include "msiserver.h"
00120 #include "wine/debug.h"
00121 #include "wine/unicode.h"
00122 #include "wine/list.h"
00123 
00124 #define YYLEX_PARAM info
00125 #define YYPARSE_PARAM info
00126 
00127 static int cond_error(const char *str);
00128 
00129 WINE_DEFAULT_DEBUG_CHANNEL(msi);
00130 
00131 typedef struct tag_yyinput
00132 {
00133     MSIPACKAGE *package;
00134     LPCWSTR str;
00135     INT    n;
00136     MSICONDITION result;
00137     struct list mem;
00138 } COND_input;
00139 
00140 struct cond_str {
00141     LPCWSTR data;
00142     INT len;
00143 };
00144 
00145 static LPWSTR COND_GetString( COND_input *info, const struct cond_str *str );
00146 static LPWSTR COND_GetLiteral( COND_input *info, const struct cond_str *str );
00147 static int cond_lex( void *COND_lval, COND_input *info);
00148 
00149 static void *cond_alloc( COND_input *cond, unsigned int sz );
00150 static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz );
00151 static void cond_free( void *ptr );
00152 
00153 static INT compare_int( INT a, INT operator, INT b );
00154 static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert );
00155 
00156 static INT compare_and_free_strings( LPWSTR a, INT op, LPWSTR b, BOOL convert )
00157 {
00158     INT r;
00159 
00160     r = compare_string( a, op, b, convert );
00161     cond_free( a );
00162     cond_free( b );
00163     return r;
00164 }
00165 
00166 static BOOL num_from_prop( LPCWSTR p, INT *val )
00167 {
00168     INT ret = 0, sign = 1;
00169 
00170     if (!p)
00171         return FALSE;
00172     if (*p == '-')
00173     {
00174         sign = -1;
00175         p++;
00176     }
00177     if (!*p)
00178         return FALSE;
00179     while (*p)
00180     {
00181         if( *p < '0' || *p > '9' )
00182             return FALSE;
00183         ret = ret*10 + (*p - '0');
00184         p++;
00185     }
00186     *val = ret*sign;
00187     return TRUE;
00188 }
00189 
00190 
00191 
00192 /* Line 189 of yacc.c  */
00193 #line 194 "cond.tab.c"
00194 
00195 /* Enabling traces.  */
00196 #ifndef YYDEBUG
00197 # define YYDEBUG 0
00198 #endif
00199 
00200 /* Enabling verbose error messages.  */
00201 #ifdef YYERROR_VERBOSE
00202 # undef YYERROR_VERBOSE
00203 # define YYERROR_VERBOSE 1
00204 #else
00205 # define YYERROR_VERBOSE 0
00206 #endif
00207 
00208 /* Enabling the token table.  */
00209 #ifndef YYTOKEN_TABLE
00210 # define YYTOKEN_TABLE 0
00211 #endif
00212 
00213 
00214 /* Tokens.  */
00215 #ifndef YYTOKENTYPE
00216 # define YYTOKENTYPE
00217    /* Put the tokens into the symbol table, so that GDB and other debuggers
00218       know about them.  */
00219    enum yytokentype {
00220      COND_SPACE = 258,
00221      COND_EOF = 259,
00222      COND_OR = 260,
00223      COND_AND = 261,
00224      COND_NOT = 262,
00225      COND_XOR = 263,
00226      COND_IMP = 264,
00227      COND_EQV = 265,
00228      COND_LT = 266,
00229      COND_GT = 267,
00230      COND_EQ = 268,
00231      COND_NE = 269,
00232      COND_GE = 270,
00233      COND_LE = 271,
00234      COND_ILT = 272,
00235      COND_IGT = 273,
00236      COND_IEQ = 274,
00237      COND_INE = 275,
00238      COND_IGE = 276,
00239      COND_ILE = 277,
00240      COND_LPAR = 278,
00241      COND_RPAR = 279,
00242      COND_TILDA = 280,
00243      COND_SS = 281,
00244      COND_ISS = 282,
00245      COND_ILHS = 283,
00246      COND_IRHS = 284,
00247      COND_LHS = 285,
00248      COND_RHS = 286,
00249      COND_PERCENT = 287,
00250      COND_DOLLARS = 288,
00251      COND_QUESTION = 289,
00252      COND_AMPER = 290,
00253      COND_EXCLAM = 291,
00254      COND_IDENT = 292,
00255      COND_NUMBER = 293,
00256      COND_LITER = 294,
00257      COND_ERROR = 295
00258    };
00259 #endif
00260 
00261 
00262 
00263 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
00264 typedef union YYSTYPE
00265 {
00266 
00267 /* Line 214 of yacc.c  */
00268 #line 116 "cond.y"
00269 
00270     struct cond_str str;
00271     LPWSTR    string;
00272     INT       value;
00273 
00274 
00275 
00276 /* Line 214 of yacc.c  */
00277 #line 278 "cond.tab.c"
00278 } YYSTYPE;
00279 # define YYSTYPE_IS_TRIVIAL 1
00280 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
00281 # define YYSTYPE_IS_DECLARED 1
00282 #endif
00283 
00284 
00285 /* Copy the second part of user declarations.  */
00286 
00287 
00288 /* Line 264 of yacc.c  */
00289 #line 290 "cond.tab.c"
00290 
00291 #ifdef short
00292 # undef short
00293 #endif
00294 
00295 #ifdef YYTYPE_UINT8
00296 typedef YYTYPE_UINT8 yytype_uint8;
00297 #else
00298 typedef unsigned char yytype_uint8;
00299 #endif
00300 
00301 #ifdef YYTYPE_INT8
00302 typedef YYTYPE_INT8 yytype_int8;
00303 #elif (defined __STDC__ || defined __C99__FUNC__ \
00304      || defined __cplusplus || defined _MSC_VER)
00305 typedef signed char yytype_int8;
00306 #else
00307 typedef short int yytype_int8;
00308 #endif
00309 
00310 #ifdef YYTYPE_UINT16
00311 typedef YYTYPE_UINT16 yytype_uint16;
00312 #else
00313 typedef unsigned short int yytype_uint16;
00314 #endif
00315 
00316 #ifdef YYTYPE_INT16
00317 typedef YYTYPE_INT16 yytype_int16;
00318 #else
00319 typedef short int yytype_int16;
00320 #endif
00321 
00322 #ifndef YYSIZE_T
00323 # ifdef __SIZE_TYPE__
00324 #  define YYSIZE_T __SIZE_TYPE__
00325 # elif defined size_t
00326 #  define YYSIZE_T size_t
00327 # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
00328      || defined __cplusplus || defined _MSC_VER)
00329 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
00330 #  define YYSIZE_T size_t
00331 # else
00332 #  define YYSIZE_T unsigned int
00333 # endif
00334 #endif
00335 
00336 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
00337 
00338 #ifndef YY_
00339 # if YYENABLE_NLS
00340 #  if ENABLE_NLS
00341 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
00342 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
00343 #  endif
00344 # endif
00345 # ifndef YY_
00346 #  define YY_(msgid) msgid
00347 # endif
00348 #endif
00349 
00350 /* Suppress unused-variable warnings by "using" E.  */
00351 #if ! defined lint || defined __GNUC__
00352 # define YYUSE(e) ((void) (e))
00353 #else
00354 # define YYUSE(e) /* empty */
00355 #endif
00356 
00357 /* Identity function, used to suppress warnings about constant conditions.  */
00358 #ifndef lint
00359 # define YYID(n) (n)
00360 #else
00361 #if (defined __STDC__ || defined __C99__FUNC__ \
00362      || defined __cplusplus || defined _MSC_VER)
00363 static int
00364 YYID (int yyi)
00365 #else
00366 static int
00367 YYID (yyi)
00368     int yyi;
00369 #endif
00370 {
00371   return yyi;
00372 }
00373 #endif
00374 
00375 #if ! defined yyoverflow || YYERROR_VERBOSE
00376 
00377 /* The parser invokes alloca or malloc; define the necessary symbols.  */
00378 
00379 # ifdef YYSTACK_USE_ALLOCA
00380 #  if YYSTACK_USE_ALLOCA
00381 #   ifdef __GNUC__
00382 #    define YYSTACK_ALLOC __builtin_alloca
00383 #   elif defined __BUILTIN_VA_ARG_INCR
00384 #    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
00385 #   elif defined _AIX
00386 #    define YYSTACK_ALLOC __alloca
00387 #   elif defined _MSC_VER
00388 #    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
00389 #    define alloca _alloca
00390 #   else
00391 #    define YYSTACK_ALLOC alloca
00392 #    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
00393      || defined __cplusplus || defined _MSC_VER)
00394 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
00395 #     ifndef _STDLIB_H
00396 #      define _STDLIB_H 1
00397 #     endif
00398 #    endif
00399 #   endif
00400 #  endif
00401 # endif
00402 
00403 # ifdef YYSTACK_ALLOC
00404    /* Pacify GCC's `empty if-body' warning.  */
00405 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
00406 #  ifndef YYSTACK_ALLOC_MAXIMUM
00407     /* The OS might guarantee only one guard page at the bottom of the stack,
00408        and a page size can be as small as 4096 bytes.  So we cannot safely
00409        invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
00410        to allow for a few compiler-allocated temporary stack slots.  */
00411 #   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
00412 #  endif
00413 # else
00414 #  define YYSTACK_ALLOC YYMALLOC
00415 #  define YYSTACK_FREE YYFREE
00416 #  ifndef YYSTACK_ALLOC_MAXIMUM
00417 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
00418 #  endif
00419 #  if (defined __cplusplus && ! defined _STDLIB_H \
00420        && ! ((defined YYMALLOC || defined malloc) \
00421          && (defined YYFREE || defined free)))
00422 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
00423 #   ifndef _STDLIB_H
00424 #    define _STDLIB_H 1
00425 #   endif
00426 #  endif
00427 #  ifndef YYMALLOC
00428 #   define YYMALLOC malloc
00429 #   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
00430      || defined __cplusplus || defined _MSC_VER)
00431 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
00432 #   endif
00433 #  endif
00434 #  ifndef YYFREE
00435 #   define YYFREE free
00436 #   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
00437      || defined __cplusplus || defined _MSC_VER)
00438 void free (void *); /* INFRINGES ON USER NAME SPACE */
00439 #   endif
00440 #  endif
00441 # endif
00442 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
00443 
00444 
00445 #if (! defined yyoverflow \
00446      && (! defined __cplusplus \
00447      || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
00448 
00449 /* A type that is properly aligned for any stack member.  */
00450 union yyalloc
00451 {
00452   yytype_int16 yyss_alloc;
00453   YYSTYPE yyvs_alloc;
00454 };
00455 
00456 /* The size of the maximum gap between one aligned stack and the next.  */
00457 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
00458 
00459 /* The size of an array large to enough to hold all stacks, each with
00460    N elements.  */
00461 # define YYSTACK_BYTES(N) \
00462      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
00463       + YYSTACK_GAP_MAXIMUM)
00464 
00465 /* Copy COUNT objects from FROM to TO.  The source and destination do
00466    not overlap.  */
00467 # ifndef YYCOPY
00468 #  if defined __GNUC__ && 1 < __GNUC__
00469 #   define YYCOPY(To, From, Count) \
00470       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
00471 #  else
00472 #   define YYCOPY(To, From, Count)      \
00473       do                    \
00474     {                   \
00475       YYSIZE_T yyi;             \
00476       for (yyi = 0; yyi < (Count); yyi++)   \
00477         (To)[yyi] = (From)[yyi];        \
00478     }                   \
00479       while (YYID (0))
00480 #  endif
00481 # endif
00482 
00483 /* Relocate STACK from its old location to the new one.  The
00484    local variables YYSIZE and YYSTACKSIZE give the old and new number of
00485    elements in the stack, and YYPTR gives the new location of the
00486    stack.  Advance YYPTR to a properly aligned location for the next
00487    stack.  */
00488 # define YYSTACK_RELOCATE(Stack_alloc, Stack)               \
00489     do                                  \
00490       {                                 \
00491     YYSIZE_T yynewbytes;                        \
00492     YYCOPY (&yyptr->Stack_alloc, Stack, yysize);            \
00493     Stack = &yyptr->Stack_alloc;                    \
00494     yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
00495     yyptr += yynewbytes / sizeof (*yyptr);              \
00496       }                                 \
00497     while (YYID (0))
00498 
00499 #endif
00500 
00501 /* YYFINAL -- State number of the termination state.  */
00502 #define YYFINAL  28
00503 /* YYLAST -- Last index in YYTABLE.  */
00504 #define YYLAST   71
00505 
00506 /* YYNTOKENS -- Number of terminals.  */
00507 #define YYNTOKENS  41
00508 /* YYNNTS -- Number of nonterminals.  */
00509 #define YYNNTS  12
00510 /* YYNRULES -- Number of rules.  */
00511 #define YYNRULES  53
00512 /* YYNRULES -- Number of states.  */
00513 #define YYNSTATES  70
00514 
00515 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
00516 #define YYUNDEFTOK  2
00517 #define YYMAXUTOK   295
00518 
00519 #define YYTRANSLATE(YYX)                        \
00520   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
00521 
00522 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
00523 static const yytype_uint8 yytranslate[] =
00524 {
00525        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00526        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00527        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00528        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00529        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00530        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00531        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00532        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00533        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00534        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00535        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00536        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00537        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00538        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00539        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00540        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00541        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00542        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00543        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00544        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00545        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00546        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00547        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00548        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00549        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00550        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
00551        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
00552       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
00553       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
00554       35,    36,    37,    38,    39,    40
00555 };
00556 
00557 #if YYDEBUG
00558 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
00559    YYRHS.  */
00560 static const yytype_uint8 yyprhs[] =
00561 {
00562        0,     0,     3,     5,     6,     8,    12,    16,    20,    24,
00563       26,    30,    33,    35,    37,    41,    45,    49,    53,    57,
00564       61,    65,    69,    73,    77,    79,    81,    83,    85,    87,
00565       89,    91,    93,    95,    97,    99,   101,   103,   105,   107,
00566      109,   111,   113,   115,   117,   119,   121,   124,   127,   130,
00567      133,   135,   138,   140
00568 };
00569 
00570 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
00571 static const yytype_int8 yyrhs[] =
00572 {
00573       42,     0,    -1,    43,    -1,    -1,    44,    -1,    43,     5,
00574       44,    -1,    43,     9,    44,    -1,    43,     8,    44,    -1,
00575       43,    10,    44,    -1,    45,    -1,    44,     6,    45,    -1,
00576        7,    45,    -1,    49,    -1,    47,    -1,    49,    46,    49,
00577       -1,    50,    46,    49,    -1,    49,    46,    50,    -1,    50,
00578       46,    50,    -1,    50,    46,    48,    -1,    48,    46,    50,
00579       -1,    48,    46,    48,    -1,    48,    46,    49,    -1,    49,
00580       46,    48,    -1,    23,    43,    24,    -1,    13,    -1,    14,
00581       -1,    11,    -1,    12,    -1,    16,    -1,    15,    -1,    26,
00582       -1,    19,    -1,    20,    -1,    17,    -1,    18,    -1,    22,
00583       -1,    21,    -1,    27,    -1,    30,    -1,    31,    -1,    28,
00584       -1,    29,    -1,    50,    -1,    48,    -1,    39,    -1,    52,
00585       -1,    33,    51,    -1,    34,    51,    -1,    35,    51,    -1,
00586       36,    51,    -1,    51,    -1,    32,    51,    -1,    37,    -1,
00587       38,    -1
00588 };
00589 
00590 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
00591 static const yytype_uint16 yyrline[] =
00592 {
00593        0,   140,   140,   146,   153,   157,   161,   165,   169,   176,
00594      180,   187,   191,   195,   200,   204,   213,   222,   226,   230,
00595      234,   238,   243,   248,   256,   257,   258,   259,   260,   261,
00596      262,   263,   264,   265,   266,   267,   268,   269,   270,   271,
00597      272,   273,   277,   281,   288,   298,   302,   311,   320,   333,
00598      345,   358,   375,   385
00599 };
00600 #endif
00601 
00602 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
00603 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
00604    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
00605 static const char *const yytname[] =
00606 {
00607   "$end", "error", "$undefined", "COND_SPACE", "COND_EOF", "COND_OR",
00608   "COND_AND", "COND_NOT", "COND_XOR", "COND_IMP", "COND_EQV", "COND_LT",
00609   "COND_GT", "COND_EQ", "COND_NE", "COND_GE", "COND_LE", "COND_ILT",
00610   "COND_IGT", "COND_IEQ", "COND_INE", "COND_IGE", "COND_ILE", "COND_LPAR",
00611   "COND_RPAR", "COND_TILDA", "COND_SS", "COND_ISS", "COND_ILHS",
00612   "COND_IRHS", "COND_LHS", "COND_RHS", "COND_PERCENT", "COND_DOLLARS",
00613   "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT",
00614   "COND_NUMBER", "COND_LITER", "COND_ERROR", "$accept", "condition",
00615   "expression", "boolean_term", "boolean_factor", "operator", "value_s",
00616   "literal", "value_i", "symbol_s", "identifier", "integer", 0
00617 };
00618 #endif
00619 
00620 # ifdef YYPRINT
00621 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
00622    token YYLEX-NUM.  */
00623 static const yytype_uint16 yytoknum[] =
00624 {
00625        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
00626      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
00627      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
00628      285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
00629      295
00630 };
00631 # endif
00632 
00633 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
00634 static const yytype_uint8 yyr1[] =
00635 {
00636        0,    41,    42,    42,    43,    43,    43,    43,    43,    44,
00637       44,    45,    45,    45,    45,    45,    45,    45,    45,    45,
00638       45,    45,    45,    45,    46,    46,    46,    46,    46,    46,
00639       46,    46,    46,    46,    46,    46,    46,    46,    46,    46,
00640       46,    46,    47,    47,    48,    49,    49,    49,    49,    49,
00641       50,    50,    51,    52
00642 };
00643 
00644 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
00645 static const yytype_uint8 yyr2[] =
00646 {
00647        0,     2,     1,     0,     1,     3,     3,     3,     3,     1,
00648        3,     2,     1,     1,     3,     3,     3,     3,     3,     3,
00649        3,     3,     3,     3,     1,     1,     1,     1,     1,     1,
00650        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
00651        1,     1,     1,     1,     1,     1,     2,     2,     2,     2,
00652        1,     2,     1,     1
00653 };
00654 
00655 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
00656    STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
00657    means the default is an error.  */
00658 static const yytype_uint8 yydefact[] =
00659 {
00660        3,     0,     0,     0,     0,     0,     0,     0,    52,    53,
00661       44,     0,     2,     4,     9,    13,    43,    12,    42,    50,
00662       45,    11,     0,    51,    46,    47,    48,    49,     1,     0,
00663        0,     0,     0,     0,    26,    27,    24,    25,    29,    28,
00664       33,    34,    31,    32,    36,    35,    30,    37,    40,    41,
00665       38,    39,     0,     0,     0,    23,     5,     7,     6,     8,
00666       10,    20,    21,    19,    22,    14,    16,    18,    15,    17
00667 };
00668 
00669 /* YYDEFGOTO[NTERM-NUM].  */
00670 static const yytype_int8 yydefgoto[] =
00671 {
00672       -1,    11,    12,    13,    14,    52,    15,    16,    17,    18,
00673       19,    20
00674 };
00675 
00676 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
00677    STATE-NUM.  */
00678 #define YYPACT_NINF -15
00679 static const yytype_int8 yypact[] =
00680 {
00681       -7,    -7,    -7,   -14,   -14,   -14,   -14,   -14,   -15,   -15,
00682      -15,    24,    46,    30,   -15,   -15,    -9,    -9,    -9,   -15,
00683      -15,   -15,    29,   -15,   -15,   -15,   -15,   -15,   -15,    -7,
00684       -7,    -7,    -7,    -7,   -15,   -15,   -15,   -15,   -15,   -15,
00685      -15,   -15,   -15,   -15,   -15,   -15,   -15,   -15,   -15,   -15,
00686      -15,   -15,     8,     8,     8,   -15,    30,    30,    30,    30,
00687      -15,   -15,   -15,   -15,   -15,   -15,   -15,   -15,   -15,   -15
00688 };
00689 
00690 /* YYPGOTO[NTERM-NUM].  */
00691 static const yytype_int8 yypgoto[] =
00692 {
00693      -15,   -15,    50,    33,     0,    -3,   -15,    -4,    14,    17,
00694       54,   -15
00695 };
00696 
00697 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
00698    positive, shift that token.  If negative, reduce the rule which
00699    number is the opposite.  If zero, do what YYDEFACT says.
00700    If YYTABLE_NINF, syntax error.  */
00701 #define YYTABLE_NINF -1
00702 static const yytype_uint8 yytable[] =
00703 {
00704        1,    21,    34,    35,    36,    37,    38,    39,    40,    41,
00705       42,    43,    44,    45,    53,    54,     2,    46,    47,    48,
00706       49,    50,    51,     8,    28,     3,     4,     5,     6,     7,
00707        8,     9,    10,    60,    29,     0,    33,    30,    31,    32,
00708        3,     4,     5,     6,     7,     8,     9,    10,    61,    64,
00709       67,    29,    22,    55,    30,    31,    32,    23,    24,    25,
00710       26,    27,    56,    57,    58,    59,    62,    65,    68,    63,
00711       66,    69
00712 };
00713 
00714 static const yytype_int8 yycheck[] =
00715 {
00716        7,     1,    11,    12,    13,    14,    15,    16,    17,    18,
00717       19,    20,    21,    22,    17,    18,    23,    26,    27,    28,
00718       29,    30,    31,    37,     0,    32,    33,    34,    35,    36,
00719       37,    38,    39,    33,     5,    -1,     6,     8,     9,    10,
00720       32,    33,    34,    35,    36,    37,    38,    39,    52,    53,
00721       54,     5,     2,    24,     8,     9,    10,     3,     4,     5,
00722        6,     7,    29,    30,    31,    32,    52,    53,    54,    52,
00723       53,    54
00724 };
00725 
00726 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
00727    symbol of state STATE-NUM.  */
00728 static const yytype_uint8 yystos[] =
00729 {
00730        0,     7,    23,    32,    33,    34,    35,    36,    37,    38,
00731       39,    42,    43,    44,    45,    47,    48,    49,    50,    51,
00732       52,    45,    43,    51,    51,    51,    51,    51,     0,     5,
00733        8,     9,    10,     6,    11,    12,    13,    14,    15,    16,
00734       17,    18,    19,    20,    21,    22,    26,    27,    28,    29,
00735       30,    31,    46,    46,    46,    24,    44,    44,    44,    44,
00736       45,    48,    49,    50,    48,    49,    50,    48,    49,    50
00737 };
00738 
00739 #define yyerrok     (yyerrstatus = 0)
00740 #define yyclearin   (yychar = YYEMPTY)
00741 #define YYEMPTY     (-2)
00742 #define YYEOF       0
00743 
00744 #define YYACCEPT    goto yyacceptlab
00745 #define YYABORT     goto yyabortlab
00746 #define YYERROR     goto yyerrorlab
00747 
00748 
00749 /* Like YYERROR except do call yyerror.  This remains here temporarily
00750    to ease the transition to the new meaning of YYERROR, for GCC.
00751    Once GCC version 2 has supplanted version 1, this can go.  */
00752 
00753 #define YYFAIL      goto yyerrlab
00754 
00755 #define YYRECOVERING()  (!!yyerrstatus)
00756 
00757 #define YYBACKUP(Token, Value)                  \
00758 do                              \
00759   if (yychar == YYEMPTY && yylen == 1)              \
00760     {                               \
00761       yychar = (Token);                     \
00762       yylval = (Value);                     \
00763       yytoken = YYTRANSLATE (yychar);               \
00764       YYPOPSTACK (1);                       \
00765       goto yybackup;                        \
00766     }                               \
00767   else                              \
00768     {                               \
00769       yyerror (YY_("syntax error: cannot back up")); \
00770       YYERROR;                          \
00771     }                               \
00772 while (YYID (0))
00773 
00774 
00775 #define YYTERROR    1
00776 #define YYERRCODE   256
00777 
00778 
00779 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
00780    If N is 0, then set CURRENT to the empty location which ends
00781    the previous symbol: RHS[0] (always defined).  */
00782 
00783 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
00784 #ifndef YYLLOC_DEFAULT
00785 # define YYLLOC_DEFAULT(Current, Rhs, N)                \
00786     do                                  \
00787       if (YYID (N))                                                    \
00788     {                               \
00789       (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;    \
00790       (Current).first_column = YYRHSLOC (Rhs, 1).first_column;  \
00791       (Current).last_line    = YYRHSLOC (Rhs, N).last_line;     \
00792       (Current).last_column  = YYRHSLOC (Rhs, N).last_column;   \
00793     }                               \
00794       else                              \
00795     {                               \
00796       (Current).first_line   = (Current).last_line   =      \
00797         YYRHSLOC (Rhs, 0).last_line;                \
00798       (Current).first_column = (Current).last_column =      \
00799         YYRHSLOC (Rhs, 0).last_column;              \
00800     }                               \
00801     while (YYID (0))
00802 #endif
00803 
00804 
00805 /* YY_LOCATION_PRINT -- Print the location on the stream.
00806    This macro was not mandated originally: define only if we know
00807    we won't break user code: when these are the locations we know.  */
00808 
00809 #ifndef YY_LOCATION_PRINT
00810 # if YYLTYPE_IS_TRIVIAL
00811 #  define YY_LOCATION_PRINT(File, Loc)          \
00812      fprintf (File, "%d.%d-%d.%d",          \
00813           (Loc).first_line, (Loc).first_column, \
00814           (Loc).last_line,  (Loc).last_column)
00815 # else
00816 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
00817 # endif
00818 #endif
00819 
00820 
00821 /* YYLEX -- calling `yylex' with the right arguments.  */
00822 
00823 #ifdef YYLEX_PARAM
00824 # define YYLEX yylex (&yylval, YYLEX_PARAM)
00825 #else
00826 # define YYLEX yylex (&yylval)
00827 #endif
00828 
00829 /* Enable debugging if requested.  */
00830 #if YYDEBUG
00831 
00832 # ifndef YYFPRINTF
00833 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
00834 #  define YYFPRINTF fprintf
00835 # endif
00836 
00837 # define YYDPRINTF(Args)            \
00838 do {                        \
00839   if (yydebug)                  \
00840     YYFPRINTF Args;             \
00841 } while (YYID (0))
00842 
00843 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)            \
00844 do {                                      \
00845   if (yydebug)                                \
00846     {                                     \
00847       YYFPRINTF (stderr, "%s ", Title);                   \
00848       yy_symbol_print (stderr,                        \
00849           Type, Value); \
00850       YYFPRINTF (stderr, "\n");                       \
00851     }                                     \
00852 } while (YYID (0))
00853 
00854 
00855 /*--------------------------------.
00856 | Print this symbol on YYOUTPUT.  |
00857 `--------------------------------*/
00858 
00859 /*ARGSUSED*/
00860 #if (defined __STDC__ || defined __C99__FUNC__ \
00861      || defined __cplusplus || defined _MSC_VER)
00862 static void
00863 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
00864 #else
00865 static void
00866 yy_symbol_value_print (yyoutput, yytype, yyvaluep)
00867     FILE *yyoutput;
00868     int yytype;
00869     YYSTYPE const * const yyvaluep;
00870 #endif
00871 {
00872   if (!yyvaluep)
00873     return;
00874 # ifdef YYPRINT
00875   if (yytype < YYNTOKENS)
00876     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
00877 # else
00878   YYUSE (yyoutput);
00879 # endif
00880   switch (yytype)
00881     {
00882       default:
00883     break;
00884     }
00885 }
00886 
00887 
00888 /*--------------------------------.
00889 | Print this symbol on YYOUTPUT.  |
00890 `--------------------------------*/
00891 
00892 #if (defined __STDC__ || defined __C99__FUNC__ \
00893      || defined __cplusplus || defined _MSC_VER)
00894 static void
00895 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
00896 #else
00897 static void
00898 yy_symbol_print (yyoutput, yytype, yyvaluep)
00899     FILE *yyoutput;
00900     int yytype;
00901     YYSTYPE const * const yyvaluep;
00902 #endif
00903 {
00904   if (yytype < YYNTOKENS)
00905     YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
00906   else
00907     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
00908 
00909   yy_symbol_value_print (yyoutput, yytype, yyvaluep);
00910   YYFPRINTF (yyoutput, ")");
00911 }
00912 
00913 /*------------------------------------------------------------------.
00914 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
00915 | TOP (included).                                                   |
00916 `------------------------------------------------------------------*/
00917 
00918 #if (defined __STDC__ || defined __C99__FUNC__ \
00919      || defined __cplusplus || defined _MSC_VER)
00920 static void
00921 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
00922 #else
00923 static void
00924 yy_stack_print (yybottom, yytop)
00925     yytype_int16 *yybottom;
00926     yytype_int16 *yytop;
00927 #endif
00928 {
00929   YYFPRINTF (stderr, "Stack now");
00930   for (; yybottom <= yytop; yybottom++)
00931     {
00932       int yybot = *yybottom;
00933       YYFPRINTF (stderr, " %d", yybot);
00934     }
00935   YYFPRINTF (stderr, "\n");
00936 }
00937 
00938 # define YY_STACK_PRINT(Bottom, Top)                \
00939 do {                                \
00940   if (yydebug)                          \
00941     yy_stack_print ((Bottom), (Top));               \
00942 } while (YYID (0))
00943 
00944 
00945 /*------------------------------------------------.
00946 | Report that the YYRULE is going to be reduced.  |
00947 `------------------------------------------------*/
00948 
00949 #if (defined __STDC__ || defined __C99__FUNC__ \
00950      || defined __cplusplus || defined _MSC_VER)
00951 static void
00952 yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
00953 #else
00954 static void
00955 yy_reduce_print (yyvsp, yyrule)
00956     YYSTYPE *yyvsp;
00957     int yyrule;
00958 #endif
00959 {
00960   int yynrhs = yyr2[yyrule];
00961   int yyi;
00962   unsigned long int yylno = yyrline[yyrule];
00963   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
00964          yyrule - 1, yylno);
00965   /* The symbols being reduced.  */
00966   for (yyi = 0; yyi < yynrhs; yyi++)
00967     {
00968       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
00969       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
00970                &(yyvsp[(yyi + 1) - (yynrhs)])
00971                            );
00972       YYFPRINTF (stderr, "\n");
00973     }
00974 }
00975 
00976 # define YY_REDUCE_PRINT(Rule)      \
00977 do {                    \
00978   if (yydebug)              \
00979     yy_reduce_print (yyvsp, Rule); \
00980 } while (YYID (0))
00981 
00982 /* Nonzero means print parse trace.  It is left uninitialized so that
00983    multiple parsers can coexist.  */
00984 int yydebug;
00985 #else /* !YYDEBUG */
00986 # define YYDPRINTF(Args)
00987 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
00988 # define YY_STACK_PRINT(Bottom, Top)
00989 # define YY_REDUCE_PRINT(Rule)
00990 #endif /* !YYDEBUG */
00991 
00992 
00993 /* YYINITDEPTH -- initial size of the parser's stacks.  */
00994 #ifndef YYINITDEPTH
00995 # define YYINITDEPTH 200
00996 #endif
00997 
00998 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
00999    if the built-in stack extension method is used).
01000 
01001    Do not make this value too large; the results are undefined if
01002    YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
01003    evaluated with infinite-precision integer arithmetic.  */
01004 
01005 #ifndef YYMAXDEPTH
01006 # define YYMAXDEPTH 10000
01007 #endif
01008 
01009 
01010 
01011 #if YYERROR_VERBOSE
01012 
01013 # ifndef yystrlen
01014 #  if defined __GLIBC__ && defined _STRING_H
01015 #   define yystrlen strlen
01016 #  else
01017 /* Return the length of YYSTR.  */
01018 #if (defined __STDC__ || defined __C99__FUNC__ \
01019      || defined __cplusplus || defined _MSC_VER)
01020 static YYSIZE_T
01021 yystrlen (const char *yystr)
01022 #else
01023 static YYSIZE_T
01024 yystrlen (yystr)
01025     const char *yystr;
01026 #endif
01027 {
01028   YYSIZE_T yylen;
01029   for (yylen = 0; yystr[yylen]; yylen++)
01030     continue;
01031   return yylen;
01032 }
01033 #  endif
01034 # endif
01035 
01036 # ifndef yystpcpy
01037 #  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
01038 #   define yystpcpy stpcpy
01039 #  else
01040 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
01041    YYDEST.  */
01042 #if (defined __STDC__ || defined __C99__FUNC__ \
01043      || defined __cplusplus || defined _MSC_VER)
01044 static char *
01045 yystpcpy (char *yydest, const char *yysrc)
01046 #else
01047 static char *
01048 yystpcpy (yydest, yysrc)
01049     char *yydest;
01050     const char *yysrc;
01051 #endif
01052 {
01053   char *yyd = yydest;
01054   const char *yys = yysrc;
01055 
01056   while ((*yyd++ = *yys++) != '\0')
01057     continue;
01058 
01059   return yyd - 1;
01060 }
01061 #  endif
01062 # endif
01063 
01064 # ifndef yytnamerr
01065 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
01066    quotes and backslashes, so that it's suitable for yyerror.  The
01067    heuristic is that double-quoting is unnecessary unless the string
01068    contains an apostrophe, a comma, or backslash (other than
01069    backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
01070    null, do not copy; instead, return the length of what the result
01071    would have been.  */
01072 static YYSIZE_T
01073 yytnamerr (char *yyres, const char *yystr)
01074 {
01075   if (*yystr == '"')
01076     {
01077       YYSIZE_T yyn = 0;
01078       char const *yyp = yystr;
01079 
01080       for (;;)
01081     switch (*++yyp)
01082       {
01083       case '\'':
01084       case ',':
01085         goto do_not_strip_quotes;
01086 
01087       case '\\':
01088         if (*++yyp != '\\')
01089           goto do_not_strip_quotes;
01090         /* Fall through.  */
01091       default:
01092         if (yyres)
01093           yyres[yyn] = *yyp;
01094         yyn++;
01095         break;
01096 
01097       case '"':
01098         if (yyres)
01099           yyres[yyn] = '\0';
01100         return yyn;
01101       }
01102     do_not_strip_quotes: ;
01103     }
01104 
01105   if (! yyres)
01106     return yystrlen (yystr);
01107 
01108   return yystpcpy (yyres, yystr) - yyres;
01109 }
01110 # endif
01111 
01112 /* Copy into YYRESULT an error message about the unexpected token
01113    YYCHAR while in state YYSTATE.  Return the number of bytes copied,
01114    including the terminating null byte.  If YYRESULT is null, do not
01115    copy anything; just return the number of bytes that would be
01116    copied.  As a special case, return 0 if an ordinary "syntax error"
01117    message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
01118    size calculation.  */
01119 static YYSIZE_T
01120 yysyntax_error (char *yyresult, int yystate, int yychar)
01121 {
01122   int yyn = yypact[yystate];
01123 
01124   if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
01125     return 0;
01126   else
01127     {
01128       int yytype = YYTRANSLATE (yychar);
01129       YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
01130       YYSIZE_T yysize = yysize0;
01131       YYSIZE_T yysize1;
01132       int yysize_overflow = 0;
01133       enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
01134       char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
01135       int yyx;
01136 
01137 # if 0
01138       /* This is so xgettext sees the translatable formats that are
01139      constructed on the fly.  */
01140       YY_("syntax error, unexpected %s");
01141       YY_("syntax error, unexpected %s, expecting %s");
01142       YY_("syntax error, unexpected %s, expecting %s or %s");
01143       YY_("syntax error, unexpected %s, expecting %s or %s or %s");
01144       YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
01145 # endif
01146       char *yyfmt;
01147       char const *yyf;
01148       static char const yyunexpected[] = "syntax error, unexpected %s";
01149       static char const yyexpecting[] = ", expecting %s";
01150       static char const yyor[] = " or %s";
01151       char yyformat[sizeof yyunexpected
01152             + sizeof yyexpecting - 1
01153             + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
01154                * (sizeof yyor - 1))];
01155       char const *yyprefix = yyexpecting;
01156 
01157       /* Start YYX at -YYN if negative to avoid negative indexes in
01158      YYCHECK.  */
01159       int yyxbegin = yyn < 0 ? -yyn : 0;
01160 
01161       /* Stay within bounds of both yycheck and yytname.  */
01162       int yychecklim = YYLAST - yyn + 1;
01163       int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
01164       int yycount = 1;
01165 
01166       yyarg[0] = yytname[yytype];
01167       yyfmt = yystpcpy (yyformat, yyunexpected);
01168 
01169       for (yyx = yyxbegin; yyx < yyxend; ++yyx)
01170     if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
01171       {
01172         if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
01173           {
01174         yycount = 1;
01175         yysize = yysize0;
01176         yyformat[sizeof yyunexpected - 1] = '\0';
01177         break;
01178           }
01179         yyarg[yycount++] = yytname[yyx];
01180         yysize1 = yysize + yytnamerr (0, yytname[yyx]);
01181         yysize_overflow |= (yysize1 < yysize);
01182         yysize = yysize1;
01183         yyfmt = yystpcpy (yyfmt, yyprefix);
01184         yyprefix = yyor;
01185       }
01186 
01187       yyf = YY_(yyformat);
01188       yysize1 = yysize + yystrlen (yyf);
01189       yysize_overflow |= (yysize1 < yysize);
01190       yysize = yysize1;
01191 
01192       if (yysize_overflow)
01193     return YYSIZE_MAXIMUM;
01194 
01195       if (yyresult)
01196     {
01197       /* Avoid sprintf, as that infringes on the user's name space.
01198          Don't have undefined behavior even if the translation
01199          produced a string with the wrong number of "%s"s.  */
01200       char *yyp = yyresult;
01201       int yyi = 0;
01202       while ((*yyp = *yyf) != '\0')
01203         {
01204           if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
01205         {
01206           yyp += yytnamerr (yyp, yyarg[yyi++]);
01207           yyf += 2;
01208         }
01209           else
01210         {
01211           yyp++;
01212           yyf++;
01213         }
01214         }
01215     }
01216       return yysize;
01217     }
01218 }
01219 #endif /* YYERROR_VERBOSE */
01220 
01221 
01222 /*-----------------------------------------------.
01223 | Release the memory associated to this symbol.  |
01224 `-----------------------------------------------*/
01225 
01226 /*ARGSUSED*/
01227 #if (defined __STDC__ || defined __C99__FUNC__ \
01228      || defined __cplusplus || defined _MSC_VER)
01229 static void
01230 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
01231 #else
01232 static void
01233 yydestruct (yymsg, yytype, yyvaluep)
01234     const char *yymsg;
01235     int yytype;
01236     YYSTYPE *yyvaluep;
01237 #endif
01238 {
01239   YYUSE (yyvaluep);
01240 
01241   if (!yymsg)
01242     yymsg = "Deleting";
01243   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
01244 
01245   switch (yytype)
01246     {
01247 
01248       default:
01249     break;
01250     }
01251 }
01252 
01253 /* Prevent warnings from -Wmissing-prototypes.  */
01254 #ifdef YYPARSE_PARAM
01255 #if defined __STDC__ || defined __cplusplus
01256 int yyparse (void *YYPARSE_PARAM);
01257 #else
01258 int yyparse ();
01259 #endif
01260 #else /* ! YYPARSE_PARAM */
01261 #if defined __STDC__ || defined __cplusplus
01262 int yyparse (void);
01263 #else
01264 int yyparse ();
01265 #endif
01266 #endif /* ! YYPARSE_PARAM */
01267 
01268 
01269 
01270 
01271 
01272 /*-------------------------.
01273 | yyparse or yypush_parse.  |
01274 `-------------------------*/
01275 
01276 #ifdef YYPARSE_PARAM
01277 #if (defined __STDC__ || defined __C99__FUNC__ \
01278      || defined __cplusplus || defined _MSC_VER)
01279 int
01280 yyparse (void *YYPARSE_PARAM)
01281 #else
01282 int
01283 yyparse (YYPARSE_PARAM)
01284     void *YYPARSE_PARAM;
01285 #endif
01286 #else /* ! YYPARSE_PARAM */
01287 #if (defined __STDC__ || defined __C99__FUNC__ \
01288      || defined __cplusplus || defined _MSC_VER)
01289 int
01290 yyparse (void)
01291 #else
01292 int
01293 yyparse ()
01294 
01295 #endif
01296 #endif
01297 {
01298 /* The lookahead symbol.  */
01299 int yychar;
01300 
01301 /* The semantic value of the lookahead symbol.  */
01302 YYSTYPE yylval;
01303 
01304     /* Number of syntax errors so far.  */
01305     int yynerrs;
01306 
01307     int yystate;
01308     /* Number of tokens to shift before error messages enabled.  */
01309     int yyerrstatus;
01310 
01311     /* The stacks and their tools:
01312        `yyss': related to states.
01313        `yyvs': related to semantic values.
01314 
01315        Refer to the stacks thru separate pointers, to allow yyoverflow
01316        to reallocate them elsewhere.  */
01317 
01318     /* The state stack.  */
01319     yytype_int16 yyssa[YYINITDEPTH];
01320     yytype_int16 *yyss;
01321     yytype_int16 *yyssp;
01322 
01323     /* The semantic value stack.  */
01324     YYSTYPE yyvsa[YYINITDEPTH];
01325     YYSTYPE *yyvs;
01326     YYSTYPE *yyvsp;
01327 
01328     YYSIZE_T yystacksize;
01329 
01330   int yyn;
01331   int yyresult;
01332   /* Lookahead token as an internal (translated) token number.  */
01333   int yytoken;
01334   /* The variables used to return semantic value and location from the
01335      action routines.  */
01336   YYSTYPE yyval;
01337 
01338 #if YYERROR_VERBOSE
01339   /* Buffer for error messages, and its allocated size.  */
01340   char yymsgbuf[128];
01341   char *yymsg = yymsgbuf;
01342   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
01343 #endif
01344 
01345 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
01346 
01347   /* The number of symbols on the RHS of the reduced rule.
01348      Keep to zero when no symbol should be popped.  */
01349   int yylen = 0;
01350 
01351   yytoken = 0;
01352   yyss = yyssa;
01353   yyvs = yyvsa;
01354   yystacksize = YYINITDEPTH;
01355 
01356   YYDPRINTF ((stderr, "Starting parse\n"));
01357 
01358   yystate = 0;
01359   yyerrstatus = 0;
01360   yynerrs = 0;
01361   yychar = YYEMPTY; /* Cause a token to be read.  */
01362 
01363   /* Initialize stack pointers.
01364      Waste one element of value and location stack
01365      so that they stay on the same level as the state stack.
01366      The wasted elements are never initialized.  */
01367   yyssp = yyss;
01368   yyvsp = yyvs;
01369 
01370   goto yysetstate;
01371 
01372 /*------------------------------------------------------------.
01373 | yynewstate -- Push a new state, which is found in yystate.  |
01374 `------------------------------------------------------------*/
01375  yynewstate:
01376   /* In all cases, when you get here, the value and location stacks
01377      have just been pushed.  So pushing a state here evens the stacks.  */
01378   yyssp++;
01379 
01380  yysetstate:
01381   *yyssp = yystate;
01382 
01383   if (yyss + yystacksize - 1 <= yyssp)
01384     {
01385       /* Get the current used size of the three stacks, in elements.  */
01386       YYSIZE_T yysize = yyssp - yyss + 1;
01387 
01388 #ifdef yyoverflow
01389       {
01390     /* Give user a chance to reallocate the stack.  Use copies of
01391        these so that the &'s don't force the real ones into
01392        memory.  */
01393     YYSTYPE *yyvs1 = yyvs;
01394     yytype_int16 *yyss1 = yyss;
01395 
01396     /* Each stack pointer address is followed by the size of the
01397        data in use in that stack, in bytes.  This used to be a
01398        conditional around just the two extra args, but that might
01399        be undefined if yyoverflow is a macro.  */
01400     yyoverflow (YY_("memory exhausted"),
01401             &yyss1, yysize * sizeof (*yyssp),
01402             &yyvs1, yysize * sizeof (*yyvsp),
01403             &yystacksize);
01404 
01405     yyss = yyss1;
01406     yyvs = yyvs1;
01407       }
01408 #else /* no yyoverflow */
01409 # ifndef YYSTACK_RELOCATE
01410       goto yyexhaustedlab;
01411 # else
01412       /* Extend the stack our own way.  */
01413       if (YYMAXDEPTH <= yystacksize)
01414     goto yyexhaustedlab;
01415       yystacksize *= 2;
01416       if (YYMAXDEPTH < yystacksize)
01417     yystacksize = YYMAXDEPTH;
01418 
01419       {
01420     yytype_int16 *yyss1 = yyss;
01421     union yyalloc *yyptr =
01422       (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
01423     if (! yyptr)
01424       goto yyexhaustedlab;
01425     YYSTACK_RELOCATE (yyss_alloc, yyss);
01426     YYSTACK_RELOCATE (yyvs_alloc, yyvs);
01427 #  undef YYSTACK_RELOCATE
01428     if (yyss1 != yyssa)
01429       YYSTACK_FREE (yyss1);
01430       }
01431 # endif
01432 #endif /* no yyoverflow */
01433 
01434       yyssp = yyss + yysize - 1;
01435       yyvsp = yyvs + yysize - 1;
01436 
01437       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
01438           (unsigned long int) yystacksize));
01439 
01440       if (yyss + yystacksize - 1 <= yyssp)
01441     YYABORT;
01442     }
01443 
01444   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
01445 
01446   if (yystate == YYFINAL)
01447     YYACCEPT;
01448 
01449   goto yybackup;
01450 
01451 /*-----------.
01452 | yybackup.  |
01453 `-----------*/
01454 yybackup:
01455 
01456   /* Do appropriate processing given the current state.  Read a
01457      lookahead token if we need one and don't already have one.  */
01458 
01459   /* First try to decide what to do without reference to lookahead token.  */
01460   yyn = yypact[yystate];
01461   if (yyn == YYPACT_NINF)
01462     goto yydefault;
01463 
01464   /* Not known => get a lookahead token if don't already have one.  */
01465 
01466   /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
01467   if (yychar == YYEMPTY)
01468     {
01469       YYDPRINTF ((stderr, "Reading a token: "));
01470       yychar = YYLEX;
01471     }
01472 
01473   if (yychar <= YYEOF)
01474     {
01475       yychar = yytoken = YYEOF;
01476       YYDPRINTF ((stderr, "Now at end of input.\n"));
01477     }
01478   else
01479     {
01480       yytoken = YYTRANSLATE (yychar);
01481       YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
01482     }
01483 
01484   /* If the proper action on seeing token YYTOKEN is to reduce or to
01485      detect an error, take that action.  */
01486   yyn += yytoken;
01487   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
01488     goto yydefault;
01489   yyn = yytable[yyn];
01490   if (yyn <= 0)
01491     {
01492       if (yyn == 0 || yyn == YYTABLE_NINF)
01493     goto yyerrlab;
01494       yyn = -yyn;
01495       goto yyreduce;
01496     }
01497 
01498   /* Count tokens shifted since error; after three, turn off error
01499      status.  */
01500   if (yyerrstatus)
01501     yyerrstatus--;
01502 
01503   /* Shift the lookahead token.  */
01504   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
01505 
01506   /* Discard the shifted token.  */
01507   yychar = YYEMPTY;
01508 
01509   yystate = yyn;
01510   *++yyvsp = yylval;
01511 
01512   goto yynewstate;
01513 
01514 
01515 /*-----------------------------------------------------------.
01516 | yydefault -- do the default action for the current state.  |
01517 `-----------------------------------------------------------*/
01518 yydefault:
01519   yyn = yydefact[yystate];
01520   if (yyn == 0)
01521     goto yyerrlab;
01522   goto yyreduce;
01523 
01524 
01525 /*-----------------------------.
01526 | yyreduce -- Do a reduction.  |
01527 `-----------------------------*/
01528 yyreduce:
01529   /* yyn is the number of a rule to reduce with.  */
01530   yylen = yyr2[yyn];
01531 
01532   /* If YYLEN is nonzero, implement the default value of the action:
01533      `$$ = $1'.
01534 
01535      Otherwise, the following line sets YYVAL to garbage.
01536      This behavior is undocumented and Bison
01537      users should not rely upon it.  Assigning to YYVAL
01538      unconditionally makes the parser a bit smaller, and it avoids a
01539      GCC warning that YYVAL may be used uninitialized.  */
01540   yyval = yyvsp[1-yylen];
01541 
01542 
01543   YY_REDUCE_PRINT (yyn);
01544   switch (yyn)
01545     {
01546         case 2:
01547 
01548 /* Line 1455 of yacc.c  */
01549 #line 141 "cond.y"
01550     {
01551             COND_input* cond = (COND_input*) info;
01552             cond->result = (yyvsp[(1) - (1)].value);
01553         ;}
01554     break;
01555 
01556   case 3:
01557 
01558 /* Line 1455 of yacc.c  */
01559 #line 146 "cond.y"
01560     {
01561             COND_input* cond = (COND_input*) info;
01562             cond->result = MSICONDITION_NONE;
01563         ;}
01564     break;
01565 
01566   case 4:
01567 
01568 /* Line 1455 of yacc.c  */
01569 #line 154 "cond.y"
01570     {
01571             (yyval.value) = (yyvsp[(1) - (1)].value);
01572         ;}
01573     break;
01574 
01575   case 5:
01576 
01577 /* Line 1455 of yacc.c  */
01578 #line 158 "cond.y"
01579     {
01580             (yyval.value) = (yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value);
01581         ;}
01582     break;
01583 
01584   case 6:
01585 
01586 /* Line 1455 of yacc.c  */
01587 #line 162 "cond.y"
01588     {
01589             (yyval.value) = !(yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value);
01590         ;}
01591     break;
01592 
01593   case 7:
01594 
01595 /* Line 1455 of yacc.c  */
01596 #line 166 "cond.y"
01597     {
01598             (yyval.value) = ( (yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value) ) && !( (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value) );
01599         ;}
01600     break;
01601 
01602   case 8:
01603 
01604 /* Line 1455 of yacc.c  */
01605 #line 170 "cond.y"
01606     {
01607             (yyval.value) = ( (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value) ) || ( !(yyvsp[(1) - (3)].value) && !(yyvsp[(3) - (3)].value) );
01608         ;}
01609     break;
01610 
01611   case 9:
01612 
01613 /* Line 1455 of yacc.c  */
01614 #line 177 "cond.y"
01615     {
01616             (yyval.value) = (yyvsp[(1) - (1)].value);
01617         ;}
01618     break;
01619 
01620   case 10:
01621 
01622 /* Line 1455 of yacc.c  */
01623 #line 181 "cond.y"
01624     {
01625             (yyval.value) = (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value);
01626         ;}
01627     break;
01628 
01629   case 11:
01630 
01631 /* Line 1455 of yacc.c  */
01632 #line 188 "cond.y"
01633     {
01634             (yyval.value) = (yyvsp[(2) - (2)].value) ? 0 : 1;
01635         ;}
01636     break;
01637 
01638   case 12:
01639 
01640 /* Line 1455 of yacc.c  */
01641 #line 192 "cond.y"
01642     {
01643             (yyval.value) = (yyvsp[(1) - (1)].value) ? 1 : 0;
01644         ;}
01645     break;
01646 
01647   case 13:
01648 
01649 /* Line 1455 of yacc.c  */
01650 #line 196 "cond.y"
01651     {
01652             (yyval.value) = ((yyvsp[(1) - (1)].string) && (yyvsp[(1) - (1)].string)[0]) ? 1 : 0;
01653             cond_free( (yyvsp[(1) - (1)].string) );
01654         ;}
01655     break;
01656 
01657   case 14:
01658 
01659 /* Line 1455 of yacc.c  */
01660 #line 201 "cond.y"
01661     {
01662             (yyval.value) = compare_int( (yyvsp[(1) - (3)].value), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].value) );
01663         ;}
01664     break;
01665 
01666   case 15:
01667 
01668 /* Line 1455 of yacc.c  */
01669 #line 205 "cond.y"
01670     {
01671             int num;
01672             if (num_from_prop( (yyvsp[(1) - (3)].string), &num ))
01673                 (yyval.value) = compare_int( num, (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].value) );
01674             else 
01675                 (yyval.value) = ((yyvsp[(2) - (3)].value) == COND_NE || (yyvsp[(2) - (3)].value) == COND_INE );
01676             cond_free( (yyvsp[(1) - (3)].string) );
01677         ;}
01678     break;
01679 
01680   case 16:
01681 
01682 /* Line 1455 of yacc.c  */
01683 #line 214 "cond.y"
01684     {
01685             int num;
01686             if (num_from_prop( (yyvsp[(3) - (3)].string), &num ))
01687                 (yyval.value) = compare_int( (yyvsp[(1) - (3)].value), (yyvsp[(2) - (3)].value), num );
01688             else 
01689                 (yyval.value) = ((yyvsp[(2) - (3)].value) == COND_NE || (yyvsp[(2) - (3)].value) == COND_INE );
01690             cond_free( (yyvsp[(3) - (3)].string) );
01691         ;}
01692     break;
01693 
01694   case 17:
01695 
01696 /* Line 1455 of yacc.c  */
01697 #line 223 "cond.y"
01698     {
01699             (yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE );
01700         ;}
01701     break;
01702 
01703   case 18:
01704 
01705 /* Line 1455 of yacc.c  */
01706 #line 227 "cond.y"
01707     {
01708             (yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE );
01709         ;}
01710     break;
01711 
01712   case 19:
01713 
01714 /* Line 1455 of yacc.c  */
01715 #line 231 "cond.y"
01716     {
01717             (yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE );
01718         ;}
01719     break;
01720 
01721   case 20:
01722 
01723 /* Line 1455 of yacc.c  */
01724 #line 235 "cond.y"
01725     {
01726             (yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), FALSE );
01727         ;}
01728     break;
01729 
01730   case 21:
01731 
01732 /* Line 1455 of yacc.c  */
01733 #line 239 "cond.y"
01734     {
01735             (yyval.value) = 0;
01736             cond_free( (yyvsp[(1) - (3)].string) );
01737         ;}
01738     break;
01739 
01740   case 22:
01741 
01742 /* Line 1455 of yacc.c  */
01743 #line 244 "cond.y"
01744     {
01745             (yyval.value) = 0;
01746             cond_free( (yyvsp[(3) - (3)].string) );
01747         ;}
01748     break;
01749 
01750   case 23:
01751 
01752 /* Line 1455 of yacc.c  */
01753 #line 249 "cond.y"
01754     {
01755             (yyval.value) = (yyvsp[(2) - (3)].value);
01756         ;}
01757     break;
01758 
01759   case 24:
01760 
01761 /* Line 1455 of yacc.c  */
01762 #line 256 "cond.y"
01763     { (yyval.value) = COND_EQ; ;}
01764     break;
01765 
01766   case 25:
01767 
01768 /* Line 1455 of yacc.c  */
01769 #line 257 "cond.y"
01770     { (yyval.value) = COND_NE; ;}
01771     break;
01772 
01773   case 26:
01774 
01775 /* Line 1455 of yacc.c  */
01776 #line 258 "cond.y"
01777     { (yyval.value) = COND_LT; ;}
01778     break;
01779 
01780   case 27:
01781 
01782 /* Line 1455 of yacc.c  */
01783 #line 259 "cond.y"
01784     { (yyval.value) = COND_GT; ;}
01785     break;
01786 
01787   case 28:
01788 
01789 /* Line 1455 of yacc.c  */
01790 #line 260 "cond.y"
01791     { (yyval.value) = COND_LE; ;}
01792     break;
01793 
01794   case 29:
01795 
01796 /* Line 1455 of yacc.c  */
01797 #line 261 "cond.y"
01798     { (yyval.value) = COND_GE; ;}
01799     break;
01800 
01801   case 30:
01802 
01803 /* Line 1455 of yacc.c  */
01804 #line 262 "cond.y"
01805     { (yyval.value) = COND_SS; ;}
01806     break;
01807 
01808   case 31:
01809 
01810 /* Line 1455 of yacc.c  */
01811 #line 263 "cond.y"
01812     { (yyval.value) = COND_IEQ; ;}
01813     break;
01814 
01815   case 32:
01816 
01817 /* Line 1455 of yacc.c  */
01818 #line 264 "cond.y"
01819     { (yyval.value) = COND_INE; ;}
01820     break;
01821 
01822   case 33:
01823 
01824 /* Line 1455 of yacc.c  */
01825 #line 265 "cond.y"
01826     { (yyval.value) = COND_ILT; ;}
01827     break;
01828 
01829   case 34:
01830 
01831 /* Line 1455 of yacc.c  */
01832 #line 266 "cond.y"
01833     { (yyval.value) = COND_IGT; ;}
01834     break;
01835 
01836   case 35:
01837 
01838 /* Line 1455 of yacc.c  */
01839 #line 267 "cond.y"
01840     { (yyval.value) = COND_ILE; ;}
01841     break;
01842 
01843   case 36:
01844 
01845 /* Line 1455 of yacc.c  */
01846 #line 268 "cond.y"
01847     { (yyval.value) = COND_IGE; ;}
01848     break;
01849 
01850   case 37:
01851 
01852 /* Line 1455 of yacc.c  */
01853 #line 269 "cond.y"
01854     { (yyval.value) = COND_ISS; ;}
01855     break;
01856 
01857   case 38:
01858 
01859 /* Line 1455 of yacc.c  */
01860 #line 270 "cond.y"
01861     { (yyval.value) = COND_LHS; ;}
01862     break;
01863 
01864   case 39:
01865 
01866 /* Line 1455 of yacc.c  */
01867 #line 271 "cond.y"
01868     { (yyval.value) = COND_RHS; ;}
01869     break;
01870 
01871   case 40:
01872 
01873 /* Line 1455 of yacc.c  */
01874 #line 272 "cond.y"
01875     { (yyval.value) = COND_ILHS; ;}
01876     break;
01877 
01878   case 41:
01879 
01880 /* Line 1455 of yacc.c  */
01881 #line 273 "cond.y"
01882     { (yyval.value) = COND_IRHS; ;}
01883     break;
01884 
01885   case 42:
01886 
01887 /* Line 1455 of yacc.c  */
01888 #line 278 "cond.y"
01889     {
01890         (yyval.string) = (yyvsp[(1) - (1)].string);
01891     ;}
01892     break;
01893 
01894   case 43:
01895 
01896 /* Line 1455 of yacc.c  */
01897 #line 282 "cond.y"
01898     {
01899         (yyval.string) = (yyvsp[(1) - (1)].string);
01900     ;}
01901     break;
01902 
01903   case 44:
01904 
01905 /* Line 1455 of yacc.c  */
01906 #line 289 "cond.y"
01907     {
01908             COND_input* cond = (COND_input*) info;
01909             (yyval.string) = COND_GetLiteral( cond, &(yyvsp[(1) - (1)].str) );
01910             if( !(yyval.string) )
01911                 YYABORT;
01912         ;}
01913     break;
01914 
01915   case 45:
01916 
01917 /* Line 1455 of yacc.c  */
01918 #line 299 "cond.y"
01919     {
01920             (yyval.value) = (yyvsp[(1) - (1)].value);
01921         ;}
01922     break;
01923 
01924   case 46:
01925 
01926 /* Line 1455 of yacc.c  */
01927 #line 303 "cond.y"
01928     {
01929             COND_input* cond = (COND_input*) info;
01930             INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
01931       
01932             MSI_GetComponentStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action );
01933             (yyval.value) = action;
01934             cond_free( (yyvsp[(2) - (2)].string) );
01935         ;}
01936     break;
01937 
01938   case 47:
01939 
01940 /* Line 1455 of yacc.c  */
01941 #line 312 "cond.y"
01942     {
01943             COND_input* cond = (COND_input*) info;
01944             INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
01945       
01946             MSI_GetComponentStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action );
01947             (yyval.value) = install;
01948             cond_free( (yyvsp[(2) - (2)].string) );
01949         ;}
01950     break;
01951 
01952   case 48:
01953 
01954 /* Line 1455 of yacc.c  */
01955 #line 321 "cond.y"
01956     {
01957             COND_input* cond = (COND_input*) info;
01958             INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
01959       
01960             MSI_GetFeatureStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action );
01961             if (action == INSTALLSTATE_UNKNOWN)
01962                 (yyval.value) = MSICONDITION_FALSE;
01963             else
01964                 (yyval.value) = action;
01965 
01966             cond_free( (yyvsp[(2) - (2)].string) );
01967         ;}
01968     break;
01969 
01970   case 49:
01971 
01972 /* Line 1455 of yacc.c  */
01973 #line 334 "cond.y"
01974     {
01975             COND_input* cond = (COND_input*) info;
01976             INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
01977       
01978             MSI_GetFeatureStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action );
01979             (yyval.value) = install;
01980             cond_free( (yyvsp[(2) - (2)].string) );
01981         ;}
01982     break;
01983 
01984   case 50:
01985 
01986 /* Line 1455 of yacc.c  */
01987 #line 346 "cond.y"
01988     {
01989             COND_input* cond = (COND_input*) info;
01990             UINT len;
01991 
01992             (yyval.string) = msi_dup_property( cond->package->db, (yyvsp[(1) - (1)].string) );
01993             if ((yyval.string))
01994             {
01995                 len = (lstrlenW((yyval.string)) + 1) * sizeof (WCHAR);
01996                 (yyval.string) = cond_track_mem( cond, (yyval.string), len );
01997             }
01998             cond_free( (yyvsp[(1) - (1)].string) );
01999         ;}
02000     break;
02001 
02002   case 51:
02003 
02004 /* Line 1455 of yacc.c  */
02005 #line 359 "cond.y"
02006     {
02007             COND_input* cond = (COND_input*) info;
02008             UINT len = GetEnvironmentVariableW( (yyvsp[(2) - (2)].string), NULL, 0 );
02009             (yyval.string) = NULL;
02010             if (len++)
02011             {
02012                 (yyval.string) = cond_alloc( cond, len*sizeof (WCHAR) );
02013                 if( !(yyval.string) )
02014                     YYABORT;
02015                 GetEnvironmentVariableW( (yyvsp[(2) - (2)].string), (yyval.string), len );
02016             }
02017             cond_free( (yyvsp[(2) - (2)].string) );
02018         ;}
02019     break;
02020 
02021   case 52:
02022 
02023 /* Line 1455 of yacc.c  */
02024 #line 376 "cond.y"
02025     {
02026             COND_input* cond = (COND_input*) info;
02027             (yyval.string) = COND_GetString( cond, &(yyvsp[(1) - (1)].str) );
02028             if( !(yyval.string) )
02029                 YYABORT;
02030         ;}
02031     break;
02032 
02033   case 53:
02034 
02035 /* Line 1455 of yacc.c  */
02036 #line 386 "cond.y"
02037     {
02038             COND_input* cond = (COND_input*) info;
02039             LPWSTR szNum = COND_GetString( cond, &(yyvsp[(1) - (1)].str) );
02040             if( !szNum )
02041                 YYABORT;
02042             (yyval.value) = atoiW( szNum );
02043             cond_free( szNum );
02044         ;}
02045     break;
02046 
02047 
02048 
02049 /* Line 1455 of yacc.c  */
02050 #line 2051 "cond.tab.c"
02051       default: break;
02052     }
02053   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
02054 
02055   YYPOPSTACK (yylen);
02056   yylen = 0;
02057   YY_STACK_PRINT (yyss, yyssp);
02058 
02059   *++yyvsp = yyval;
02060 
02061   /* Now `shift' the result of the reduction.  Determine what state
02062      that goes to, based on the state we popped back to and the rule
02063      number reduced by.  */
02064 
02065   yyn = yyr1[yyn];
02066 
02067   yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
02068   if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
02069     yystate = yytable[yystate];
02070   else
02071     yystate = yydefgoto[yyn - YYNTOKENS];
02072 
02073   goto yynewstate;
02074 
02075 
02076 /*------------------------------------.
02077 | yyerrlab -- here on detecting error |
02078 `------------------------------------*/
02079 yyerrlab:
02080   /* If not already recovering from an error, report this error.  */
02081   if (!yyerrstatus)
02082     {
02083       ++yynerrs;
02084 #if ! YYERROR_VERBOSE
02085       yyerror (YY_("syntax error"));
02086 #else
02087       {
02088     YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
02089     if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
02090       {
02091         YYSIZE_T yyalloc = 2 * yysize;
02092         if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
02093           yyalloc = YYSTACK_ALLOC_MAXIMUM;
02094         if (yymsg != yymsgbuf)
02095           YYSTACK_FREE (yymsg);
02096         yymsg = (char *) YYSTACK_ALLOC (yyalloc);
02097         if (yymsg)
02098           yymsg_alloc = yyalloc;
02099         else
02100           {
02101         yymsg = yymsgbuf;
02102         yymsg_alloc = sizeof yymsgbuf;
02103           }
02104       }
02105 
02106     if (0 < yysize && yysize <= yymsg_alloc)
02107       {
02108         (void) yysyntax_error (yymsg, yystate, yychar);
02109         yyerror (yymsg);
02110       }
02111     else
02112       {
02113         yyerror (YY_("syntax error"));
02114         if (yysize != 0)
02115           goto yyexhaustedlab;
02116       }
02117       }
02118 #endif
02119     }
02120 
02121 
02122 
02123   if (yyerrstatus == 3)
02124     {
02125       /* If just tried and failed to reuse lookahead token after an
02126      error, discard it.  */
02127 
02128       if (yychar <= YYEOF)
02129     {
02130       /* Return failure if at end of input.  */
02131       if (yychar == YYEOF)
02132         YYABORT;
02133     }
02134       else
02135     {
02136       yydestruct ("Error: discarding",
02137               yytoken, &yylval);
02138       yychar = YYEMPTY;
02139     }
02140     }
02141 
02142   /* Else will try to reuse lookahead token after shifting the error
02143      token.  */
02144   goto yyerrlab1;
02145 
02146 
02147 /*---------------------------------------------------.
02148 | yyerrorlab -- error raised explicitly by YYERROR.  |
02149 `---------------------------------------------------*/
02150 yyerrorlab:
02151 
02152   /* Pacify compilers like GCC when the user code never invokes
02153      YYERROR and the label yyerrorlab therefore never appears in user
02154      code.  */
02155   if (/*CONSTCOND*/ 0)
02156      goto yyerrorlab;
02157 
02158   /* Do not reclaim the symbols of the rule which action triggered
02159      this YYERROR.  */
02160   YYPOPSTACK (yylen);
02161   yylen = 0;
02162   YY_STACK_PRINT (yyss, yyssp);
02163   yystate = *yyssp;
02164   goto yyerrlab1;
02165 
02166 
02167 /*-------------------------------------------------------------.
02168 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
02169 `-------------------------------------------------------------*/
02170 yyerrlab1:
02171   yyerrstatus = 3;  /* Each real token shifted decrements this.  */
02172 
02173   for (;;)
02174     {
02175       yyn = yypact[yystate];
02176       if (yyn != YYPACT_NINF)
02177     {
02178       yyn += YYTERROR;
02179       if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
02180         {
02181           yyn = yytable[yyn];
02182           if (0 < yyn)
02183         break;
02184         }
02185     }
02186 
02187       /* Pop the current state because it cannot handle the error token.  */
02188       if (yyssp == yyss)
02189     YYABORT;
02190 
02191 
02192       yydestruct ("Error: popping",
02193           yystos[yystate], yyvsp);
02194       YYPOPSTACK (1);
02195       yystate = *yyssp;
02196       YY_STACK_PRINT (yyss, yyssp);
02197     }
02198 
02199   *++yyvsp = yylval;
02200 
02201 
02202   /* Shift the error token.  */
02203   YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
02204 
02205   yystate = yyn;
02206   goto yynewstate;
02207 
02208 
02209 /*-------------------------------------.
02210 | yyacceptlab -- YYACCEPT comes here.  |
02211 `-------------------------------------*/
02212 yyacceptlab:
02213   yyresult = 0;
02214   goto yyreturn;
02215 
02216 /*-----------------------------------.
02217 | yyabortlab -- YYABORT comes here.  |
02218 `-----------------------------------*/
02219 yyabortlab:
02220   yyresult = 1;
02221   goto yyreturn;
02222 
02223 #if !defined(yyoverflow) || YYERROR_VERBOSE
02224 /*-------------------------------------------------.
02225 | yyexhaustedlab -- memory exhaustion comes here.  |
02226 `-------------------------------------------------*/
02227 yyexhaustedlab:
02228   yyerror (YY_("memory exhausted"));
02229   yyresult = 2;
02230   /* Fall through.  */
02231 #endif
02232 
02233 yyreturn:
02234   if (yychar != YYEMPTY)
02235      yydestruct ("Cleanup: discarding lookahead",
02236          yytoken, &yylval);
02237   /* Do not reclaim the symbols of the rule which action triggered
02238      this YYABORT or YYACCEPT.  */
02239   YYPOPSTACK (yylen);
02240   YY_STACK_PRINT (yyss, yyssp);
02241   while (yyssp != yyss)
02242     {
02243       yydestruct ("Cleanup: popping",
02244           yystos[*yyssp], yyvsp);
02245       YYPOPSTACK (1);
02246     }
02247 #ifndef yyoverflow
02248   if (yyss != yyssa)
02249     YYSTACK_FREE (yyss);
02250 #endif
02251 #if YYERROR_VERBOSE
02252   if (yymsg != yymsgbuf)
02253     YYSTACK_FREE (yymsg);
02254 #endif
02255   /* Make sure YYID is used.  */
02256   return YYID (yyresult);
02257 }
02258 
02259 
02260 
02261 /* Line 1675 of yacc.c  */
02262 #line 396 "cond.y"
02263 
02264 
02265 
02266 static int COND_IsAlpha( WCHAR x )
02267 {
02268     return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
02269             ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
02270             ( ( x == '_' ) ) );
02271 }
02272 
02273 static int COND_IsNumber( WCHAR x )
02274 {
02275     return( (( x >= '0' ) && ( x <= '9' ))  || (x =='-') || (x =='.') );
02276 }
02277 
02278 static WCHAR *strstriW( const WCHAR *str, const WCHAR *sub )
02279 {
02280     LPWSTR strlower, sublower, r;
02281     strlower = CharLowerW( strdupW( str ) );
02282     sublower = CharLowerW( strdupW( sub ) );
02283     r = strstrW( strlower, sublower );
02284     if (r)
02285         r = (LPWSTR)str + (r - strlower);
02286     msi_free( strlower );
02287     msi_free( sublower );
02288     return r;
02289 }
02290 
02291 static BOOL str_is_number( LPCWSTR str )
02292 {
02293     int i;
02294 
02295     if (!*str)
02296         return FALSE;
02297 
02298     for (i = 0; i < lstrlenW( str ); i++)
02299         if (!isdigitW(str[i]))
02300             return FALSE;
02301 
02302     return TRUE;
02303 }
02304 
02305 static INT compare_substring( LPCWSTR a, INT operator, LPCWSTR b )
02306 {
02307     int lhs, rhs;
02308 
02309     /* substring operators return 0 if LHS is missing */
02310     if (!a || !*a)
02311         return 0;
02312 
02313     /* substring operators return 1 if RHS is missing */
02314     if (!b || !*b)
02315         return 1;
02316 
02317     /* if both strings contain only numbers, use integer comparison */
02318     lhs = atoiW(a);
02319     rhs = atoiW(b);
02320     if (str_is_number(a) && str_is_number(b))
02321         return compare_int( lhs, operator, rhs );
02322 
02323     switch (operator)
02324     {
02325     case COND_SS:
02326         return strstrW( a, b ) != 0;
02327     case COND_ISS:
02328         return strstriW( a, b ) != 0;
02329     case COND_LHS:
02330     {
02331         int l = strlenW( a );
02332         int r = strlenW( b );
02333         if (r > l) return 0;
02334         return !strncmpW( a, b, r );
02335     }
02336     case COND_RHS:
02337     {
02338         int l = strlenW( a );
02339         int r = strlenW( b );
02340         if (r > l) return 0;
02341         return !strncmpW( a + (l - r), b, r );
02342     }
02343     case COND_ILHS:
02344     {
02345         int l = strlenW( a );
02346         int r = strlenW( b );
02347         if (r > l) return 0;
02348         return !strncmpiW( a, b, r );
02349     }
02350     case COND_IRHS:
02351     {
02352         int l = strlenW( a );
02353         int r = strlenW( b );
02354         if (r > l) return 0;
02355         return !strncmpiW( a + (l - r), b, r );
02356     }
02357     default:
02358         ERR("invalid substring operator\n");
02359         return 0;
02360     }
02361     return 0;
02362 }
02363 
02364 static INT compare_string( LPCWSTR a, INT operator, LPCWSTR b, BOOL convert )
02365 {
02366     if (operator >= COND_SS && operator <= COND_RHS)
02367         return compare_substring( a, operator, b );
02368 
02369     /* null and empty string are equivalent */
02370     if (!a) a = szEmpty;
02371     if (!b) b = szEmpty;
02372 
02373     if (convert && str_is_number(a) && str_is_number(b))
02374         return compare_int( atoiW(a), operator, atoiW(b) );
02375 
02376     /* a or b may be NULL */
02377     switch (operator)
02378     {
02379     case COND_LT:
02380         return strcmpW( a, b ) < 0;
02381     case COND_GT:
02382         return strcmpW( a, b ) > 0;
02383     case COND_EQ:
02384         return strcmpW( a, b ) == 0;
02385     case COND_NE:
02386         return strcmpW( a, b ) != 0;
02387     case COND_GE:
02388         return strcmpW( a, b ) >= 0;
02389     case COND_LE:
02390         return strcmpW( a, b ) <= 0;
02391     case COND_ILT:
02392         return strcmpiW( a, b ) < 0;
02393     case COND_IGT:
02394         return strcmpiW( a, b ) > 0;
02395     case COND_IEQ:
02396         return strcmpiW( a, b ) == 0;
02397     case COND_INE:
02398         return strcmpiW( a, b ) != 0;
02399     case COND_IGE:
02400         return strcmpiW( a, b ) >= 0;
02401     case COND_ILE:
02402         return strcmpiW( a, b ) <= 0;
02403     default:
02404         ERR("invalid string operator\n");
02405         return 0;
02406     }
02407     return 0;
02408 }
02409 
02410 
02411 static INT compare_int( INT a, INT operator, INT b )
02412 {
02413     switch (operator)
02414     {
02415     case COND_LT:
02416     case COND_ILT:
02417         return a < b;
02418     case COND_GT:
02419     case COND_IGT:
02420         return a > b;
02421     case COND_EQ:
02422     case COND_IEQ:
02423         return a == b;
02424     case COND_NE:
02425     case COND_INE:
02426         return a != b;
02427     case COND_GE:
02428     case COND_IGE:
02429         return a >= b;
02430     case COND_LE:
02431     case COND_ILE:
02432         return a <= b;
02433     case COND_SS:
02434     case COND_ISS:
02435         return ( a & b ) ? 1 : 0;
02436     case COND_RHS:
02437         return ( ( a & 0xffff ) == b ) ? 1 : 0;
02438     case COND_LHS:
02439         return ( ( (a>>16) & 0xffff ) == b ) ? 1 : 0;
02440     default:
02441         ERR("invalid integer operator\n");
02442         return 0;
02443     }
02444     return 0;
02445 }
02446 
02447 
02448 static int COND_IsIdent( WCHAR x )
02449 {
02450     return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' ) 
02451             || ( x == '#' ) || (x == '.') );
02452 }
02453 
02454 static int COND_GetOperator( COND_input *cond )
02455 {
02456     static const struct {
02457         const WCHAR str[4];
02458         int id;
02459     } table[] = {
02460         { {'~','<','=',0}, COND_ILE },
02461         { {'~','>','<',0}, COND_ISS },
02462         { {'~','>','>',0}, COND_IRHS },
02463         { {'~','<','>',0}, COND_INE },
02464         { {'~','>','=',0}, COND_IGE },
02465         { {'~','<','<',0}, COND_ILHS },
02466         { {'~','=',0},     COND_IEQ },
02467         { {'~','<',0},     COND_ILT },
02468         { {'~','>',0},     COND_IGT },
02469         { {'>','=',0},     COND_GE  },
02470         { {'>','<',0},     COND_SS  },
02471         { {'<','<',0},     COND_LHS },
02472         { {'<','>',0},     COND_NE  },
02473         { {'<','=',0},     COND_LE  },
02474         { {'>','>',0},     COND_RHS },
02475         { {'>',0},         COND_GT  },
02476         { {'<',0},         COND_LT  },
02477         { {0},             0        }
02478     };
02479     LPCWSTR p = &cond->str[cond->n];
02480     int i = 0, len;
02481 
02482     while ( 1 )
02483     {
02484         len = lstrlenW( table[i].str );
02485         if ( !len || 0 == strncmpW( table[i].str, p, len ) )
02486             break;
02487         i++;
02488     }
02489     cond->n += len;
02490     return table[i].id;
02491 }
02492 
02493 static int COND_GetOne( struct cond_str *str, COND_input *cond )
02494 {
02495     int rc, len = 1;
02496     WCHAR ch;
02497 
02498     str->data = &cond->str[cond->n];
02499 
02500     ch = str->data[0];
02501 
02502     switch( ch )
02503     {
02504     case 0: return 0;
02505     case '(': rc = COND_LPAR; break;
02506     case ')': rc = COND_RPAR; break;
02507     case '&': rc = COND_AMPER; break;
02508     case '!': rc = COND_EXCLAM; break;
02509     case '$': rc = COND_DOLLARS; break;
02510     case '?': rc = COND_QUESTION; break;
02511     case '%': rc = COND_PERCENT; break;
02512     case ' ': rc = COND_SPACE; break;
02513     case '=': rc = COND_EQ; break;
02514 
02515     case '~':
02516     case '<':
02517     case '>':
02518         rc = COND_GetOperator( cond );
02519         if (!rc)
02520             rc = COND_ERROR;
02521         return rc;
02522     default:
02523         rc = 0;
02524     }
02525 
02526     if ( rc )
02527     {
02528         cond->n += len;
02529         return rc;
02530     }
02531 
02532     if (ch == '"' )
02533     {
02534         LPCWSTR p = strchrW( str->data + 1, '"' );
02535         if (!p) return COND_ERROR;
02536         len = p - str->data + 1;
02537         rc = COND_LITER;
02538     }
02539     else if( COND_IsAlpha( ch ) )
02540     {
02541         static const WCHAR szNot[] = {'N','O','T',0};
02542         static const WCHAR szAnd[] = {'A','N','D',0};
02543         static const WCHAR szXor[] = {'X','O','R',0};
02544         static const WCHAR szEqv[] = {'E','Q','V',0};
02545         static const WCHAR szImp[] = {'I','M','P',0};
02546         static const WCHAR szOr[] = {'O','R',0};
02547 
02548         while( COND_IsIdent( str->data[len] ) )
02549             len++;
02550         rc = COND_IDENT;
02551 
02552         if ( len == 3 )
02553         {
02554             if ( !strncmpiW( str->data, szNot, len ) )
02555                 rc = COND_NOT;
02556             else if( !strncmpiW( str->data, szAnd, len ) )
02557                 rc = COND_AND;
02558             else if( !strncmpiW( str->data, szXor, len ) )
02559                 rc = COND_XOR;
02560             else if( !strncmpiW( str->data, szEqv, len ) )
02561                 rc = COND_EQV;
02562             else if( !strncmpiW( str->data, szImp, len ) )
02563                 rc = COND_IMP;
02564         }
02565         else if( (len == 2) && !strncmpiW( str->data, szOr, len ) )
02566             rc = COND_OR;
02567     }
02568     else if( COND_IsNumber( ch ) )
02569     {
02570         while( COND_IsNumber( str->data[len] ) )
02571             len++;
02572         rc = COND_NUMBER;
02573     }
02574     else
02575     {
02576         ERR("Got unknown character %c(%x)\n",ch,ch);
02577         return COND_ERROR;
02578     }
02579 
02580     cond->n += len;
02581     str->len = len;
02582 
02583     return rc;
02584 }
02585 
02586 static int cond_lex( void *COND_lval, COND_input *cond )
02587 {
02588     int rc;
02589     struct cond_str *str = COND_lval;
02590 
02591     do {
02592         rc = COND_GetOne( str, cond );
02593     } while (rc == COND_SPACE);
02594     
02595     return rc;
02596 }
02597 
02598 static LPWSTR COND_GetString( COND_input *cond, const struct cond_str *str )
02599 {
02600     LPWSTR ret;
02601 
02602     ret = cond_alloc( cond, (str->len+1) * sizeof (WCHAR) );
02603     if( ret )
02604     {
02605         memcpy( ret, str->data, str->len * sizeof(WCHAR));
02606         ret[str->len]=0;
02607     }
02608     TRACE("Got identifier %s\n",debugstr_w(ret));
02609     return ret;
02610 }
02611 
02612 static LPWSTR COND_GetLiteral( COND_input *cond, const struct cond_str *str )
02613 {
02614     LPWSTR ret;
02615 
02616     ret = cond_alloc( cond, (str->len-1) * sizeof (WCHAR) );
02617     if( ret )
02618     {
02619         memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );
02620         ret[str->len - 2]=0;
02621     }
02622     TRACE("Got literal %s\n",debugstr_w(ret));
02623     return ret;
02624 }
02625 
02626 static void *cond_alloc( COND_input *cond, unsigned int sz )
02627 {
02628     struct list *mem;
02629 
02630     mem = msi_alloc( sizeof (struct list) + sz );
02631     if( !mem )
02632         return NULL;
02633 
02634     list_add_head( &(cond->mem), mem );
02635     return mem + 1;
02636 }
02637 
02638 static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz )
02639 {
02640     void *new_ptr;
02641 
02642     if( !ptr )
02643         return ptr;
02644 
02645     new_ptr = cond_alloc( cond, sz );
02646     if( !new_ptr )
02647     {
02648         msi_free( ptr );
02649         return NULL;
02650     }
02651 
02652     memcpy( new_ptr, ptr, sz );
02653     msi_free( ptr );
02654     return new_ptr;
02655 }
02656 
02657 static void cond_free( void *ptr )
02658 {
02659     struct list *mem = (struct list *)ptr - 1;
02660 
02661     if( ptr )
02662     {
02663         list_remove( mem );
02664         msi_free( mem );
02665     }
02666 }
02667 
02668 static int cond_error(const char *str)
02669 {
02670     TRACE("%s\n", str );
02671     return 0;
02672 }
02673 
02674 MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
02675 {
02676     COND_input cond;
02677     MSICONDITION r;
02678     struct list *mem, *safety;
02679 
02680     TRACE("%s\n", debugstr_w( szCondition ) );
02681 
02682     if (szCondition == NULL) return MSICONDITION_NONE;
02683 
02684     cond.package = package;
02685     cond.str   = szCondition;
02686     cond.n     = 0;
02687     cond.result = MSICONDITION_ERROR;
02688 
02689     list_init( &cond.mem );
02690 
02691     if ( !cond_parse( &cond ) )
02692         r = cond.result;
02693     else
02694         r = MSICONDITION_ERROR;
02695 
02696     LIST_FOR_EACH_SAFE( mem, safety, &cond.mem )
02697     {
02698         /* The tracked memory lives directly after the list struct */
02699         void *ptr = mem + 1;
02700         if ( r != MSICONDITION_ERROR )
02701             WARN( "condition parser failed to free up some memory: %p\n", ptr );
02702         cond_free( ptr );
02703     }
02704 
02705     TRACE("%i <- %s\n", r, debugstr_w(szCondition));
02706     return r;
02707 }
02708 
02709 MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
02710 {
02711     MSIPACKAGE *package;
02712     UINT ret;
02713 
02714     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
02715     if( !package )
02716     {
02717         HRESULT hr;
02718         BSTR condition;
02719         IWineMsiRemotePackage *remote_package;
02720 
02721         remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
02722         if (!remote_package)
02723             return MSICONDITION_ERROR;
02724 
02725         condition = SysAllocString( szCondition );
02726         if (!condition)
02727         {
02728             IWineMsiRemotePackage_Release( remote_package );
02729             return ERROR_OUTOFMEMORY;
02730         }
02731 
02732         hr = IWineMsiRemotePackage_EvaluateCondition( remote_package, condition );
02733 
02734         SysFreeString( condition );
02735         IWineMsiRemotePackage_Release( remote_package );
02736 
02737         if (FAILED(hr))
02738         {
02739             if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
02740                 return HRESULT_CODE(hr);
02741 
02742             return ERROR_FUNCTION_FAILED;
02743         }
02744 
02745         return ERROR_SUCCESS;
02746     }
02747 
02748     ret = MSI_EvaluateConditionW( package, szCondition );
02749     msiobj_release( &package->hdr );
02750     return ret;
02751 }
02752 
02753 MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
02754 {
02755     LPWSTR szwCond = NULL;
02756     MSICONDITION r;
02757 
02758     szwCond = strdupAtoW( szCondition );
02759     if( szCondition && !szwCond )
02760         return MSICONDITION_ERROR;
02761 
02762     r = MsiEvaluateConditionW( hInstall, szwCond );
02763     msi_free( szwCond );
02764     return r;
02765 }
02766 

Generated on Sun May 27 2012 04:25:13 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.