* Sync with Wine 1.7.1.
CORE-7469
svn path=/trunk/; revision=60307
dialog.c
distinct.c
drop.c
- events.c
files.c
font.c
format.c
endif()
add_library(msi SHARED ${SOURCE})
-
add_idl_headers(msi_idlheader msiserver.idl)
add_typelib(msiserver.idl)
-
set_source_files_properties(msi.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/msiserver.tlb)
-
set_module_type(msi win32dll)
target_link_libraries(msi uuid ${PSEH_LIB} wine)
add_dependencies(msi msi_idlheader)
len = ptr2 - ptr;
if (!len) return ERROR_INVALID_COMMAND_LINE;
+ while (ptr[len - 1] == ' ') len--;
+
prop = msi_alloc( (len + 1) * sizeof(WCHAR) );
memcpy( prop, ptr, len * sizeof(WCHAR) );
prop[len] = 0;
static const WCHAR query [] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','I','n','s','t','a','l','l','U','I','S','e','q','u','e','n','c','e','`',' ',
- 'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',' ','>',' ','0',' ',
- 'O','R','D','E','R',' ','B','Y',' ','`','S','e','q','u','e','n','c','e','`',0};
+ 'W','H','E','R','E',' ','`','S','e','q','u','e','n','c','e','`',' ','>',' ','0',0};
MSIQUERY *view;
- UINT rc;
+ DWORD count = 0;
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
- if (rc == ERROR_SUCCESS)
+ if (!(MSI_DatabaseOpenViewW( package->db, query, &view )))
{
- msiobj_release(&view->hdr);
- return TRUE;
+ MSI_IterateRecords( view, &count, NULL, package );
+ msiobj_release( &view->hdr );
}
- return FALSE;
+ return count != 0;
}
UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
/********************************************************
* ACTION helper functions and functions that perform the actions
*******************************************************/
-static BOOL ACTION_HandleCustomAction( MSIPACKAGE* package, LPCWSTR action,
- UINT* rc, UINT script, BOOL force )
+static BOOL ACTION_HandleCustomAction( MSIPACKAGE *package, LPCWSTR action, UINT *rc, UINT script )
{
BOOL ret=FALSE;
UINT arc;
- arc = ACTION_CustomAction(package, action, script, force);
-
+ arc = ACTION_CustomAction( package, action, script );
if (arc != ERROR_CALL_NOT_IMPLEMENTED)
{
*rc = arc;
WCHAR *path;
if (!package->ProductCode) return NULL;
- if (MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE ))
- return NULL;
- path = msi_reg_get_val_str( hkey, szInstallLocation );
+ if (MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE )) return NULL;
+ if ((path = msi_reg_get_val_str( hkey, szInstallLocation )) && !path[0])
+ {
+ msi_free( path );
+ path = NULL;
+ }
RegCloseKey( hkey );
return path;
}
static UINT ACTION_CostFinalize(MSIPACKAGE *package)
{
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','C','o','n','d','i','t','i','o','n','`',0};
- static const WCHAR szOutOfDiskSpace[] = {
- 'O','u','t','O','f','D','i','s','k','S','p','a','c','e',0};
+ static const WCHAR query[] =
+ {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','C','o','n','d','i','t','i','o','n','`',0};
+ static const WCHAR szOutOfDiskSpace[] =
+ {'O','u','t','O','f','D','i','s','k','S','p','a','c','e',0};
+ static const WCHAR szPrimaryFolder[] =
+ {'P','R','I','M','A','R','Y','F','O','L','D','E','R',0};
+ static const WCHAR szPrimaryVolumePath[] =
+ {'P','r','i','m','a','r','y','V','o','l','u','m','e','P','a','t','h',0};
+ static const WCHAR szPrimaryVolumeSpaceAvailable[] =
+ {'P','r','i','m','a','r','y','V','o','l','u','m','e','S','p','a','c','e',
+ 'A','v','a','i','l','a','b','l','e',0};
MSICOMPONENT *comp;
MSIQUERY *view;
- LPWSTR level;
+ WCHAR *level, *primary_key, *primary_folder;
UINT rc;
TRACE("Building directory properties\n");
msi_set_property( package->db, szCostingComplete, szOne, -1 );
/* set default run level if not set */
level = msi_dup_property( package->db, szInstallLevel );
- if (!level)
- msi_set_property( package->db, szInstallLevel, szOne, -1 );
+ if (!level) msi_set_property( package->db, szInstallLevel, szOne, -1 );
msi_free(level);
+ if ((primary_key = msi_dup_property( package->db, szPrimaryFolder )))
+ {
+ if ((primary_folder = msi_dup_property( package->db, primary_key )))
+ {
+ if (((primary_folder[0] >= 'A' && primary_folder[0] <= 'Z') ||
+ (primary_folder[0] >= 'a' && primary_folder[0] <= 'z')) && primary_folder[1] == ':')
+ {
+ ULARGE_INTEGER free;
+
+ primary_folder[2] = 0;
+ if (GetDiskFreeSpaceExW( primary_folder, &free, NULL, NULL ))
+ {
+ static const WCHAR fmtW[] = {'%','l','u',0};
+ WCHAR buf[21];
+
+ sprintfW( buf, fmtW, free.QuadPart / 512 );
+ msi_set_property( package->db, szPrimaryVolumeSpaceAvailable, buf, -1 );
+ }
+ toupperW( primary_folder[0] );
+ msi_set_property( package->db, szPrimaryVolumePath, primary_folder, 2 );
+ }
+ msi_free( primary_folder );
+ }
+ msi_free( primary_key );
+ }
+
/* FIXME: check volume disk space */
msi_set_property( package->db, szOutOfDiskSpace, szZero, -1 );
handled = ACTION_HandleStandardAction(package, action, &rc);
if (!handled)
- handled = ACTION_HandleCustomAction(package, action, &rc, script, TRUE);
+ handled = ACTION_HandleCustomAction(package, action, &rc, script);
if (!handled)
{
handled = ACTION_HandleStandardAction(package, action, &rc);
if (!handled)
- handled = ACTION_HandleCustomAction(package, action, &rc, script, FALSE);
+ handled = ACTION_HandleCustomAction(package, action, &rc, script);
if( !handled && ACTION_DialogBox(package, action) == ERROR_SUCCESS )
handled = TRUE;
+/* A Bison parser, made by GNU Bison 2.5. */
-/* A Bison parser, made by GNU Bison 2.4.1. */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "2.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
/* Copy the first part of user declarations. */
-/* Line 189 of yacc.c */
+/* Line 268 of yacc.c */
#line 1 "cond.y"
#include <wine/unicode.h>
//#include "wine/list.h"
-#define YYLEX_PARAM info
-#define YYPARSE_PARAM info
-
-static int cond_error(const char *str);
-
WINE_DEFAULT_DEBUG_CHANNEL(msi);
typedef struct tag_yyinput
static LPWSTR COND_GetString( COND_input *info, const struct cond_str *str );
static LPWSTR COND_GetLiteral( COND_input *info, const struct cond_str *str );
static int cond_lex( void *COND_lval, COND_input *info);
+static int cond_error( COND_input *info, const char *str);
static void *cond_alloc( COND_input *cond, unsigned int sz );
static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz );
-/* Line 189 of yacc.c */
-#line 194 "cond.tab.c"
+/* Line 268 of yacc.c */
+#line 188 "cond.tab.c"
/* Enabling traces. */
#ifndef YYDEBUG
typedef union YYSTYPE
{
-/* Line 214 of yacc.c */
-#line 116 "cond.y"
+/* Line 293 of yacc.c */
+#line 114 "cond.y"
struct cond_str str;
LPWSTR string;
-/* Line 214 of yacc.c */
-#line 278 "cond.tab.c"
+/* Line 293 of yacc.c */
+#line 272 "cond.tab.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
/* Copy the second part of user declarations. */
-/* Line 264 of yacc.c */
-#line 290 "cond.tab.c"
+/* Line 343 of yacc.c */
+#line 284 "cond.tab.c"
#ifdef short
# undef short
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
#ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
# define YY_(msgid) dgettext ("bison-runtime", msgid)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
# endif
# endif
# endif
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# if (defined __cplusplus && ! defined _STDLIB_H \
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
+# define YYCOPY_NEEDED 1
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
#endif
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 28
/* YYLAST -- Last index in YYTABLE. */
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 140, 140, 146, 153, 157, 161, 165, 169, 176,
- 180, 187, 191, 195, 200, 204, 213, 222, 226, 230,
- 234, 238, 243, 248, 256, 257, 258, 259, 260, 261,
- 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
- 272, 273, 277, 281, 288, 298, 302, 311, 320, 333,
- 345, 358, 375, 385
+ 0, 138, 138, 144, 151, 155, 159, 163, 167, 174,
+ 178, 185, 189, 193, 198, 202, 211, 220, 224, 228,
+ 232, 236, 241, 246, 254, 255, 256, 257, 258, 259,
+ 260, 261, 262, 263, 264, 265, 266, 267, 268, 269,
+ 270, 271, 275, 279, 286, 296, 300, 309, 318, 331,
+ 343, 356, 373, 383
};
#endif
1, 2, 1, 1
};
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
+ number is the opposite. If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -1
static const yytype_uint8 yytable[] =
{
66, 69
};
+#define yypact_value_is_default(yystate) \
+ ((yystate) == (-15))
+
+#define yytable_value_is_error(yytable_value) \
+ YYID (0)
+
static const yytype_int8 yycheck[] =
{
7, 1, 11, 12, 13, 14, 15, 16, 17, 18,
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
+ Once GCC version 2 has supplanted version 1, this can go. However,
+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated
+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+ discussed. */
#define YYFAIL goto yyerrlab
+#if defined YYFAIL
+ /* This is here to suppress warnings from the GCC cpp's
+ -Wunused-macros. Normally we don't worry about that warning, but
+ some users do, and we want to make it easy for users to remove
+ YYFAIL uses, which will produce warnings from Bison 2.5. */
+#endif
#define YYRECOVERING() (!!yyerrstatus)
{ \
yychar = (Token); \
yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
else \
{ \
- yyerror (YY_("syntax error: cannot back up")); \
+ yyerror (info, YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (YYID (0))
#endif
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
+/* This macro is provided for backward compatibility. */
#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif
#ifdef YYLEX_PARAM
# define YYLEX yylex (&yylval, YYLEX_PARAM)
#else
-# define YYLEX yylex (&yylval)
+# define YYLEX yylex (&yylval, info)
#endif
/* Enable debugging if requested. */
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
- Type, Value); \
+ Type, Value, info); \
YYFPRINTF (stderr, "\n"); \
} \
} while (YYID (0))
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, COND_input *info)
#else
static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, info)
FILE *yyoutput;
int yytype;
YYSTYPE const * const yyvaluep;
+ COND_input *info;
#endif
{
if (!yyvaluep)
return;
+ YYUSE (info);
# ifdef YYPRINT
if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, COND_input *info)
#else
static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
+yy_symbol_print (yyoutput, yytype, yyvaluep, info)
FILE *yyoutput;
int yytype;
YYSTYPE const * const yyvaluep;
+ COND_input *info;
#endif
{
if (yytype < YYNTOKENS)
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, info);
YYFPRINTF (yyoutput, ")");
}
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule, COND_input *info)
#else
static void
-yy_reduce_print (yyvsp, yyrule)
+yy_reduce_print (yyvsp, yyrule, info)
YYSTYPE *yyvsp;
int yyrule;
+ COND_input *info;
#endif
{
int yynrhs = yyr2[yyrule];
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
- );
+ , info);
YYFPRINTF (stderr, "\n");
}
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (yyvsp, Rule); \
+ yy_reduce_print (yyvsp, Rule, info); \
} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
# define YYMAXDEPTH 10000
#endif
-\f
#if YYERROR_VERBOSE
}
# endif
-/* Copy into YYRESULT an error message about the unexpected token
- YYCHAR while in state YYSTATE. Return the number of bytes copied,
- including the terminating null byte. If YYRESULT is null, do not
- copy anything; just return the number of bytes that would be
- copied. As a special case, return 0 if an ordinary "syntax error"
- message will do. Return YYSIZE_MAXIMUM if overflow occurs during
- size calculation. */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
- int yyn = yypact[yystate];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
- if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
- return 0;
- else
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-# if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
- }
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = 0;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - Assume YYFAIL is not used. It's too flawed to consider. See
+ <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+ for details. YYERROR is fine as it does not invoke this
+ function.
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
- if (yysize_overflow)
- return YYSIZE_MAXIMUM;
+ yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
- if (yyresult)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yyresult;
- int yyi = 0;
- while ((*yyp = *yyf) != '\0')
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- }
- return yysize;
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
}
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
}
#endif /* YYERROR_VERBOSE */
-\f
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, COND_input *info)
#else
static void
-yydestruct (yymsg, yytype, yyvaluep)
+yydestruct (yymsg, yytype, yyvaluep, info)
const char *yymsg;
int yytype;
YYSTYPE *yyvaluep;
+ COND_input *info;
#endif
{
YYUSE (yyvaluep);
+ YYUSE (info);
if (!yymsg)
yymsg = "Deleting";
}
}
+
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
+int yyparse (COND_input *info);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
-
-
-
-/*-------------------------.
-| yyparse or yypush_parse. |
-`-------------------------*/
+/*----------.
+| yyparse. |
+`----------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
int
-yyparse (void)
+yyparse (COND_input *info)
#else
int
-yyparse ()
-
+yyparse (info)
+ COND_input *info;
#endif
#endif
{
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
+ if (yypact_value_is_default (yyn))
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
yyn = yytable[yyn];
if (yyn <= 0)
{
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
{
case 2:
-/* Line 1455 of yacc.c */
-#line 141 "cond.y"
+/* Line 1806 of yacc.c */
+#line 139 "cond.y"
{
COND_input* cond = (COND_input*) info;
cond->result = (yyvsp[(1) - (1)].value);
- ;}
+ }
break;
case 3:
-/* Line 1455 of yacc.c */
-#line 146 "cond.y"
+/* Line 1806 of yacc.c */
+#line 144 "cond.y"
{
COND_input* cond = (COND_input*) info;
cond->result = MSICONDITION_NONE;
- ;}
+ }
break;
case 4:
-/* Line 1455 of yacc.c */
-#line 154 "cond.y"
+/* Line 1806 of yacc.c */
+#line 152 "cond.y"
{
(yyval.value) = (yyvsp[(1) - (1)].value);
- ;}
+ }
break;
case 5:
-/* Line 1455 of yacc.c */
-#line 158 "cond.y"
+/* Line 1806 of yacc.c */
+#line 156 "cond.y"
{
(yyval.value) = (yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value);
- ;}
+ }
break;
case 6:
-/* Line 1455 of yacc.c */
-#line 162 "cond.y"
+/* Line 1806 of yacc.c */
+#line 160 "cond.y"
{
(yyval.value) = !(yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value);
- ;}
+ }
break;
case 7:
-/* Line 1455 of yacc.c */
-#line 166 "cond.y"
+/* Line 1806 of yacc.c */
+#line 164 "cond.y"
{
(yyval.value) = ( (yyvsp[(1) - (3)].value) || (yyvsp[(3) - (3)].value) ) && !( (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value) );
- ;}
+ }
break;
case 8:
-/* Line 1455 of yacc.c */
-#line 170 "cond.y"
+/* Line 1806 of yacc.c */
+#line 168 "cond.y"
{
(yyval.value) = ( (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value) ) || ( !(yyvsp[(1) - (3)].value) && !(yyvsp[(3) - (3)].value) );
- ;}
+ }
break;
case 9:
-/* Line 1455 of yacc.c */
-#line 177 "cond.y"
+/* Line 1806 of yacc.c */
+#line 175 "cond.y"
{
(yyval.value) = (yyvsp[(1) - (1)].value);
- ;}
+ }
break;
case 10:
-/* Line 1455 of yacc.c */
-#line 181 "cond.y"
+/* Line 1806 of yacc.c */
+#line 179 "cond.y"
{
(yyval.value) = (yyvsp[(1) - (3)].value) && (yyvsp[(3) - (3)].value);
- ;}
+ }
break;
case 11:
-/* Line 1455 of yacc.c */
-#line 188 "cond.y"
+/* Line 1806 of yacc.c */
+#line 186 "cond.y"
{
(yyval.value) = (yyvsp[(2) - (2)].value) ? 0 : 1;
- ;}
+ }
break;
case 12:
-/* Line 1455 of yacc.c */
-#line 192 "cond.y"
+/* Line 1806 of yacc.c */
+#line 190 "cond.y"
{
(yyval.value) = (yyvsp[(1) - (1)].value) ? 1 : 0;
- ;}
+ }
break;
case 13:
-/* Line 1455 of yacc.c */
-#line 196 "cond.y"
+/* Line 1806 of yacc.c */
+#line 194 "cond.y"
{
(yyval.value) = ((yyvsp[(1) - (1)].string) && (yyvsp[(1) - (1)].string)[0]) ? 1 : 0;
cond_free( (yyvsp[(1) - (1)].string) );
- ;}
+ }
break;
case 14:
-/* Line 1455 of yacc.c */
-#line 201 "cond.y"
+/* Line 1806 of yacc.c */
+#line 199 "cond.y"
{
(yyval.value) = compare_int( (yyvsp[(1) - (3)].value), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].value) );
- ;}
+ }
break;
case 15:
-/* Line 1455 of yacc.c */
-#line 205 "cond.y"
+/* Line 1806 of yacc.c */
+#line 203 "cond.y"
{
int num;
if (num_from_prop( (yyvsp[(1) - (3)].string), &num ))
else
(yyval.value) = ((yyvsp[(2) - (3)].value) == COND_NE || (yyvsp[(2) - (3)].value) == COND_INE );
cond_free( (yyvsp[(1) - (3)].string) );
- ;}
+ }
break;
case 16:
-/* Line 1455 of yacc.c */
-#line 214 "cond.y"
+/* Line 1806 of yacc.c */
+#line 212 "cond.y"
{
int num;
if (num_from_prop( (yyvsp[(3) - (3)].string), &num ))
else
(yyval.value) = ((yyvsp[(2) - (3)].value) == COND_NE || (yyvsp[(2) - (3)].value) == COND_INE );
cond_free( (yyvsp[(3) - (3)].string) );
- ;}
+ }
break;
case 17:
-/* Line 1455 of yacc.c */
-#line 223 "cond.y"
+/* Line 1806 of yacc.c */
+#line 221 "cond.y"
{
(yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE );
- ;}
+ }
break;
case 18:
-/* Line 1455 of yacc.c */
-#line 227 "cond.y"
+/* Line 1806 of yacc.c */
+#line 225 "cond.y"
{
(yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE );
- ;}
+ }
break;
case 19:
-/* Line 1455 of yacc.c */
-#line 231 "cond.y"
+/* Line 1806 of yacc.c */
+#line 229 "cond.y"
{
(yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), TRUE );
- ;}
+ }
break;
case 20:
-/* Line 1455 of yacc.c */
-#line 235 "cond.y"
+/* Line 1806 of yacc.c */
+#line 233 "cond.y"
{
(yyval.value) = compare_and_free_strings( (yyvsp[(1) - (3)].string), (yyvsp[(2) - (3)].value), (yyvsp[(3) - (3)].string), FALSE );
- ;}
+ }
break;
case 21:
-/* Line 1455 of yacc.c */
-#line 239 "cond.y"
+/* Line 1806 of yacc.c */
+#line 237 "cond.y"
{
(yyval.value) = 0;
cond_free( (yyvsp[(1) - (3)].string) );
- ;}
+ }
break;
case 22:
-/* Line 1455 of yacc.c */
-#line 244 "cond.y"
+/* Line 1806 of yacc.c */
+#line 242 "cond.y"
{
(yyval.value) = 0;
cond_free( (yyvsp[(3) - (3)].string) );
- ;}
+ }
break;
case 23:
-/* Line 1455 of yacc.c */
-#line 249 "cond.y"
+/* Line 1806 of yacc.c */
+#line 247 "cond.y"
{
(yyval.value) = (yyvsp[(2) - (3)].value);
- ;}
+ }
break;
case 24:
-/* Line 1455 of yacc.c */
-#line 256 "cond.y"
- { (yyval.value) = COND_EQ; ;}
+/* Line 1806 of yacc.c */
+#line 254 "cond.y"
+ { (yyval.value) = COND_EQ; }
break;
case 25:
-/* Line 1455 of yacc.c */
-#line 257 "cond.y"
- { (yyval.value) = COND_NE; ;}
+/* Line 1806 of yacc.c */
+#line 255 "cond.y"
+ { (yyval.value) = COND_NE; }
break;
case 26:
-/* Line 1455 of yacc.c */
-#line 258 "cond.y"
- { (yyval.value) = COND_LT; ;}
+/* Line 1806 of yacc.c */
+#line 256 "cond.y"
+ { (yyval.value) = COND_LT; }
break;
case 27:
-/* Line 1455 of yacc.c */
-#line 259 "cond.y"
- { (yyval.value) = COND_GT; ;}
+/* Line 1806 of yacc.c */
+#line 257 "cond.y"
+ { (yyval.value) = COND_GT; }
break;
case 28:
-/* Line 1455 of yacc.c */
-#line 260 "cond.y"
- { (yyval.value) = COND_LE; ;}
+/* Line 1806 of yacc.c */
+#line 258 "cond.y"
+ { (yyval.value) = COND_LE; }
break;
case 29:
-/* Line 1455 of yacc.c */
-#line 261 "cond.y"
- { (yyval.value) = COND_GE; ;}
+/* Line 1806 of yacc.c */
+#line 259 "cond.y"
+ { (yyval.value) = COND_GE; }
break;
case 30:
-/* Line 1455 of yacc.c */
-#line 262 "cond.y"
- { (yyval.value) = COND_SS; ;}
+/* Line 1806 of yacc.c */
+#line 260 "cond.y"
+ { (yyval.value) = COND_SS; }
break;
case 31:
-/* Line 1455 of yacc.c */
-#line 263 "cond.y"
- { (yyval.value) = COND_IEQ; ;}
+/* Line 1806 of yacc.c */
+#line 261 "cond.y"
+ { (yyval.value) = COND_IEQ; }
break;
case 32:
-/* Line 1455 of yacc.c */
-#line 264 "cond.y"
- { (yyval.value) = COND_INE; ;}
+/* Line 1806 of yacc.c */
+#line 262 "cond.y"
+ { (yyval.value) = COND_INE; }
break;
case 33:
-/* Line 1455 of yacc.c */
-#line 265 "cond.y"
- { (yyval.value) = COND_ILT; ;}
+/* Line 1806 of yacc.c */
+#line 263 "cond.y"
+ { (yyval.value) = COND_ILT; }
break;
case 34:
-/* Line 1455 of yacc.c */
-#line 266 "cond.y"
- { (yyval.value) = COND_IGT; ;}
+/* Line 1806 of yacc.c */
+#line 264 "cond.y"
+ { (yyval.value) = COND_IGT; }
break;
case 35:
-/* Line 1455 of yacc.c */
-#line 267 "cond.y"
- { (yyval.value) = COND_ILE; ;}
+/* Line 1806 of yacc.c */
+#line 265 "cond.y"
+ { (yyval.value) = COND_ILE; }
break;
case 36:
-/* Line 1455 of yacc.c */
-#line 268 "cond.y"
- { (yyval.value) = COND_IGE; ;}
+/* Line 1806 of yacc.c */
+#line 266 "cond.y"
+ { (yyval.value) = COND_IGE; }
break;
case 37:
-/* Line 1455 of yacc.c */
-#line 269 "cond.y"
- { (yyval.value) = COND_ISS; ;}
+/* Line 1806 of yacc.c */
+#line 267 "cond.y"
+ { (yyval.value) = COND_ISS; }
break;
case 38:
-/* Line 1455 of yacc.c */
-#line 270 "cond.y"
- { (yyval.value) = COND_LHS; ;}
+/* Line 1806 of yacc.c */
+#line 268 "cond.y"
+ { (yyval.value) = COND_LHS; }
break;
case 39:
-/* Line 1455 of yacc.c */
-#line 271 "cond.y"
- { (yyval.value) = COND_RHS; ;}
+/* Line 1806 of yacc.c */
+#line 269 "cond.y"
+ { (yyval.value) = COND_RHS; }
break;
case 40:
-/* Line 1455 of yacc.c */
-#line 272 "cond.y"
- { (yyval.value) = COND_ILHS; ;}
+/* Line 1806 of yacc.c */
+#line 270 "cond.y"
+ { (yyval.value) = COND_ILHS; }
break;
case 41:
-/* Line 1455 of yacc.c */
-#line 273 "cond.y"
- { (yyval.value) = COND_IRHS; ;}
+/* Line 1806 of yacc.c */
+#line 271 "cond.y"
+ { (yyval.value) = COND_IRHS; }
break;
case 42:
-/* Line 1455 of yacc.c */
-#line 278 "cond.y"
+/* Line 1806 of yacc.c */
+#line 276 "cond.y"
{
(yyval.string) = (yyvsp[(1) - (1)].string);
- ;}
+ }
break;
case 43:
-/* Line 1455 of yacc.c */
-#line 282 "cond.y"
+/* Line 1806 of yacc.c */
+#line 280 "cond.y"
{
(yyval.string) = (yyvsp[(1) - (1)].string);
- ;}
+ }
break;
case 44:
-/* Line 1455 of yacc.c */
-#line 289 "cond.y"
+/* Line 1806 of yacc.c */
+#line 287 "cond.y"
{
COND_input* cond = (COND_input*) info;
(yyval.string) = COND_GetLiteral( cond, &(yyvsp[(1) - (1)].str) );
if( !(yyval.string) )
YYABORT;
- ;}
+ }
break;
case 45:
-/* Line 1455 of yacc.c */
-#line 299 "cond.y"
+/* Line 1806 of yacc.c */
+#line 297 "cond.y"
{
(yyval.value) = (yyvsp[(1) - (1)].value);
- ;}
+ }
break;
case 46:
-/* Line 1455 of yacc.c */
-#line 303 "cond.y"
+/* Line 1806 of yacc.c */
+#line 301 "cond.y"
{
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetComponentStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action );
(yyval.value) = action;
cond_free( (yyvsp[(2) - (2)].string) );
- ;}
+ }
break;
case 47:
-/* Line 1455 of yacc.c */
-#line 312 "cond.y"
+/* Line 1806 of yacc.c */
+#line 310 "cond.y"
{
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetComponentStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action );
(yyval.value) = install;
cond_free( (yyvsp[(2) - (2)].string) );
- ;}
+ }
break;
case 48:
-/* Line 1455 of yacc.c */
-#line 321 "cond.y"
+/* Line 1806 of yacc.c */
+#line 319 "cond.y"
{
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
(yyval.value) = action;
cond_free( (yyvsp[(2) - (2)].string) );
- ;}
+ }
break;
case 49:
-/* Line 1455 of yacc.c */
-#line 334 "cond.y"
+/* Line 1806 of yacc.c */
+#line 332 "cond.y"
{
COND_input* cond = (COND_input*) info;
INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
MSI_GetFeatureStateW(cond->package, (yyvsp[(2) - (2)].string), &install, &action );
(yyval.value) = install;
cond_free( (yyvsp[(2) - (2)].string) );
- ;}
+ }
break;
case 50:
-/* Line 1455 of yacc.c */
-#line 346 "cond.y"
+/* Line 1806 of yacc.c */
+#line 344 "cond.y"
{
COND_input* cond = (COND_input*) info;
UINT len;
(yyval.string) = cond_track_mem( cond, (yyval.string), len );
}
cond_free( (yyvsp[(1) - (1)].string) );
- ;}
+ }
break;
case 51:
-/* Line 1455 of yacc.c */
-#line 359 "cond.y"
+/* Line 1806 of yacc.c */
+#line 357 "cond.y"
{
COND_input* cond = (COND_input*) info;
UINT len = GetEnvironmentVariableW( (yyvsp[(2) - (2)].string), NULL, 0 );
GetEnvironmentVariableW( (yyvsp[(2) - (2)].string), (yyval.string), len );
}
cond_free( (yyvsp[(2) - (2)].string) );
- ;}
+ }
break;
case 52:
-/* Line 1455 of yacc.c */
-#line 376 "cond.y"
+/* Line 1806 of yacc.c */
+#line 374 "cond.y"
{
COND_input* cond = (COND_input*) info;
(yyval.string) = COND_GetString( cond, &(yyvsp[(1) - (1)].str) );
if( !(yyval.string) )
YYABORT;
- ;}
+ }
break;
case 53:
-/* Line 1455 of yacc.c */
-#line 386 "cond.y"
+/* Line 1806 of yacc.c */
+#line 384 "cond.y"
{
COND_input* cond = (COND_input*) info;
LPWSTR szNum = COND_GetString( cond, &(yyvsp[(1) - (1)].str) );
YYABORT;
(yyval.value) = atoiW( szNum );
cond_free( szNum );
- ;}
+ }
break;
-/* Line 1455 of yacc.c */
-#line 2051 "cond.tab.c"
+/* Line 1806 of yacc.c */
+#line 2083 "cond.tab.c"
default: break;
}
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
++yynerrs;
#if ! YYERROR_VERBOSE
- yyerror (YY_("syntax error"));
+ yyerror (info, YY_("syntax error"));
#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
{
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
- {
- YYSIZE_T yyalloc = 2 * yysize;
- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
- yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- }
- }
-
- if (0 < yysize && yysize <= yymsg_alloc)
- {
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (yymsg);
- }
- else
- {
- yyerror (YY_("syntax error"));
- if (yysize != 0)
- goto yyexhaustedlab;
- }
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (info, yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
}
+# undef YYSYNTAX_ERROR
#endif
}
else
{
yydestruct ("Error: discarding",
- yytoken, &yylval);
+ yytoken, &yylval, info);
yychar = YYEMPTY;
}
}
for (;;)
{
yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
+ if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
+ yystos[yystate], yyvsp, info);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
yyexhaustedlab:
- yyerror (YY_("memory exhausted"));
+ yyerror (info, YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
if (yychar != YYEMPTY)
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, info);
+ }
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
+ yystos[*yyssp], yyvsp, info);
YYPOPSTACK (1);
}
#ifndef yyoverflow
-/* Line 1675 of yacc.c */
-#line 396 "cond.y"
+/* Line 2067 of yacc.c */
+#line 394 "cond.y"
}
}
-static int cond_error(const char *str)
+static int cond_error( COND_input *info, const char *str )
{
TRACE("%s\n", str );
return 0;
#include "wine/unicode.h"
#include "wine/list.h"
-#define YYLEX_PARAM info
-#define YYPARSE_PARAM info
-
-static int cond_error(const char *str);
-
WINE_DEFAULT_DEBUG_CHANNEL(msi);
typedef struct tag_yyinput
static LPWSTR COND_GetString( COND_input *info, const struct cond_str *str );
static LPWSTR COND_GetLiteral( COND_input *info, const struct cond_str *str );
static int cond_lex( void *COND_lval, COND_input *info);
+static int cond_error( COND_input *info, const char *str);
static void *cond_alloc( COND_input *cond, unsigned int sz );
static void *cond_track_mem( COND_input *cond, void *ptr, unsigned int sz );
%}
+%lex-param { COND_input *info }
+%parse-param { COND_input *info }
%pure-parser
%union
}
}
-static int cond_error(const char *str)
+static int cond_error( COND_input *info, const char *str )
{
TRACE("%s\n", str );
return 0;
TRACE("exe %s arg %s\n", debugstr_w(exe), debugstr_w(arg));
handle = execute_command( exe, arg, szCRoot );
+ msi_free( exe );
msi_free( arg );
if (handle == INVALID_HANDLE_VALUE) return ERROR_SUCCESS;
return wait_process_handle( package, type, handle, action );
return wait_thread_handle( info );
}
-static BOOL action_type_matches_script( MSIPACKAGE *package, UINT type, UINT script )
+static BOOL action_type_matches_script( UINT type, UINT script )
{
switch (script)
{
return ERROR_SUCCESS;
}
-UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL execute)
+UINT ACTION_CustomAction( MSIPACKAGE *package, LPCWSTR action, UINT script )
{
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
if (type & msidbCustomActionTypeNoImpersonate)
WARN("msidbCustomActionTypeNoImpersonate not handled\n");
- if (!execute || !action_type_matches_script( package, type, script ))
+ if (!action_type_matches_script( type, script ))
{
rc = defer_custom_action( package, action, type );
goto end;
r = MSI_ViewGetColumnInfo(mergeview, MSICOLINFO_NAMES, &mergerec);
if (r != ERROR_SUCCESS)
+ {
+ msiobj_release(&dbrec->hdr);
return r;
+ }
count = MSI_RecordGetFieldCount(dbrec);
for (i = 1; i <= count; i++)
r = MSI_ViewGetColumnInfo(mergeview, MSICOLINFO_TYPES, &mergerec);
if (r != ERROR_SUCCESS)
+ {
+ msiobj_release(&dbrec->hdr);
return r;
+ }
count = MSI_RecordGetFieldCount(dbrec);
for (i = 1; i <= count; i++)
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2005 Mike McCormack for CodeWeavers
+ * Copyright 2005 Aric Stewart for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include <winreg.h>
#include <shlwapi.h>
#include <msiserver.h>
+#include <shellapi.h>
#include <wine/debug.h>
#include <wine/unicode.h>
typedef struct msi_control_tag msi_control;
typedef UINT (*msi_handler)( msi_dialog *, msi_control *, WPARAM );
typedef void (*msi_update)( msi_dialog *, msi_control * );
+typedef UINT (*control_event_handler)( msi_dialog *, const WCHAR *, const WCHAR * );
struct msi_control_tag
{
{
MSIPACKAGE *package;
msi_dialog *parent;
- msi_dialog_event_handler event_handler;
+ control_event_handler event_handler;
BOOL finished;
INT scale;
DWORD attributes;
WCHAR name[1];
};
+struct subscriber
+{
+ struct list entry;
+ msi_dialog *dialog;
+ WCHAR *event;
+ WCHAR *control;
+ WCHAR *attribute;
+};
+
typedef UINT (*msi_dialog_control_func)( msi_dialog *dialog, MSIRECORD *rec );
struct control_handler
{
static const WCHAR szSelectionDescription[] = {'S','e','l','e','c','t','i','o','n','D','e','s','c','r','i','p','t','i','o','n',0};
static const WCHAR szSelectionPath[] = {'S','e','l','e','c','t','i','o','n','P','a','t','h',0};
static const WCHAR szProperty[] = {'P','r','o','p','e','r','t','y',0};
+static const WCHAR szHyperLink[] = {'H','y','p','e','r','L','i','n','k',0};
/* dialog sequencing */
return prop;
}
-msi_dialog *msi_dialog_get_parent( msi_dialog *dialog )
-{
- return dialog->parent;
-}
-
-LPWSTR msi_dialog_get_name( msi_dialog *dialog )
-{
- return dialog->name;
-}
-
/*
* msi_dialog_get_style
*
msi_free( t );
}
-static msi_control *msi_dialog_create_window( msi_dialog *dialog,
- MSIRECORD *rec, DWORD exstyle, LPCWSTR szCls, LPCWSTR name, LPCWSTR text,
- DWORD style, HWND parent )
+static msi_control *dialog_create_window( msi_dialog *dialog, MSIRECORD *rec, DWORD exstyle,
+ const WCHAR *szCls, const WCHAR *name, const WCHAR *text,
+ DWORD style, HWND parent )
{
DWORD x, y, width, height;
LPWSTR font = NULL, title_font = NULL;
return msi_seltree_feature_from_item( control->hwnd, info->selected );
}
-/* called from the Control Event subscription code */
-void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
- LPCWSTR attribute, MSIRECORD *rec )
+static void dialog_handle_event( msi_dialog *dialog, const WCHAR *control,
+ const WCHAR *attribute, MSIRECORD *rec )
{
msi_control* ctrl;
- LPCWSTR font_text, text = NULL;
- LPWSTR font;
ctrl = msi_dialog_find_control( dialog, control );
if (!ctrl)
return;
if( !strcmpW( attribute, szText ) )
{
+ const WCHAR *font_text, *text = NULL;
+ WCHAR *font, *text_fmt = NULL;
+
font_text = MSI_RecordGetString( rec , 1 );
font = msi_dialog_get_style( font_text, &text );
- if (!text) text = szEmpty;
+ deformat_string( dialog->package, text, &text_fmt );
+ if (text_fmt) text = text_fmt;
+ else text = szEmpty;
+
SetWindowTextW( ctrl->hwnd, text );
+
msi_free( font );
+ msi_free( text_fmt );
msi_dialog_check_messages( NULL );
}
else if( !strcmpW( attribute, szProgress ) )
}
}
-static void msi_dialog_map_events(msi_dialog* dialog, LPCWSTR control)
+static void event_subscribe( msi_dialog *dialog, const WCHAR *event, const WCHAR *control, const WCHAR *attribute )
{
- static const WCHAR Query[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ struct subscriber *sub;
+
+ TRACE("event %s control %s attribute %s\n", debugstr_w(event), debugstr_w(control), debugstr_w(attribute));
+
+ LIST_FOR_EACH_ENTRY( sub, &dialog->package->subscriptions, struct subscriber, entry )
+ {
+ if (!strcmpiW( sub->event, event ) &&
+ !strcmpiW( sub->control, control ) &&
+ !strcmpiW( sub->attribute, attribute ))
+ {
+ TRACE("already subscribed\n");
+ return;
+ };
+ }
+ if (!(sub = msi_alloc( sizeof(*sub) ))) return;
+ sub->dialog = dialog;
+ sub->event = strdupW( event );
+ sub->control = strdupW( control );
+ sub->attribute = strdupW( attribute );
+ list_add_tail( &dialog->package->subscriptions, &sub->entry );
+}
+
+struct dialog_control
+{
+ msi_dialog *dialog;
+ const WCHAR *control;
+};
+
+static UINT map_event( MSIRECORD *row, void *param )
+{
+ struct dialog_control *dc = param;
+ const WCHAR *event = MSI_RecordGetString( row, 3 );
+ const WCHAR *attribute = MSI_RecordGetString( row, 4 );
+
+ event_subscribe( dc->dialog, event, dc->control, attribute );
+ return ERROR_SUCCESS;
+}
+
+static void dialog_map_events( msi_dialog *dialog, const WCHAR *control )
+{
+ static const WCHAR queryW[] =
+ {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','E','v','e','n','t','M','a','p','p','i','n','g','`',' ',
- 'W','H','E','R','E',' ',
- '`','D','i','a','l','o','g','_','`',' ','=',' ','\'','%','s','\'',' ',
- 'A','N','D',' ',
- '`','C','o','n','t','r','o','l','_','`',' ','=',' ','\'','%','s','\'',0
+ 'W','H','E','R','E',' ','`','D','i','a','l','o','g','_','`',' ','=',' ','\'','%','s','\'',' ',
+ 'A','N','D',' ','`','C','o','n','t','r','o','l','_','`',' ','=',' ','\'','%','s','\'',0};
+ MSIQUERY *view;
+ struct dialog_control dialog_control =
+ {
+ dialog,
+ control
};
- MSIRECORD *row;
- LPCWSTR event, attribute;
- row = MSI_QueryGetRecord( dialog->package->db, Query, dialog->name, control );
- if (!row)
- return;
-
- event = MSI_RecordGetString( row, 3 );
- attribute = MSI_RecordGetString( row, 4 );
- ControlEvent_SubscribeToEvent( dialog->package, dialog, event, control, attribute );
- msiobj_release( &row->hdr );
+ if (!MSI_OpenQuery( dialog->package->db, &view, queryW, dialog->name, control ))
+ {
+ MSI_IterateRecords( view, NULL, map_event, &dialog_control );
+ msiobj_release( &view->hdr );
+ }
}
/* everything except radio buttons */
if( attributes & msidbControlAttributesSunken )
exstyle |= WS_EX_CLIENTEDGE;
- msi_dialog_map_events(dialog, name);
+ dialog_map_events( dialog, name );
- return msi_dialog_create_window( dialog, rec, exstyle, szCls, name,
- text, style, dialog->hwnd );
+ return dialog_create_window( dialog, rec, exstyle, szCls, name, text, style, dialog->hwnd );
}
struct msi_text_info
(LONG_PTR)MSIText_WndProc );
SetPropW( control->hwnd, szButtonData, info );
- ControlEvent_SubscribeToEvent( dialog->package, dialog,
- szSelectionPath, control_name, szSelectionPath );
-
+ event_subscribe( dialog, szSelectionPath, control_name, szSelectionPath );
return ERROR_SUCCESS;
}
deformat_string( dialog->package, event, &event_fmt );
deformat_string( dialog->package, arg, &arg_fmt );
- dialog->event_handler( dialog->package, event_fmt, arg_fmt, dialog );
+ dialog->event_handler( dialog, event_fmt, arg_fmt );
msi_free( event_fmt );
msi_free( arg_fmt );
if( attributes & msidbControlAttributesSunken )
exstyle |= WS_EX_CLIENTEDGE;
- msi_dialog_map_events(dialog, name);
+ dialog_map_events( dialog, name );
control = msi_alloc( FIELD_OFFSET(msi_control, name[strlenW( name ) + 1] ));
if (!control)
if( !control )
return ERROR_FUNCTION_FAILED;
- ControlEvent_SubscribeToEvent( dialog->package, dialog,
- szSetProgress, control->name, szProgress );
+ event_subscribe( dialog, szSetProgress, control->name, szProgress );
return ERROR_SUCCESS;
}
if( ~attributes & msidbControlAttributesEnabled )
style |= WS_DISABLED;
- control = msi_dialog_create_window( dialog, rec, 0, szButton, name, text,
- style, group->parent->hwnd );
+ control = dialog_create_window( dialog, rec, 0, szButton, name, text, style,
+ group->parent->hwnd );
if (!control)
return ERROR_FUNCTION_FAILED;
control->handler = msi_dialog_radiogroup_handler;
rec = MSI_CreateRecord( 1 );
MSI_RecordSetStringW( rec, 1, MSI_RecordGetString( row, 4 ) );
- ControlEvent_FireSubscribedEvent( dialog->package, szSelectionDescription, rec );
+ msi_event_fire( dialog->package, szSelectionDescription, rec );
dir = MSI_RecordGetString( row, 7 );
if (dir)
else
MSI_RecordSetStringW( rec, 1, NULL );
- ControlEvent_FireSubscribedEvent( dialog->package, szSelectionPath, rec );
+ msi_event_fire( dialog->package, szSelectionPath, rec );
done:
msiobj_release(&row->hdr);
(LONG_PTR)MSISelectionTree_WndProc );
SetPropW( control->hwnd, szButtonData, info );
- ControlEvent_SubscribeToEvent( dialog->package, dialog,
- szSelectionPath, control_name, szProperty );
+ event_subscribe( dialog, szSelectionPath, control_name, szProperty );
/* initialize it */
msi_seltree_create_imagelist( control->hwnd );
return ERROR_SUCCESS;
}
+static UINT msi_dialog_hyperlink_handler( msi_dialog *dialog, msi_control *control, WPARAM param )
+{
+ static const WCHAR hrefW[] = {'h','r','e','f'};
+ static const WCHAR openW[] = {'o','p','e','n',0};
+ int len, len_href = sizeof(hrefW) / sizeof(hrefW[0]);
+ const WCHAR *p, *q;
+ WCHAR quote = 0;
+ LITEM item;
+
+ item.mask = LIF_ITEMINDEX | LIF_URL;
+ item.iLink = 0;
+ item.szUrl[0] = 0;
+
+ SendMessageW( control->hwnd, LM_GETITEM, 0, (LPARAM)&item );
+
+ p = item.szUrl;
+ while (*p && *p != '<') p++;
+ if (!*p++) return ERROR_SUCCESS;
+ if (toupperW( *p++ ) != 'A' || !isspaceW( *p++ )) return ERROR_SUCCESS;
+ while (*p && isspaceW( *p )) p++;
+
+ len = strlenW( p );
+ if (len > len_href && !memicmpW( p, hrefW, len_href ))
+ {
+ p += len_href;
+ while (*p && isspaceW( *p )) p++;
+ if (!*p || *p++ != '=') return ERROR_SUCCESS;
+ while (*p && isspaceW( *p )) p++;
+
+ if (*p == '\"' || *p == '\'') quote = *p++;
+ q = p;
+ if (quote)
+ {
+ while (*q && *q != quote) q++;
+ if (*q != quote) return ERROR_SUCCESS;
+ }
+ else
+ {
+ while (*q && *q != '>' && !isspaceW( *q )) q++;
+ if (!*q) return ERROR_SUCCESS;
+ }
+ item.szUrl[q - item.szUrl] = 0;
+ ShellExecuteW( NULL, openW, p, NULL, NULL, SW_SHOWNORMAL );
+ }
+ return ERROR_SUCCESS;
+}
+
+static UINT msi_dialog_hyperlink( msi_dialog *dialog, MSIRECORD *rec )
+{
+ msi_control *control;
+ DWORD style = WS_CHILD | WS_TABSTOP | WS_GROUP;
+ const WCHAR *text = MSI_RecordGetString( rec, 10 );
+ int len = strlenW( text );
+ LITEM item;
+
+ control = msi_dialog_add_control( dialog, rec, WC_LINK, style );
+ if (!control)
+ return ERROR_FUNCTION_FAILED;
+
+ control->attributes = MSI_RecordGetInteger( rec, 8 );
+ control->handler = msi_dialog_hyperlink_handler;
+
+ item.mask = LIF_ITEMINDEX | LIF_STATE | LIF_URL;
+ item.iLink = 0;
+ item.state = LIS_ENABLED;
+ item.stateMask = LIS_ENABLED;
+ if (len < L_MAX_URL_LENGTH) strcpyW( item.szUrl, text );
+ else item.szUrl[0] = 0;
+
+ SendMessageW( control->hwnd, LM_SETITEM, 0, (LPARAM)&item );
+
+ return ERROR_SUCCESS;
+}
+
static const struct control_handler msi_dialog_handler[] =
{
{ szText, msi_dialog_text_control },
{ szDirectoryList, msi_dialog_directory_list },
{ szVolumeCostList, msi_dialog_volumecost_list },
{ szVolumeSelectCombo, msi_dialog_volumeselect_combo },
+ { szHyperLink, msi_dialog_hyperlink }
};
#define NUM_CONTROL_TYPES (sizeof msi_dialog_handler/sizeof msi_dialog_handler[0])
if (!dialog->default_font)
{
dialog->default_font = strdupW(dfv);
+ msiobj_release( &rec->hdr );
if (!dialog->default_font) return -1;
}
return 0;
}
-static void msi_dialog_setfocus( msi_dialog *dialog )
+static void dialog_setfocus( msi_dialog *dialog )
{
HWND hwnd = dialog->hWndFocus;
if( LOWORD(wParam) == WA_INACTIVE )
dialog->hWndFocus = GetFocus();
else
- msi_dialog_setfocus( dialog );
+ dialog_setfocus( dialog );
return 0;
case WM_SETFOCUS:
- msi_dialog_setfocus( dialog );
+ dialog_setfocus( dialog );
return 0;
/* bounce back to our subclassed static control */
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
+static void process_pending_messages( HWND hdlg )
+{
+ MSG msg;
+
+ while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
+ {
+ if (hdlg && IsDialogMessageW( hdlg, &msg )) continue;
+ TranslateMessage( &msg );
+ DispatchMessageW( &msg );
+ }
+}
+
+static UINT dialog_run_message_loop( msi_dialog *dialog )
+{
+ DWORD style;
+ HWND hwnd;
+
+ if( uiThreadId != GetCurrentThreadId() )
+ return SendMessageW( hMsiHiddenWindow, WM_MSI_DIALOG_CREATE, 0, (LPARAM) dialog );
+
+ /* create the dialog window, don't show it yet */
+ style = WS_OVERLAPPED;
+ if( dialog->attributes & msidbDialogAttributesVisible )
+ style |= WS_VISIBLE;
+
+ hwnd = CreateWindowW( szMsiDialogClass, dialog->name, style,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ NULL, NULL, NULL, dialog );
+ if( !hwnd )
+ {
+ ERR("Failed to create dialog %s\n", debugstr_w( dialog->name ));
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ ShowWindow( hwnd, SW_SHOW );
+ /* UpdateWindow( hwnd ); - and causes the transparent static controls not to paint */
+
+ if( dialog->attributes & msidbDialogAttributesModal )
+ {
+ while( !dialog->finished )
+ {
+ MsgWaitForMultipleObjects( 0, NULL, 0, INFINITE, QS_ALLINPUT );
+ process_pending_messages( dialog->hwnd );
+ }
+ }
+ else
+ return ERROR_IO_PENDING;
+
+ return ERROR_SUCCESS;
+}
+
static LRESULT WINAPI MSIHiddenWindowProc( HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
switch (msg)
{
case WM_MSI_DIALOG_CREATE:
- return msi_dialog_run_message_loop( dialog );
+ return dialog_run_message_loop( dialog );
case WM_MSI_DIALOG_DESTROY:
msi_dialog_destroy( dialog );
return 0;
return DefWindowProcW( hwnd, msg, wParam, lParam );
}
-static BOOL msi_dialog_register_class( void )
+static BOOL dialog_register_class( void )
{
WNDCLASSW cls;
return TRUE;
}
-/* functions that interface to other modules within MSI */
-
-msi_dialog *msi_dialog_create( MSIPACKAGE* package,
- LPCWSTR szDialogName, msi_dialog *parent,
- msi_dialog_event_handler event_handler )
+static msi_dialog *dialog_create( MSIPACKAGE *package, const WCHAR *name, msi_dialog *parent,
+ control_event_handler event_handler )
{
MSIRECORD *rec = NULL;
msi_dialog *dialog;
- TRACE("%p %s\n", package, debugstr_w(szDialogName));
+ TRACE("%s\n", debugstr_w(name));
- if (!hMsiHiddenWindow)
- msi_dialog_register_class();
+ if (!hMsiHiddenWindow) dialog_register_class();
/* allocate the structure for the dialog to use */
- dialog = msi_alloc_zero( FIELD_OFFSET( msi_dialog, name[strlenW( szDialogName ) + 1] ));
+ dialog = msi_alloc_zero( FIELD_OFFSET( msi_dialog, name[strlenW( name ) + 1] ));
if( !dialog )
return NULL;
- strcpyW( dialog->name, szDialogName );
+ strcpyW( dialog->name, name );
dialog->parent = parent;
msiobj_addref( &package->hdr );
dialog->package = package;
return dialog;
}
-static void msi_process_pending_messages( HWND hdlg )
-{
- MSG msg;
-
- while( PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ) )
- {
- if( hdlg && IsDialogMessageW( hdlg, &msg ))
- continue;
- TranslateMessage( &msg );
- DispatchMessageW( &msg );
- }
-}
-
void msi_dialog_end_dialog( msi_dialog *dialog )
{
TRACE("%p\n", dialog);
/* there's two choices for the UI thread */
while (1)
{
- msi_process_pending_messages( NULL );
+ process_pending_messages( NULL );
if( !handle )
break;
}
}
-UINT msi_dialog_run_message_loop( msi_dialog *dialog )
+static void dialog_do_preview( msi_dialog *dialog )
{
- DWORD style;
- HWND hwnd;
+ TRACE("\n");
+ dialog->attributes |= msidbDialogAttributesVisible;
+ dialog->attributes &= ~msidbDialogAttributesModal;
+ dialog_run_message_loop( dialog );
+}
- if( uiThreadId != GetCurrentThreadId() )
- return SendMessageW( hMsiHiddenWindow, WM_MSI_DIALOG_CREATE, 0, (LPARAM) dialog );
+static void free_subscriber( struct subscriber *sub )
+{
+ msi_free( sub->event );
+ msi_free( sub->control );
+ msi_free( sub->attribute );
+ msi_free( sub );
+}
- /* create the dialog window, don't show it yet */
- style = WS_OVERLAPPED;
- if( dialog->attributes & msidbDialogAttributesVisible )
- style |= WS_VISIBLE;
+static void event_cleanup_subscriptions( MSIPACKAGE *package, const WCHAR *dialog )
+{
+ struct list *item, *next;
- hwnd = CreateWindowW( szMsiDialogClass, dialog->name, style,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, NULL, dialog );
- if( !hwnd )
+ LIST_FOR_EACH_SAFE( item, next, &package->subscriptions )
{
- ERR("Failed to create dialog %s\n", debugstr_w( dialog->name ));
- return ERROR_FUNCTION_FAILED;
- }
-
- ShowWindow( hwnd, SW_SHOW );
- /* UpdateWindow( hwnd ); - and causes the transparent static controls not to paint */
+ struct subscriber *sub = LIST_ENTRY( item, struct subscriber, entry );
- if( dialog->attributes & msidbDialogAttributesModal )
- {
- while( !dialog->finished )
- {
- MsgWaitForMultipleObjects( 0, NULL, 0, INFINITE, QS_ALLINPUT );
- msi_process_pending_messages( dialog->hwnd );
- }
+ if (strcmpW( sub->dialog->name, dialog )) continue;
+ list_remove( &sub->entry );
+ free_subscriber( sub );
}
- else
- return ERROR_IO_PENDING;
-
- return ERROR_SUCCESS;
-}
-
-static void msi_dialog_do_preview( msi_dialog *dialog )
-{
- TRACE("\n");
- dialog->attributes |= msidbDialogAttributesVisible;
- dialog->attributes &= ~msidbDialogAttributesModal;
- msi_dialog_run_message_loop( dialog );
}
void msi_dialog_destroy( msi_dialog *dialog )
DestroyWindow( dialog->hwnd );
/* unsubscribe events */
- ControlEvent_CleanupDialogSubscriptions(dialog->package, dialog->name);
+ event_cleanup_subscriptions( dialog->package, dialog->name );
/* destroy the list of controls */
while( !list_empty( &dialog->controls ) )
uiThreadId = 0;
}
-static UINT error_dialog_handler(MSIPACKAGE *package, LPCWSTR event,
- LPCWSTR argument, msi_dialog* dialog)
+void msi_event_cleanup_all_subscriptions( MSIPACKAGE *package )
+{
+ struct list *item, *next;
+
+ LIST_FOR_EACH_SAFE( item, next, &package->subscriptions )
+ {
+ struct subscriber *sub = LIST_ENTRY( item, struct subscriber, entry );
+ list_remove( &sub->entry );
+ free_subscriber( sub );
+ }
+}
+
+static UINT error_dialog_handler( msi_dialog *dialog, const WCHAR *event, const WCHAR *argument )
{
static const WCHAR end_dialog[] = {'E','n','d','D','i','a','l','o','g',0};
static const WCHAR error_abort[] = {'E','r','r','o','r','A','b','o','r','t',0};
if ( !strcmpW( argument, error_abort ) || !strcmpW( argument, error_cancel ) ||
!strcmpW( argument, error_no ) )
{
- msi_set_property( package->db, result_prop, error_abort, -1 );
+ msi_set_property( dialog->package->db, result_prop, error_abort, -1 );
}
- ControlEvent_CleanupSubscriptions(package);
+ msi_event_cleanup_all_subscriptions( dialog->package );
msi_dialog_end_dialog( dialog );
return ERROR_SUCCESS;
if ( r != ERROR_SUCCESS )
return r;
- dialog = msi_dialog_create( package, error_dialog, package->dialog,
- error_dialog_handler );
+ dialog = dialog_create( package, error_dialog, package->dialog, error_dialog_handler );
if ( !dialog )
return ERROR_FUNCTION_FAILED;
dialog->finished = FALSE;
- r = msi_dialog_run_message_loop( dialog );
+ r = dialog_run_message_loop( dialog );
if ( r != ERROR_SUCCESS )
goto done;
return r;
}
-static UINT preview_event_handler( MSIPACKAGE *package, LPCWSTR event,
- LPCWSTR argument, msi_dialog *dialog )
+static UINT preview_event_handler( msi_dialog *dialog, const WCHAR *event, const WCHAR *argument )
{
MESSAGE("Preview dialog event '%s' (arg='%s')\n", debugstr_w(event), debugstr_w(argument));
return ERROR_SUCCESS;
/* an empty name means we should just destroy the current preview dialog */
if (szDialogName)
{
- dialog = msi_dialog_create( preview->package, szDialogName, NULL, preview_event_handler );
+ dialog = dialog_create( preview->package, szDialogName, NULL, preview_event_handler );
if (dialog)
- msi_dialog_do_preview( dialog );
+ dialog_do_preview( dialog );
else
r = ERROR_FUNCTION_FAILED;
}
FIXME("%d %s %s\n", hPreview, debugstr_a(szControlName), debugstr_a(szBillboard));
return ERROR_CALL_NOT_IMPLEMENTED;
}
+
+typedef UINT (*event_handler)( msi_dialog *, const WCHAR * );
+
+struct control_event
+{
+ const WCHAR *event;
+ event_handler handler;
+};
+
+static UINT dialog_event_handler( msi_dialog *, const WCHAR *, const WCHAR * );
+
+/* create a dialog box and run it if it's modal */
+static UINT event_do_dialog( MSIPACKAGE *package, const WCHAR *name, msi_dialog *parent, BOOL destroy_modeless )
+{
+ msi_dialog *dialog;
+ UINT r;
+
+ /* create a new dialog */
+ dialog = dialog_create( package, name, parent, dialog_event_handler );
+ if (dialog)
+ {
+ /* kill the current modeless dialog */
+ if (destroy_modeless && package->dialog)
+ {
+ msi_dialog_destroy( package->dialog );
+ package->dialog = NULL;
+ }
+
+ /* modeless dialogs return an error message */
+ r = dialog_run_message_loop( dialog );
+ if (r == ERROR_SUCCESS)
+ msi_dialog_destroy( dialog );
+ else
+ package->dialog = dialog;
+ }
+ else r = ERROR_FUNCTION_FAILED;
+ return r;
+}
+
+/* end a modal dialog box */
+static UINT event_end_dialog( msi_dialog *dialog, const WCHAR *argument )
+{
+ static const WCHAR exitW[] = {'E','x','i','t',0};
+ static const WCHAR retryW[] = {'R','e','t','r','y',0};
+ static const WCHAR ignoreW[] = {'I','g','n','o','r','e',0};
+ static const WCHAR returnW[] = {'R','e','t','u','r','n',0};
+
+ if (!strcmpW( argument, exitW ))
+ dialog->package->CurrentInstallState = ERROR_INSTALL_USEREXIT;
+ else if (!strcmpW( argument, retryW ))
+ dialog->package->CurrentInstallState = ERROR_INSTALL_SUSPEND;
+ else if (!strcmpW( argument, ignoreW ))
+ dialog->package->CurrentInstallState = ERROR_SUCCESS;
+ else if (!strcmpW( argument, returnW ))
+ {
+ msi_dialog *parent = dialog->parent;
+ msi_free( dialog->package->next_dialog );
+ dialog->package->next_dialog = (parent) ? strdupW( parent->name ) : NULL;
+ dialog->package->CurrentInstallState = ERROR_SUCCESS;
+ }
+ else
+ {
+ ERR("Unknown argument string %s\n", debugstr_w(argument));
+ dialog->package->CurrentInstallState = ERROR_FUNCTION_FAILED;
+ }
+ event_cleanup_subscriptions( dialog->package, dialog->name );
+ msi_dialog_end_dialog( dialog );
+ return ERROR_SUCCESS;
+}
+
+/* transition from one modal dialog to another modal dialog */
+static UINT event_new_dialog( msi_dialog *dialog, const WCHAR *argument )
+{
+ /* store the name of the next dialog, and signal this one to end */
+ dialog->package->next_dialog = strdupW( argument );
+ msi_event_cleanup_all_subscriptions( dialog->package );
+ msi_dialog_end_dialog( dialog );
+ return ERROR_SUCCESS;
+}
+
+/* create a new child dialog of an existing modal dialog */
+static UINT event_spawn_dialog( msi_dialog *dialog, const WCHAR *argument )
+{
+ /* don't destroy a modeless dialogs that might be our parent */
+ event_do_dialog( dialog->package, argument, dialog, FALSE );
+ if (dialog->package->CurrentInstallState != ERROR_SUCCESS) msi_dialog_end_dialog( dialog );
+ return ERROR_SUCCESS;
+}
+
+/* creates a dialog that remains up for a period of time based on a condition */
+static UINT event_spawn_wait_dialog( msi_dialog *dialog, const WCHAR *argument )
+{
+ FIXME("doing nothing\n");
+ return ERROR_SUCCESS;
+}
+
+static UINT event_do_action( msi_dialog *dialog, const WCHAR *argument )
+{
+ ACTION_PerformAction( dialog->package, argument, SCRIPT_NONE );
+ return ERROR_SUCCESS;
+}
+
+static UINT event_add_local( msi_dialog *dialog, const WCHAR *argument )
+{
+ MSIFEATURE *feature;
+
+ LIST_FOR_EACH_ENTRY( feature, &dialog->package->features, MSIFEATURE, entry )
+ {
+ if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
+ {
+ if (feature->ActionRequest != INSTALLSTATE_LOCAL)
+ msi_set_property( dialog->package->db, szPreselected, szOne, -1 );
+ MSI_SetFeatureStateW( dialog->package, feature->Feature, INSTALLSTATE_LOCAL );
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+static UINT event_remove( msi_dialog *dialog, const WCHAR *argument )
+{
+ MSIFEATURE *feature;
+
+ LIST_FOR_EACH_ENTRY( feature, &dialog->package->features, MSIFEATURE, entry )
+ {
+ if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
+ {
+ if (feature->ActionRequest != INSTALLSTATE_ABSENT)
+ msi_set_property( dialog->package->db, szPreselected, szOne, -1 );
+ MSI_SetFeatureStateW( dialog->package, feature->Feature, INSTALLSTATE_ABSENT );
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+static UINT event_add_source( msi_dialog *dialog, const WCHAR *argument )
+{
+ MSIFEATURE *feature;
+
+ LIST_FOR_EACH_ENTRY( feature, &dialog->package->features, MSIFEATURE, entry )
+ {
+ if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
+ {
+ if (feature->ActionRequest != INSTALLSTATE_SOURCE)
+ msi_set_property( dialog->package->db, szPreselected, szOne, -1 );
+ MSI_SetFeatureStateW( dialog->package, feature->Feature, INSTALLSTATE_SOURCE );
+ }
+ }
+ return ERROR_SUCCESS;
+}
+
+void msi_event_fire( MSIPACKAGE *package, const WCHAR *event, MSIRECORD *rec )
+{
+ struct subscriber *sub;
+
+ TRACE("firing event %s\n", debugstr_w(event));
+
+ LIST_FOR_EACH_ENTRY( sub, &package->subscriptions, struct subscriber, entry )
+ {
+ if (strcmpiW( sub->event, event )) continue;
+ dialog_handle_event( sub->dialog, sub->control, sub->attribute, rec );
+ }
+}
+
+static UINT event_set_target_path( msi_dialog *dialog, const WCHAR *argument )
+{
+ WCHAR *path = msi_dup_property( dialog->package->db, argument );
+ MSIRECORD *rec = MSI_CreateRecord( 1 );
+ UINT r = ERROR_SUCCESS;
+
+ MSI_RecordSetStringW( rec, 1, path );
+ msi_event_fire( dialog->package, szSelectionPath, rec );
+ if (path)
+ {
+ /* failure to set the path halts the executing of control events */
+ r = MSI_SetTargetPathW( dialog->package, argument, path );
+ msi_free( path );
+ }
+ msi_free( &rec->hdr );
+ return r;
+}
+
+static UINT event_reset( msi_dialog *dialog, const WCHAR *argument )
+{
+ msi_dialog_reset( dialog );
+ return ERROR_SUCCESS;
+}
+
+/* Return ERROR_SUCCESS if dialog is process and ERROR_FUNCTION_FAILED
+ * if the given parameter is not a dialog box
+ */
+UINT ACTION_DialogBox( MSIPACKAGE *package, const WCHAR *dialog )
+{
+ UINT r;
+
+ if (package->next_dialog) ERR("Already got next dialog... ignoring it\n");
+ package->next_dialog = NULL;
+
+ /* Dialogs are chained by filling in the next_dialog member
+ * of the package structure, then terminating the current dialog.
+ * The code below sees the next_dialog member set, and runs the
+ * next dialog.
+ * We fall out of the loop below if we come across a modeless
+ * dialog, as it returns ERROR_IO_PENDING when we try to run
+ * its message loop.
+ */
+ r = event_do_dialog( package, dialog, NULL, TRUE );
+ while (r == ERROR_SUCCESS && package->next_dialog)
+ {
+ WCHAR *name = package->next_dialog;
+
+ package->next_dialog = NULL;
+ r = event_do_dialog( package, name, NULL, TRUE );
+ msi_free( name );
+ }
+ if (r == ERROR_IO_PENDING) r = ERROR_SUCCESS;
+ return r;
+}
+
+static UINT event_set_install_level( msi_dialog *dialog, const WCHAR *argument )
+{
+ int level = atolW( argument );
+
+ TRACE("setting install level to %d\n", level);
+ return MSI_SetInstallLevel( dialog->package, level );
+}
+
+static UINT event_directory_list_up( msi_dialog *dialog, const WCHAR *argument )
+{
+ return msi_dialog_directorylist_up( dialog );
+}
+
+static UINT event_reinstall_mode( msi_dialog *dialog, const WCHAR *argument )
+{
+ return msi_set_property( dialog->package->db, szReinstallMode, argument, -1 );
+}
+
+static UINT event_reinstall( msi_dialog *dialog, const WCHAR *argument )
+{
+ return msi_set_property( dialog->package->db, szReinstall, argument, -1 );
+}
+
+static UINT event_validate_product_id( msi_dialog *dialog, const WCHAR *argument )
+{
+ return msi_validate_product_id( dialog->package );
+}
+
+static const WCHAR end_dialogW[] = {'E','n','d','D','i','a','l','o','g',0};
+static const WCHAR new_dialogW[] = {'N','e','w','D','i','a','l','o','g',0};
+static const WCHAR spawn_dialogW[] = {'S','p','a','w','n','D','i','a','l','o','g',0};
+static const WCHAR spawn_wait_dialogW[] = {'S','p','a','w','n','W','a','i','t','D','i','a','l','o','g',0};
+static const WCHAR do_actionW[] = {'D','o','A','c','t','i','o','n',0};
+static const WCHAR add_localW[] = {'A','d','d','L','o','c','a','l',0};
+static const WCHAR removeW[] = {'R','e','m','o','v','e',0};
+static const WCHAR add_sourceW[] = {'A','d','d','S','o','u','r','c','e',0};
+static const WCHAR set_target_pathW[] = {'S','e','t','T','a','r','g','e','t','P','a','t','h',0};
+static const WCHAR resetW[] = {'R','e','s','e','t',0};
+static const WCHAR set_install_levelW[] = {'S','e','t','I','n','s','t','a','l','l','L','e','v','e','l',0};
+static const WCHAR directory_list_upW[] = {'D','i','r','e','c','t','o','r','y','L','i','s','t','U','p',0};
+static const WCHAR selection_browseW[] = {'S','e','l','e','c','t','i','o','n','B','r','o','w','s','e',0};
+static const WCHAR reinstall_modeW[] = {'R','e','i','n','s','t','a','l','l','M','o','d','e',0};
+static const WCHAR reinstallW[] = {'R','e','i','n','s','t','a','l','l',0};
+static const WCHAR validate_product_idW[] = {'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};
+
+static const struct control_event control_events[] =
+{
+ { end_dialogW, event_end_dialog },
+ { new_dialogW, event_new_dialog },
+ { spawn_dialogW, event_spawn_dialog },
+ { spawn_wait_dialogW, event_spawn_wait_dialog },
+ { do_actionW, event_do_action },
+ { add_localW, event_add_local },
+ { removeW, event_remove },
+ { add_sourceW, event_add_source },
+ { set_target_pathW, event_set_target_path },
+ { resetW, event_reset },
+ { set_install_levelW, event_set_install_level },
+ { directory_list_upW, event_directory_list_up },
+ { selection_browseW, event_spawn_dialog },
+ { reinstall_modeW, event_reinstall_mode },
+ { reinstallW, event_reinstall },
+ { validate_product_idW, event_validate_product_id },
+ { NULL, NULL }
+};
+
+static UINT dialog_event_handler( msi_dialog *dialog, const WCHAR *event, const WCHAR *argument )
+{
+ unsigned int i;
+
+ TRACE("handling event %s\n", debugstr_w(event));
+
+ if (!event) return ERROR_SUCCESS;
+
+ for (i = 0; control_events[i].event; i++)
+ {
+ if (!strcmpW( control_events[i].event, event ))
+ return control_events[i].handler( dialog, argument );
+ }
+ FIXME("unhandled event %s arg(%s)\n", debugstr_w(event), debugstr_w(argument));
+ return ERROR_SUCCESS;
+}
+++ /dev/null
-/*
- * Implementation of the Microsoft Installer (msi.dll)
- *
- * Copyright 2005 Aric Stewart for CodeWeavers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
-
-//#include <stdarg.h>
-//#include <stdio.h>
-
-//#include <windef.h>
-//#include "winbase.h"
-//#include "winerror.h"
-//#include "winreg.h"
-//#include "msi.h"
-#include "msipriv.h"
-
-#include <wine/debug.h>
-#include <wine/unicode.h>
-
-WINE_DEFAULT_DEBUG_CHANNEL(msi);
-
-typedef UINT (*EVENTHANDLER)(MSIPACKAGE*,LPCWSTR,msi_dialog *);
-
-struct control_events
-{
- const WCHAR *event;
- EVENTHANDLER handler;
-};
-
-struct subscriber {
- struct list entry;
- msi_dialog *dialog;
- LPWSTR event;
- LPWSTR control;
- LPWSTR attribute;
-};
-
-static UINT ControlEvent_HandleControlEvent(MSIPACKAGE *, LPCWSTR, LPCWSTR, msi_dialog*);
-
-/*
- * Create a dialog box and run it if it's modal
- */
-static UINT event_do_dialog( MSIPACKAGE *package, LPCWSTR name, msi_dialog *parent, BOOL destroy_modeless )
-{
- msi_dialog *dialog;
- UINT r;
-
- /* create a new dialog */
- dialog = msi_dialog_create( package, name, parent,
- ControlEvent_HandleControlEvent );
- if( dialog )
- {
- /* kill the current modeless dialog */
- if( destroy_modeless && package->dialog )
- {
- msi_dialog_destroy( package->dialog );
- package->dialog = NULL;
- }
-
- /* modeless dialogs return an error message */
- r = msi_dialog_run_message_loop( dialog );
- if( r == ERROR_SUCCESS )
- msi_dialog_destroy( dialog );
- else
- package->dialog = dialog;
- }
- else
- r = ERROR_FUNCTION_FAILED;
-
- return r;
-}
-
-
-/*
- * End a modal dialog box
- */
-static UINT ControlEvent_EndDialog(MSIPACKAGE* package, LPCWSTR argument,
- msi_dialog* dialog)
-{
- static const WCHAR szExit[] = {'E','x','i','t',0};
- static const WCHAR szRetry[] = {'R','e','t','r','y',0};
- static const WCHAR szIgnore[] = {'I','g','n','o','r','e',0};
- static const WCHAR szReturn[] = {'R','e','t','u','r','n',0};
-
- if (!strcmpW( argument, szExit ))
- package->CurrentInstallState = ERROR_INSTALL_USEREXIT;
- else if (!strcmpW( argument, szRetry ))
- package->CurrentInstallState = ERROR_INSTALL_SUSPEND;
- else if (!strcmpW( argument, szIgnore ))
- package->CurrentInstallState = ERROR_SUCCESS;
- else if (!strcmpW( argument, szReturn ))
- {
- msi_dialog *parent = msi_dialog_get_parent(dialog);
- msi_free(package->next_dialog);
- package->next_dialog = (parent) ? strdupW(msi_dialog_get_name(parent)) : NULL;
- package->CurrentInstallState = ERROR_SUCCESS;
- }
- else
- {
- ERR("Unknown argument string %s\n",debugstr_w(argument));
- package->CurrentInstallState = ERROR_FUNCTION_FAILED;
- }
-
- ControlEvent_CleanupDialogSubscriptions(package, msi_dialog_get_name( dialog ));
- msi_dialog_end_dialog( dialog );
- return ERROR_SUCCESS;
-}
-
-/*
- * transition from one modal dialog to another modal dialog
- */
-static UINT ControlEvent_NewDialog(MSIPACKAGE* package, LPCWSTR argument,
- msi_dialog *dialog)
-{
- /* store the name of the next dialog, and signal this one to end */
- package->next_dialog = strdupW(argument);
- ControlEvent_CleanupSubscriptions(package);
- msi_dialog_end_dialog( dialog );
- return ERROR_SUCCESS;
-}
-
-/*
- * Create a new child dialog of an existing modal dialog
- */
-static UINT ControlEvent_SpawnDialog(MSIPACKAGE* package, LPCWSTR argument,
- msi_dialog *dialog)
-{
- /* don't destroy a modeless dialogs that might be our parent */
- event_do_dialog( package, argument, dialog, FALSE );
- if( package->CurrentInstallState != ERROR_SUCCESS )
- msi_dialog_end_dialog( dialog );
- return ERROR_SUCCESS;
-}
-
-/*
- * Creates a dialog that remains up for a period of time
- * based on a condition
- */
-static UINT ControlEvent_SpawnWaitDialog(MSIPACKAGE* package, LPCWSTR argument,
- msi_dialog* dialog)
-{
- FIXME("Doing Nothing\n");
- return ERROR_SUCCESS;
-}
-
-static UINT ControlEvent_DoAction(MSIPACKAGE* package, LPCWSTR argument,
- msi_dialog* dialog)
-{
- ACTION_PerformAction(package, argument, SCRIPT_NONE);
- return ERROR_SUCCESS;
-}
-
-static UINT ControlEvent_AddLocal( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
-{
- MSIFEATURE *feature;
-
- LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
- {
- if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
- {
- if (feature->ActionRequest != INSTALLSTATE_LOCAL)
- msi_set_property( package->db, szPreselected, szOne, -1 );
- MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_LOCAL );
- }
- }
- return ERROR_SUCCESS;
-}
-
-static UINT ControlEvent_Remove( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
-{
- MSIFEATURE *feature;
-
- LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
- {
- if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
- {
- if (feature->ActionRequest != INSTALLSTATE_ABSENT)
- msi_set_property( package->db, szPreselected, szOne, -1 );
- MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_ABSENT );
- }
- }
- return ERROR_SUCCESS;
-}
-
-static UINT ControlEvent_AddSource( MSIPACKAGE *package, LPCWSTR argument, msi_dialog *dialog )
-{
- MSIFEATURE *feature;
-
- LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
- {
- if (!strcmpW( argument, feature->Feature ) || !strcmpW( argument, szAll ))
- {
- if (feature->ActionRequest != INSTALLSTATE_SOURCE)
- msi_set_property( package->db, szPreselected, szOne, -1 );
- MSI_SetFeatureStateW( package, feature->Feature, INSTALLSTATE_SOURCE );
- }
- }
- return ERROR_SUCCESS;
-}
-
-static UINT ControlEvent_SetTargetPath(MSIPACKAGE* package, LPCWSTR argument,
- msi_dialog* dialog)
-{
- static const WCHAR szSelectionPath[] = {'S','e','l','e','c','t','i','o','n','P','a','t','h',0};
- LPWSTR path = msi_dup_property( package->db, argument );
- MSIRECORD *rec = MSI_CreateRecord( 1 );
- UINT r = ERROR_SUCCESS;
-
- MSI_RecordSetStringW( rec, 1, path );
- ControlEvent_FireSubscribedEvent( package, szSelectionPath, rec );
- if (path)
- {
- /* failure to set the path halts the executing of control events */
- r = MSI_SetTargetPathW(package, argument, path);
- msi_free(path);
- }
- msi_free(&rec->hdr);
- return r;
-}
-
-static UINT ControlEvent_Reset(MSIPACKAGE* package, LPCWSTR argument,
- msi_dialog* dialog)
-{
- msi_dialog_reset(dialog);
- return ERROR_SUCCESS;
-}
-
-/*
- * Subscribed events
- */
-static void free_subscriber( struct subscriber *sub )
-{
- msi_free(sub->event);
- msi_free(sub->control);
- msi_free(sub->attribute);
- msi_free(sub);
-}
-
-VOID ControlEvent_SubscribeToEvent( MSIPACKAGE *package, msi_dialog *dialog,
- LPCWSTR event, LPCWSTR control, LPCWSTR attribute )
-{
- struct subscriber *sub;
-
- TRACE("event %s control %s attribute %s\n", debugstr_w(event), debugstr_w(control), debugstr_w(attribute));
-
- LIST_FOR_EACH_ENTRY( sub, &package->subscriptions, struct subscriber, entry )
- {
- if (!strcmpiW( sub->event, event ) &&
- !strcmpiW( sub->control, control ) &&
- !strcmpiW( sub->attribute, attribute ))
- {
- TRACE("already subscribed\n");
- return;
- };
- }
- if (!(sub = msi_alloc( sizeof(*sub) ))) return;
- sub->dialog = dialog;
- sub->event = strdupW(event);
- sub->control = strdupW(control);
- sub->attribute = strdupW(attribute);
- list_add_tail( &package->subscriptions, &sub->entry );
-}
-
-VOID ControlEvent_FireSubscribedEvent( MSIPACKAGE *package, LPCWSTR event, MSIRECORD *rec )
-{
- struct subscriber *sub;
-
- TRACE("Firing event %s\n", debugstr_w(event));
-
- LIST_FOR_EACH_ENTRY( sub, &package->subscriptions, struct subscriber, entry )
- {
- if (strcmpiW( sub->event, event )) continue;
- msi_dialog_handle_event( sub->dialog, sub->control, sub->attribute, rec );
- }
-}
-
-VOID ControlEvent_CleanupDialogSubscriptions(MSIPACKAGE *package, LPWSTR dialog)
-{
- struct list *i, *t;
- struct subscriber *sub;
-
- LIST_FOR_EACH_SAFE( i, t, &package->subscriptions )
- {
- sub = LIST_ENTRY( i, struct subscriber, entry );
-
- if (strcmpW( msi_dialog_get_name( sub->dialog ), dialog ))
- continue;
-
- list_remove( &sub->entry );
- free_subscriber( sub );
- }
-}
-
-VOID ControlEvent_CleanupSubscriptions(MSIPACKAGE *package)
-{
- struct list *i, *t;
- struct subscriber *sub;
-
- LIST_FOR_EACH_SAFE( i, t, &package->subscriptions )
- {
- sub = LIST_ENTRY( i, struct subscriber, entry );
-
- list_remove( &sub->entry );
- free_subscriber( sub );
- }
-}
-
-/*
- * ACTION_DialogBox()
- *
- * Return ERROR_SUCCESS if dialog is process and ERROR_FUNCTION_FAILED
- * if the given parameter is not a dialog box
- */
-UINT ACTION_DialogBox( MSIPACKAGE* package, LPCWSTR szDialogName )
-{
- UINT r = ERROR_SUCCESS;
-
- if( package->next_dialog )
- ERR("Already a next dialog... ignoring it\n");
- package->next_dialog = NULL;
-
- /*
- * Dialogs are chained by filling in the next_dialog member
- * of the package structure, then terminating the current dialog.
- * The code below sees the next_dialog member set, and runs the
- * next dialog.
- * We fall out of the loop below if we come across a modeless
- * dialog, as it returns ERROR_IO_PENDING when we try to run
- * its message loop.
- */
- r = event_do_dialog( package, szDialogName, NULL, TRUE );
- while( r == ERROR_SUCCESS && package->next_dialog )
- {
- LPWSTR name = package->next_dialog;
-
- package->next_dialog = NULL;
- r = event_do_dialog( package, name, NULL, TRUE );
- msi_free( name );
- }
-
- if( r == ERROR_IO_PENDING )
- r = ERROR_SUCCESS;
-
- return r;
-}
-
-static UINT ControlEvent_SetInstallLevel(MSIPACKAGE* package, LPCWSTR argument,
- msi_dialog* dialog)
-{
- int iInstallLevel = atolW(argument);
-
- TRACE("Setting install level: %i\n", iInstallLevel);
-
- return MSI_SetInstallLevel( package, iInstallLevel );
-}
-
-static UINT ControlEvent_DirectoryListUp(MSIPACKAGE *package, LPCWSTR argument,
- msi_dialog *dialog)
-{
- return msi_dialog_directorylist_up( dialog );
-}
-
-static UINT ControlEvent_ReinstallMode(MSIPACKAGE *package, LPCWSTR argument,
- msi_dialog *dialog)
-{
- return msi_set_property( package->db, szReinstallMode, argument, -1 );
-}
-
-static UINT ControlEvent_Reinstall( MSIPACKAGE *package, LPCWSTR argument,
- msi_dialog *dialog )
-{
- return msi_set_property( package->db, szReinstall, argument, -1 );
-}
-
-static UINT ControlEvent_ValidateProductID(MSIPACKAGE *package, LPCWSTR argument,
- msi_dialog *dialog)
-{
- return msi_validate_product_id( package );
-}
-
-static const WCHAR end_dialogW[] = {'E','n','d','D','i','a','l','o','g',0};
-static const WCHAR new_dialogW[] = {'N','e','w','D','i','a','l','o','g',0};
-static const WCHAR spawn_dialogW[] = {'S','p','a','w','n','D','i','a','l','o','g',0};
-static const WCHAR spawn_wait_dialogW[] = {'S','p','a','w','n','W','a','i','t','D','i','a','l','o','g',0};
-static const WCHAR do_actionW[] = {'D','o','A','c','t','i','o','n',0};
-static const WCHAR add_localW[] = {'A','d','d','L','o','c','a','l',0};
-static const WCHAR removeW[] = {'R','e','m','o','v','e',0};
-static const WCHAR add_sourceW[] = {'A','d','d','S','o','u','r','c','e',0};
-static const WCHAR set_target_pathW[] = {'S','e','t','T','a','r','g','e','t','P','a','t','h',0};
-static const WCHAR resetW[] = {'R','e','s','e','t',0};
-static const WCHAR set_install_levelW[] = {'S','e','t','I','n','s','t','a','l','l','L','e','v','e','l',0};
-static const WCHAR directory_list_upW[] = {'D','i','r','e','c','t','o','r','y','L','i','s','t','U','p',0};
-static const WCHAR selection_browseW[] = {'S','e','l','e','c','t','i','o','n','B','r','o','w','s','e',0};
-static const WCHAR reinstall_modeW[] = {'R','e','i','n','s','t','a','l','l','M','o','d','e',0};
-static const WCHAR reinstallW[] = {'R','e','i','n','s','t','a','l','l',0};
-static const WCHAR validate_product_idW[] = {'V','a','l','i','d','a','t','e','P','r','o','d','u','c','t','I','D',0};
-
-static const struct control_events control_events[] =
-{
- { end_dialogW, ControlEvent_EndDialog },
- { new_dialogW, ControlEvent_NewDialog },
- { spawn_dialogW, ControlEvent_SpawnDialog },
- { spawn_wait_dialogW, ControlEvent_SpawnWaitDialog },
- { do_actionW, ControlEvent_DoAction },
- { add_localW, ControlEvent_AddLocal },
- { removeW, ControlEvent_Remove },
- { add_sourceW, ControlEvent_AddSource },
- { set_target_pathW, ControlEvent_SetTargetPath },
- { resetW, ControlEvent_Reset },
- { set_install_levelW, ControlEvent_SetInstallLevel },
- { directory_list_upW, ControlEvent_DirectoryListUp },
- { selection_browseW, ControlEvent_SpawnDialog },
- { reinstall_modeW, ControlEvent_ReinstallMode },
- { reinstallW, ControlEvent_Reinstall },
- { validate_product_idW, ControlEvent_ValidateProductID },
- { NULL, NULL }
-};
-
-UINT ControlEvent_HandleControlEvent( MSIPACKAGE *package, LPCWSTR event,
- LPCWSTR argument, msi_dialog *dialog )
-{
- unsigned int i;
-
- TRACE("handling control event %s\n", debugstr_w(event));
-
- if (!event) return ERROR_SUCCESS;
-
- for (i = 0; control_events[i].event; i++)
- {
- if (!strcmpW( control_events[i].event, event ))
- return control_events[i].handler( package, argument, dialog );
- }
- FIXME("unhandled control event %s arg(%s)\n", debugstr_w(event), debugstr_w(argument));
- return ERROR_SUCCESS;
-}
return ERROR_SUCCESS;
}
-static MSIFILE *find_file( MSIPACKAGE *package, const WCHAR *filename )
+static MSIFILE *find_file( MSIPACKAGE *package, UINT disk_id, const WCHAR *filename )
{
MSIFILE *file;
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
{
- if (file->state != msifs_installed && !strcmpiW( filename, file->File )) return file;
+ if (file->disk_id == disk_id &&
+ file->state != msifs_installed &&
+ !strcmpiW( filename, file->File )) return file;
}
return NULL;
}
if (action == MSICABEXTRACT_BEGINEXTRACT)
{
- if (!(f = find_file( package, file )))
+ if (!(f = find_file( package, disk_id, file )))
{
TRACE("unknown file in cabinet (%s)\n", debugstr_w(file));
return FALSE;
}
else if (file->state != msifs_installed && !(file->Attributes & msidbFileAttributesPatchAdded))
{
- ERR("compressed file wasn't installed (%s)\n", debugstr_w(file->TargetPath));
+ ERR("compressed file wasn't installed (%s)\n", debugstr_w(file->File));
rc = ERROR_INSTALL_FAILURE;
goto done;
}
if (strcmpiW( mi->cabinet, cab ))
{
- ERR("Continuous cabinet does not match the next cabinet in the Media table\n");
- goto done;
+ char *next_cab;
+ ULONG length;
+
+ WARN("Continuous cabinet %s does not match the next cabinet %s in the media table => use latter one\n", debugstr_w(cab), debugstr_w(mi->cabinet));
+
+ /* Use cabinet name from the media table */
+ next_cab = strdupWtoA(mi->cabinet);
+ /* Modify path to cabinet file with full filename (psz3 points to a 256 bytes buffer that can be modified contrary to psz1 and psz2) */
+ length = strlen(pfdin->psz3) + 1 + strlen(next_cab) + 1;
+ if (length > 256)
+ {
+ WARN("Cannot update next cabinet filename with a string size %u > 256\n", length);
+ msi_free(next_cab);
+ goto done;
+ }
+ else
+ {
+ strcat(pfdin->psz3, "\\");
+ strcat(pfdin->psz3, next_cab);
+ }
+ /* Path psz3 and cabinet psz1 are concatenated by FDI so just reset psz1 */
+ *pfdin->psz1 = 0;
+ msi_free(next_cab);
}
if (!(cabinet_file = get_cabinet_filename(mi)))
IsWow64Process( GetCurrentProcess(), &is_wow64 );
break;
case DLL_PROCESS_DETACH:
+ if (lpvReserved) break;
msi_dialog_unregister_class();
msi_free_handle_table();
msi_free( gszLogFile );
extern LONG msi_reg_set_subkey_val( HKEY hkey, LPCWSTR path, LPCWSTR name, LPCWSTR val ) DECLSPEC_HIDDEN;
/* msi dialog interface */
-typedef UINT (*msi_dialog_event_handler)( MSIPACKAGE*, LPCWSTR, LPCWSTR, msi_dialog* );
-extern msi_dialog *msi_dialog_create( MSIPACKAGE*, LPCWSTR, msi_dialog*, msi_dialog_event_handler ) DECLSPEC_HIDDEN;
-extern UINT msi_dialog_run_message_loop( msi_dialog* ) DECLSPEC_HIDDEN;
-extern void msi_dialog_end_dialog( msi_dialog* ) DECLSPEC_HIDDEN;
extern void msi_dialog_check_messages( HANDLE ) DECLSPEC_HIDDEN;
extern void msi_dialog_destroy( msi_dialog* ) DECLSPEC_HIDDEN;
extern void msi_dialog_unregister_class( void ) DECLSPEC_HIDDEN;
-extern void msi_dialog_handle_event( msi_dialog*, LPCWSTR, LPCWSTR, MSIRECORD * ) DECLSPEC_HIDDEN;
-extern UINT msi_dialog_reset( msi_dialog *dialog ) DECLSPEC_HIDDEN;
-extern UINT msi_dialog_directorylist_up( msi_dialog *dialog ) DECLSPEC_HIDDEN;
-extern msi_dialog *msi_dialog_get_parent( msi_dialog *dialog ) DECLSPEC_HIDDEN;
-extern LPWSTR msi_dialog_get_name( msi_dialog *dialog ) DECLSPEC_HIDDEN;
extern UINT msi_spawn_error_dialog( MSIPACKAGE*, LPWSTR, LPWSTR ) DECLSPEC_HIDDEN;
/* summary information */
extern UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action, UINT script) DECLSPEC_HIDDEN;
extern UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action, UINT script) DECLSPEC_HIDDEN;
extern void ACTION_FinishCustomActions( const MSIPACKAGE* package) DECLSPEC_HIDDEN;
-extern UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action, UINT script, BOOL execute) DECLSPEC_HIDDEN;
+extern UINT ACTION_CustomAction(MSIPACKAGE *, const WCHAR *, UINT) DECLSPEC_HIDDEN;
/* actions in other modules */
extern UINT ACTION_AppSearch(MSIPACKAGE *package) DECLSPEC_HIDDEN;
extern UINT msi_add_cabinet_stream(MSIPACKAGE *, UINT, IStorage *, const WCHAR *) DECLSPEC_HIDDEN;
/* control event stuff */
-extern VOID ControlEvent_FireSubscribedEvent(MSIPACKAGE *package, LPCWSTR event,
- MSIRECORD *data) DECLSPEC_HIDDEN;
-extern VOID ControlEvent_CleanupDialogSubscriptions(MSIPACKAGE *package, LPWSTR dialog) DECLSPEC_HIDDEN;
-extern VOID ControlEvent_CleanupSubscriptions(MSIPACKAGE *package) DECLSPEC_HIDDEN;
-extern VOID ControlEvent_SubscribeToEvent(MSIPACKAGE *package, msi_dialog *dialog,
- LPCWSTR event, LPCWSTR control, LPCWSTR attribute) DECLSPEC_HIDDEN;
+extern void msi_event_fire(MSIPACKAGE *, const WCHAR *, MSIRECORD *) DECLSPEC_HIDDEN;
+extern void msi_event_cleanup_all_subscriptions( MSIPACKAGE * ) DECLSPEC_HIDDEN;
/* OLE automation */
typedef enum tid_t {
remove_tracked_tempfiles(package);
/* cleanup control event subscriptions */
- ControlEvent_CleanupSubscriptions( package );
+ msi_event_cleanup_all_subscriptions( package );
}
static void MSI_FreePackage( MSIOBJECTHDR *arg)
break;
case VER_PLATFORM_WIN32_NT:
msi_set_property( package->db, szVersionNT, verstr, len );
- len = sprintfW( verstr, szFormat,OSVersion.wProductType );
- msi_set_property( package->db, szMsiNTProductType, verstr, len );
+ len = sprintfW( bufstr, szFormat,OSVersion.wProductType );
+ msi_set_property( package->db, szMsiNTProductType, bufstr, len );
break;
}
- len = sprintfW( verstr, szFormat, OSVersion.dwBuildNumber );
- msi_set_property( package->db, szWindowsBuild, verstr, len );
- len = sprintfW( verstr, szFormat, OSVersion.wServicePackMajor );
- msi_set_property( package->db, szServicePackLevel, verstr, len );
+ len = sprintfW( bufstr, szFormat, OSVersion.dwBuildNumber );
+ msi_set_property( package->db, szWindowsBuild, bufstr, len );
+ len = sprintfW( bufstr, szFormat, OSVersion.wServicePackMajor );
+ msi_set_property( package->db, szServicePackLevel, bufstr, len );
len = sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION );
msi_set_property( package->db, szVersionMsi, bufstr, len );
if ((computername = msi_alloc( len * sizeof(WCHAR) )))
{
if (GetComputerNameW( computername, &len ))
- msi_set_property( package->db, szComputerName, computername, len - 1 );
+ msi_set_property( package->db, szComputerName, computername, len );
msi_free( computername );
}
}
MSI_RecordSetStringW(uirow, 1, deformated);
msi_free(deformated);
- ControlEvent_FireSubscribedEvent(package, szActionData, uirow);
+ msi_event_fire( package, szActionData, uirow );
msiobj_release(&uirow->hdr);
if (package->action_progress_increment)
uirow = MSI_CreateRecord(2);
MSI_RecordSetInteger(uirow, 1, 2);
MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
- ControlEvent_FireSubscribedEvent(package, szSetProgress, uirow);
+ msi_event_fire( package, szSetProgress, uirow );
msiobj_release(&uirow->hdr);
}
break;
MSI_RecordSetStringW(uirow, 1, deformated);
msi_free(deformated);
- ControlEvent_FireSubscribedEvent(package, szActionText, uirow);
+ msi_event_fire( package, szActionText, uirow );
msiobj_release(&uirow->hdr);
break;
case INSTALLMESSAGE_PROGRESS:
- ControlEvent_FireSubscribedEvent(package, szSetProgress, record);
+ msi_event_fire( package, szSetProgress, record );
break;
}
return FALSE;
}
-static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *patch )
+static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *transform )
{
- LPWSTR prod_code, patch_product, template = NULL;
+ WCHAR *package_product, *transform_product, *template = NULL;
UINT ret = ERROR_FUNCTION_FAILED;
- prod_code = msi_dup_property( package->db, szProductCode );
- patch_product = msi_get_suminfo_product( patch );
+ package_product = msi_dup_property( package->db, szProductCode );
+ transform_product = msi_get_suminfo_product( transform );
- TRACE("db = %s patch = %s\n", debugstr_w(prod_code), debugstr_w(patch_product));
+ TRACE("package = %s transform = %s\n", debugstr_w(package_product), debugstr_w(transform_product));
- if (strstrW( patch_product, prod_code ))
+ if (!transform_product || strstrW( transform_product, package_product ))
{
MSISUMMARYINFO *si;
const WCHAR *p;
- si = MSI_GetSummaryInformationW( patch, 0 );
+ si = MSI_GetSummaryInformationW( transform, 0 );
if (!si)
{
ERR("no summary information!\n");
}
end:
- msi_free( patch_product );
- msi_free( prod_code );
+ msi_free( transform_product );
+ msi_free( package_product );
msi_free( template );
return ret;
}
pos = patch_offset_list_create();
patch_offset_get_files( db, last_sequence, pos );
patch_offset_get_patches( db, last_sequence, pos );
- if (pos->count)
{
UINT offset = db->media_transform_offset - pos->min;
last_sequence = offset + pos->max;
/* FIXME: this is for the patch table, which is not yet properly transformed */
last_sequence += pos->min;
pos->offset_to_apply = offset;
- patch_offset_modify_db( db, pos );
+ if (pos->count)
+ patch_offset_modify_db( db, pos );
MSI_RecordSetInteger( rec, 2, last_sequence );
r = MSI_ViewModify( view, MSIMODIFY_UPDATE, rec );
} u;
};
+typedef struct
+{
+ MSIDATABASE *db;
+ LPCWSTR command;
+ DWORD n, len;
+ UINT r;
+ MSIVIEW **view; /* View structure for the resulting query. This value
+ * tracks the view currently being created so we can free
+ * this view on syntax error.
+ */
+ struct list *mem;
+} SQL_input;
+
UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,
struct list *mem ) DECLSPEC_HIDDEN;
return S_OK;
}
+static UINT map_return_value(LONG val)
+{
+ switch (val)
+ {
+ case 0:
+ case IDOK:
+ case IDIGNORE: return ERROR_SUCCESS;
+ case IDCANCEL: return ERROR_INSTALL_USEREXIT;
+ case IDRETRY: return ERROR_INSTALL_SUSPEND;
+ case IDABORT:
+ default: return ERROR_INSTALL_FAILURE;
+ }
+}
+
/*
* Call a script.
*/
hr = IDispatch_Invoke(pDispatch, dispid, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs, &var, NULL, NULL);
if (FAILED(hr)) goto done;
- /* Check return value, if it's not IDOK we failed */
hr = VariantChangeType(&var, &var, 0, VT_I4);
if (FAILED(hr)) goto done;
- if (V_I4(&var) == IDOK)
- ret = ERROR_SUCCESS;
- else ret = ERROR_INSTALL_FAILURE;
+ ret = map_return_value(V_I4(&var));
VariantClear(&var);
} else {
+/* A Bison parser, made by GNU Bison 2.5. */
-/* A Bison parser, made by GNU Bison 2.4.1. */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "2.5"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
#define yydebug sql_debug
#define yynerrs sql_nerrs
+
/* Copy the first part of user declarations. */
-/* Line 189 of yacc.c */
+/* Line 268 of yacc.c */
#line 1 "sql.y"
#include <wine/debug.h>
#include <wine/unicode.h>
-#define YYLEX_PARAM info
-#define YYPARSE_PARAM info
-
-static int sql_error(const char *str);
-
WINE_DEFAULT_DEBUG_CHANNEL(msi);
-typedef struct tag_SQL_input
-{
- MSIDATABASE *db;
- LPCWSTR command;
- DWORD n, len;
- UINT r;
- MSIVIEW **view; /* View structure for the resulting query. This value
- * tracks the view currently being created so we can free
- * this view on syntax error.
- */
- struct list *mem;
-} SQL_input;
-
static UINT SQL_getstring( void *info, const struct sql_str *strdata, LPWSTR *str );
static INT SQL_getint( void *info );
static int sql_lex( void *SQL_lval, SQL_input *info );
+static int sql_error( SQL_input *info, const char *str);
static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table );
static void *parser_alloc( void *info, unsigned int sz );
-/* Line 189 of yacc.c */
-#line 161 "sql.tab.c"
+/* Line 268 of yacc.c */
+#line 142 "sql.tab.c"
/* Enabling traces. */
#ifndef YYDEBUG
typedef union YYSTYPE
{
-/* Line 214 of yacc.c */
-#line 83 "sql.y"
+/* Line 293 of yacc.c */
+#line 68 "sql.y"
struct sql_str str;
LPWSTR string;
-/* Line 214 of yacc.c */
-#line 272 "sql.tab.c"
+/* Line 293 of yacc.c */
+#line 253 "sql.tab.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
/* Copy the second part of user declarations. */
-/* Line 264 of yacc.c */
-#line 276 "sql.tab.c"
+/* Line 343 of yacc.c */
+#line 265 "sql.tab.c"
#ifdef short
# undef short
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
#ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
# define YY_(msgid) dgettext ("bison-runtime", msgid)
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
# endif
# endif
# endif
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
-# if (defined __cplusplus && ! defined _STDLIB_H \
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# ifndef _STDLIB_H
-# define _STDLIB_H 1
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
# endif
# endif
# ifndef YYFREE
# define YYFREE free
-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
void free (void *); /* INFRINGES ON USER NAME SPACE */
# endif
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
-/* Copy COUNT objects from FROM to TO. The source and destination do
- not overlap. */
-# ifndef YYCOPY
-# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
- while (YYID (0))
-# endif
-# endif
+# define YYCOPY_NEEDED 1
/* Relocate STACK from its old location to the new one. The
local variables YYSIZE and YYSTACKSIZE give the old and new number of
#endif
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 36
/* YYLAST -- Last index in YYTABLE. */
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 132, 132, 140, 141, 142, 143, 144, 145, 146,
- 150, 161, 175, 192, 208, 219, 233, 247, 258, 269,
- 283, 287, 294, 309, 319, 329, 336, 345, 349, 353,
- 360, 364, 371, 375, 379, 383, 387, 391, 395, 402,
- 411, 415, 430, 450, 451, 455, 462, 463, 467, 474,
- 486, 499, 503, 515, 530, 534, 543, 549, 555, 561,
- 567, 573, 579, 585, 591, 597, 603, 612, 613, 617,
- 624, 635, 636, 644, 652, 658, 664, 670, 679, 688,
- 694, 703, 709, 715, 724, 731, 739, 747
+ 0, 117, 117, 125, 126, 127, 128, 129, 130, 131,
+ 135, 146, 160, 177, 193, 204, 218, 232, 243, 254,
+ 268, 272, 279, 294, 304, 314, 321, 330, 334, 338,
+ 345, 349, 356, 360, 364, 368, 372, 376, 380, 387,
+ 396, 400, 415, 435, 436, 440, 447, 448, 452, 459,
+ 471, 484, 488, 500, 515, 519, 528, 534, 540, 546,
+ 552, 558, 564, 570, 576, 582, 588, 597, 598, 602,
+ 609, 620, 621, 629, 637, 643, 649, 655, 664, 673,
+ 679, 688, 694, 700, 709, 716, 724, 732
};
#endif
1, 3, 1, 1, 1, 1, 1, 1
};
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
- STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE doesn't specify something else to do. Zero
means the default is an error. */
static const yytype_uint8 yydefact[] =
{
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
- number is the opposite. If zero, do what YYDEFACT says.
- If YYTABLE_NINF, syntax error. */
+ number is the opposite. If YYTABLE_NINF, syntax error. */
#define YYTABLE_NINF -85
static const yytype_int16 yytable[] =
{
58, 74, 147, 0, 110, 150, 153
};
+#define yypact_value_is_default(yystate) \
+ ((yystate) == (-80))
+
+#define yytable_value_is_error(yytable_value) \
+ YYID (0)
+
static const yytype_int16 yycheck[] =
{
6, 7, 20, 82, 57, 49, 53, 4, 20, 7,
/* Like YYERROR except do call yyerror. This remains here temporarily
to ease the transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
+ Once GCC version 2 has supplanted version 1, this can go. However,
+ YYFAIL appears to be in use. Nevertheless, it is formally deprecated
+ in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+ discussed. */
#define YYFAIL goto yyerrlab
+#if defined YYFAIL
+ /* This is here to suppress warnings from the GCC cpp's
+ -Wunused-macros. Normally we don't worry about that warning, but
+ some users do, and we want to make it easy for users to remove
+ YYFAIL uses, which will produce warnings from Bison 2.5. */
+#endif
#define YYRECOVERING() (!!yyerrstatus)
{ \
yychar = (Token); \
yylval = (Value); \
- yytoken = YYTRANSLATE (yychar); \
YYPOPSTACK (1); \
goto yybackup; \
} \
else \
{ \
- yyerror (YY_("syntax error: cannot back up")); \
+ yyerror (info, YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (YYID (0))
#endif
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
+/* This macro is provided for backward compatibility. */
#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif
#ifdef YYLEX_PARAM
# define YYLEX yylex (&yylval, YYLEX_PARAM)
#else
-# define YYLEX yylex (&yylval)
+# define YYLEX yylex (&yylval, info)
#endif
/* Enable debugging if requested. */
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
- Type, Value); \
+ Type, Value, info); \
YYFPRINTF (stderr, "\n"); \
} \
} while (YYID (0))
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, SQL_input *info)
#else
static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, info)
FILE *yyoutput;
int yytype;
YYSTYPE const * const yyvaluep;
+ SQL_input *info;
#endif
{
if (!yyvaluep)
return;
+ YYUSE (info);
# ifdef YYPRINT
if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, SQL_input *info)
#else
static void
-yy_symbol_print (yyoutput, yytype, yyvaluep)
+yy_symbol_print (yyoutput, yytype, yyvaluep, info)
FILE *yyoutput;
int yytype;
YYSTYPE const * const yyvaluep;
+ SQL_input *info;
#endif
{
if (yytype < YYNTOKENS)
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
- yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, info);
YYFPRINTF (yyoutput, ")");
}
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule, SQL_input *info)
#else
static void
-yy_reduce_print (yyvsp, yyrule)
+yy_reduce_print (yyvsp, yyrule, info)
YYSTYPE *yyvsp;
int yyrule;
+ SQL_input *info;
#endif
{
int yynrhs = yyr2[yyrule];
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
- );
+ , info);
YYFPRINTF (stderr, "\n");
}
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (yyvsp, Rule); \
+ yy_reduce_print (yyvsp, Rule, info); \
} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
# define YYMAXDEPTH 10000
#endif
-\f
#if YYERROR_VERBOSE
}
# endif
-/* Copy into YYRESULT an error message about the unexpected token
- YYCHAR while in state YYSTATE. Return the number of bytes copied,
- including the terminating null byte. If YYRESULT is null, do not
- copy anything; just return the number of bytes that would be
- copied. As a special case, return 0 if an ordinary "syntax error"
- message will do. Return YYSIZE_MAXIMUM if overflow occurs during
- size calculation. */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
- int yyn = yypact[yystate];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
- if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
- return 0;
- else
- {
- int yytype = YYTRANSLATE (yychar);
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
- YYSIZE_T yysize = yysize0;
- YYSIZE_T yysize1;
- int yysize_overflow = 0;
- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
- int yyx;
-
-# if 0
- /* This is so xgettext sees the translatable formats that are
- constructed on the fly. */
- YY_("syntax error, unexpected %s");
- YY_("syntax error, unexpected %s, expecting %s");
- YY_("syntax error, unexpected %s, expecting %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s");
- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
- char *yyfmt;
- char const *yyf;
- static char const yyunexpected[] = "syntax error, unexpected %s";
- static char const yyexpecting[] = ", expecting %s";
- static char const yyor[] = " or %s";
- char yyformat[sizeof yyunexpected
- + sizeof yyexpecting - 1
- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
- * (sizeof yyor - 1))];
- char const *yyprefix = yyexpecting;
-
- /* Start YYX at -YYN if negative to avoid negative indexes in
- YYCHECK. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
-
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = YYLAST - yyn + 1;
- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 1;
-
- yyarg[0] = yytname[yytype];
- yyfmt = yystpcpy (yyformat, yyunexpected);
-
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
- {
- yycount = 1;
- yysize = yysize0;
- yyformat[sizeof yyunexpected - 1] = '\0';
- break;
- }
- yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
- yyfmt = yystpcpy (yyfmt, yyprefix);
- yyprefix = yyor;
- }
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = 0;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - Assume YYFAIL is not used. It's too flawed to consider. See
+ <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+ for details. YYERROR is fine as it does not invoke this
+ function.
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
- yyf = YY_(yyformat);
- yysize1 = yysize + yystrlen (yyf);
- yysize_overflow |= (yysize1 < yysize);
- yysize = yysize1;
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
- if (yysize_overflow)
- return YYSIZE_MAXIMUM;
+ yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
- if (yyresult)
- {
- /* Avoid sprintf, as that infringes on the user's name space.
- Don't have undefined behavior even if the translation
- produced a string with the wrong number of "%s"s. */
- char *yyp = yyresult;
- int yyi = 0;
- while ((*yyp = *yyf) != '\0')
- {
- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
- {
- yyp += yytnamerr (yyp, yyarg[yyi++]);
- yyf += 2;
- }
- else
- {
- yyp++;
- yyf++;
- }
- }
- }
- return yysize;
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
}
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
}
#endif /* YYERROR_VERBOSE */
-\f
/*-----------------------------------------------.
| Release the memory associated to this symbol. |
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, SQL_input *info)
#else
static void
-yydestruct (yymsg, yytype, yyvaluep)
+yydestruct (yymsg, yytype, yyvaluep, info)
const char *yymsg;
int yytype;
YYSTYPE *yyvaluep;
+ SQL_input *info;
#endif
{
YYUSE (yyvaluep);
+ YYUSE (info);
if (!yymsg)
yymsg = "Deleting";
}
}
+
/* Prevent warnings from -Wmissing-prototypes. */
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
+int yyparse (SQL_input *info);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
-
-
-
-/*-------------------------.
-| yyparse or yypush_parse. |
-`-------------------------*/
+/*----------.
+| yyparse. |
+`----------*/
#ifdef YYPARSE_PARAM
#if (defined __STDC__ || defined __C99__FUNC__ \
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
int
-yyparse (void)
+yyparse (SQL_input *info)
#else
int
-yyparse ()
-
+yyparse (info)
+ SQL_input *info;
#endif
#endif
{
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
- if (yyn == YYPACT_NINF)
+ if (yypact_value_is_default (yyn))
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
yyn = yytable[yyn];
if (yyn <= 0)
{
- if (yyn == 0 || yyn == YYTABLE_NINF)
- goto yyerrlab;
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
{
case 2:
-/* Line 1455 of yacc.c */
-#line 133 "sql.y"
+/* Line 1806 of yacc.c */
+#line 118 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
*sql->view = (yyvsp[(1) - (1)].query);
- ;}
+ }
break;
case 10:
-/* Line 1455 of yacc.c */
-#line 151 "sql.y"
+/* Line 1806 of yacc.c */
+#line 136 "sql.y"
{
SQL_input *sql = (SQL_input*) info;
MSIVIEW *insert = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), insert );
- ;}
+ }
break;
case 11:
-/* Line 1455 of yacc.c */
-#line 162 "sql.y"
+/* Line 1806 of yacc.c */
+#line 147 "sql.y"
{
SQL_input *sql = (SQL_input*) info;
MSIVIEW *insert = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), insert );
- ;}
+ }
break;
case 12:
-/* Line 1455 of yacc.c */
-#line 176 "sql.y"
+/* Line 1806 of yacc.c */
+#line 161 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW *create = NULL;
}
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), create );
- ;}
+ }
break;
case 13:
-/* Line 1455 of yacc.c */
-#line 193 "sql.y"
+/* Line 1806 of yacc.c */
+#line 178 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW *create = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), create );
- ;}
+ }
break;
case 14:
-/* Line 1455 of yacc.c */
-#line 209 "sql.y"
+/* Line 1806 of yacc.c */
+#line 194 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW *update = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), update );
- ;}
+ }
break;
case 15:
-/* Line 1455 of yacc.c */
-#line 220 "sql.y"
+/* Line 1806 of yacc.c */
+#line 205 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW *update = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), update );
- ;}
+ }
break;
case 16:
-/* Line 1455 of yacc.c */
-#line 234 "sql.y"
+/* Line 1806 of yacc.c */
+#line 219 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW *delete = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), delete );
- ;}
+ }
break;
case 17:
-/* Line 1455 of yacc.c */
-#line 248 "sql.y"
+/* Line 1806 of yacc.c */
+#line 233 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW *alter = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter );
- ;}
+ }
break;
case 18:
-/* Line 1455 of yacc.c */
-#line 259 "sql.y"
+/* Line 1806 of yacc.c */
+#line 244 "sql.y"
{
SQL_input *sql = (SQL_input *)info;
MSIVIEW *alter = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter );
- ;}
+ }
break;
case 19:
-/* Line 1455 of yacc.c */
-#line 270 "sql.y"
+/* Line 1806 of yacc.c */
+#line 255 "sql.y"
{
SQL_input *sql = (SQL_input *)info;
MSIVIEW *alter = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), alter );
- ;}
+ }
break;
case 20:
-/* Line 1455 of yacc.c */
-#line 284 "sql.y"
+/* Line 1806 of yacc.c */
+#line 269 "sql.y"
{
(yyval.integer) = 1;
- ;}
+ }
break;
case 21:
-/* Line 1455 of yacc.c */
-#line 288 "sql.y"
+/* Line 1806 of yacc.c */
+#line 273 "sql.y"
{
(yyval.integer) = -1;
- ;}
+ }
break;
case 22:
-/* Line 1455 of yacc.c */
-#line 295 "sql.y"
+/* Line 1806 of yacc.c */
+#line 280 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW* drop = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), drop );
- ;}
+ }
break;
case 23:
-/* Line 1455 of yacc.c */
-#line 310 "sql.y"
+/* Line 1806 of yacc.c */
+#line 295 "sql.y"
{
if( SQL_MarkPrimaryKeys( &(yyvsp[(1) - (4)].column_list), (yyvsp[(4) - (4)].column_list) ) )
(yyval.column_list) = (yyvsp[(1) - (4)].column_list);
else
(yyval.column_list) = NULL;
- ;}
+ }
break;
case 24:
-/* Line 1455 of yacc.c */
-#line 320 "sql.y"
+/* Line 1806 of yacc.c */
+#line 305 "sql.y"
{
column_info *ci;
ci->next = (yyvsp[(3) - (3)].column_list);
(yyval.column_list) = (yyvsp[(1) - (3)].column_list);
- ;}
+ }
break;
case 25:
-/* Line 1455 of yacc.c */
-#line 330 "sql.y"
+/* Line 1806 of yacc.c */
+#line 315 "sql.y"
{
(yyval.column_list) = (yyvsp[(1) - (1)].column_list);
- ;}
+ }
break;
case 26:
-/* Line 1455 of yacc.c */
-#line 337 "sql.y"
+/* Line 1806 of yacc.c */
+#line 322 "sql.y"
{
(yyval.column_list) = (yyvsp[(1) - (2)].column_list);
(yyval.column_list)->type = ((yyvsp[(2) - (2)].column_type) | MSITYPE_VALID);
(yyval.column_list)->temporary = (yyvsp[(2) - (2)].column_type) & MSITYPE_TEMPORARY ? TRUE : FALSE;
- ;}
+ }
break;
case 27:
-/* Line 1455 of yacc.c */
-#line 346 "sql.y"
+/* Line 1806 of yacc.c */
+#line 331 "sql.y"
{
(yyval.column_type) = (yyvsp[(1) - (1)].column_type);
- ;}
+ }
break;
case 28:
-/* Line 1455 of yacc.c */
-#line 350 "sql.y"
+/* Line 1806 of yacc.c */
+#line 335 "sql.y"
{
(yyval.column_type) = (yyvsp[(1) - (2)].column_type) | MSITYPE_LOCALIZABLE;
- ;}
+ }
break;
case 29:
-/* Line 1455 of yacc.c */
-#line 354 "sql.y"
+/* Line 1806 of yacc.c */
+#line 339 "sql.y"
{
(yyval.column_type) = (yyvsp[(1) - (2)].column_type) | MSITYPE_TEMPORARY;
- ;}
+ }
break;
case 30:
-/* Line 1455 of yacc.c */
-#line 361 "sql.y"
+/* Line 1806 of yacc.c */
+#line 346 "sql.y"
{
(yyval.column_type) |= MSITYPE_NULLABLE;
- ;}
+ }
break;
case 31:
-/* Line 1455 of yacc.c */
-#line 365 "sql.y"
+/* Line 1806 of yacc.c */
+#line 350 "sql.y"
{
(yyval.column_type) = (yyvsp[(1) - (3)].column_type);
- ;}
+ }
break;
case 32:
-/* Line 1455 of yacc.c */
-#line 372 "sql.y"
+/* Line 1806 of yacc.c */
+#line 357 "sql.y"
{
(yyval.column_type) = MSITYPE_STRING | 1;
- ;}
+ }
break;
case 33:
-/* Line 1455 of yacc.c */
-#line 376 "sql.y"
+/* Line 1806 of yacc.c */
+#line 361 "sql.y"
{
(yyval.column_type) = MSITYPE_STRING | 0x400 | (yyvsp[(3) - (4)].column_type);
- ;}
+ }
break;
case 34:
-/* Line 1455 of yacc.c */
-#line 380 "sql.y"
+/* Line 1806 of yacc.c */
+#line 365 "sql.y"
{
(yyval.column_type) = MSITYPE_STRING | 0x400;
- ;}
+ }
break;
case 35:
-/* Line 1455 of yacc.c */
-#line 384 "sql.y"
+/* Line 1806 of yacc.c */
+#line 369 "sql.y"
{
(yyval.column_type) = 2 | 0x400;
- ;}
+ }
break;
case 36:
-/* Line 1455 of yacc.c */
-#line 388 "sql.y"
+/* Line 1806 of yacc.c */
+#line 373 "sql.y"
{
(yyval.column_type) = 2 | 0x400;
- ;}
+ }
break;
case 37:
-/* Line 1455 of yacc.c */
-#line 392 "sql.y"
+/* Line 1806 of yacc.c */
+#line 377 "sql.y"
{
(yyval.column_type) = 4;
- ;}
+ }
break;
case 38:
-/* Line 1455 of yacc.c */
-#line 396 "sql.y"
+/* Line 1806 of yacc.c */
+#line 381 "sql.y"
{
(yyval.column_type) = MSITYPE_STRING | MSITYPE_VALID;
- ;}
+ }
break;
case 39:
-/* Line 1455 of yacc.c */
-#line 403 "sql.y"
+/* Line 1806 of yacc.c */
+#line 388 "sql.y"
{
if( ( (yyvsp[(1) - (1)].integer) > 255 ) || ( (yyvsp[(1) - (1)].integer) < 0 ) )
YYABORT;
(yyval.column_type) = (yyvsp[(1) - (1)].integer);
- ;}
+ }
break;
case 40:
-/* Line 1455 of yacc.c */
-#line 412 "sql.y"
+/* Line 1806 of yacc.c */
+#line 397 "sql.y"
{
(yyval.query) = (yyvsp[(2) - (2)].query);
- ;}
+ }
break;
case 41:
-/* Line 1455 of yacc.c */
-#line 416 "sql.y"
+/* Line 1806 of yacc.c */
+#line 401 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW* distinct = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), distinct );
- ;}
+ }
break;
case 42:
-/* Line 1455 of yacc.c */
-#line 431 "sql.y"
+/* Line 1806 of yacc.c */
+#line 416 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW* select = NULL;
}
else
(yyval.query) = (yyvsp[(2) - (2)].query);
- ;}
+ }
break;
case 44:
-/* Line 1455 of yacc.c */
-#line 452 "sql.y"
+/* Line 1806 of yacc.c */
+#line 437 "sql.y"
{
(yyvsp[(1) - (3)].column_list)->next = (yyvsp[(3) - (3)].column_list);
- ;}
+ }
break;
case 45:
-/* Line 1455 of yacc.c */
-#line 456 "sql.y"
+/* Line 1806 of yacc.c */
+#line 441 "sql.y"
{
(yyval.column_list) = NULL;
- ;}
+ }
break;
case 47:
-/* Line 1455 of yacc.c */
-#line 464 "sql.y"
+/* Line 1806 of yacc.c */
+#line 449 "sql.y"
{
(yyvsp[(1) - (3)].column_list)->next = (yyvsp[(3) - (3)].column_list);
- ;}
+ }
break;
case 48:
-/* Line 1455 of yacc.c */
-#line 468 "sql.y"
+/* Line 1806 of yacc.c */
+#line 453 "sql.y"
{
(yyval.column_list) = NULL;
- ;}
+ }
break;
case 49:
-/* Line 1455 of yacc.c */
-#line 475 "sql.y"
+/* Line 1806 of yacc.c */
+#line 460 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW* table = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), table );
- ;}
+ }
break;
case 50:
-/* Line 1455 of yacc.c */
-#line 487 "sql.y"
+/* Line 1806 of yacc.c */
+#line 472 "sql.y"
{
UINT r;
}
(yyval.query) = (yyvsp[(1) - (4)].query);
- ;}
+ }
break;
case 52:
-/* Line 1455 of yacc.c */
-#line 504 "sql.y"
+/* Line 1806 of yacc.c */
+#line 489 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW* where = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), where );
- ;}
+ }
break;
case 53:
-/* Line 1455 of yacc.c */
-#line 516 "sql.y"
+/* Line 1806 of yacc.c */
+#line 501 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
MSIVIEW* where = NULL;
YYABORT;
PARSER_BUBBLE_UP_VIEW( sql, (yyval.query), where );
- ;}
+ }
break;
case 54:
-/* Line 1455 of yacc.c */
-#line 531 "sql.y"
+/* Line 1806 of yacc.c */
+#line 516 "sql.y"
{
(yyval.string) = (yyvsp[(1) - (1)].string);
- ;}
+ }
break;
case 55:
-/* Line 1455 of yacc.c */
-#line 535 "sql.y"
+/* Line 1806 of yacc.c */
+#line 520 "sql.y"
{
(yyval.string) = parser_add_table( info, (yyvsp[(3) - (3)].string), (yyvsp[(1) - (3)].string) );
if (!(yyval.string))
YYABORT;
- ;}
+ }
break;
case 56:
-/* Line 1455 of yacc.c */
-#line 544 "sql.y"
+/* Line 1806 of yacc.c */
+#line 529 "sql.y"
{
(yyval.expr) = (yyvsp[(2) - (3)].expr);
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 57:
-/* Line 1455 of yacc.c */
-#line 550 "sql.y"
+/* Line 1806 of yacc.c */
+#line 535 "sql.y"
{
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_AND, (yyvsp[(3) - (3)].expr) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 58:
-/* Line 1455 of yacc.c */
-#line 556 "sql.y"
+/* Line 1806 of yacc.c */
+#line 541 "sql.y"
{
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_OR, (yyvsp[(3) - (3)].expr) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 59:
-/* Line 1455 of yacc.c */
-#line 562 "sql.y"
+/* Line 1806 of yacc.c */
+#line 547 "sql.y"
{
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_EQ, (yyvsp[(3) - (3)].expr) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 60:
-/* Line 1455 of yacc.c */
-#line 568 "sql.y"
+/* Line 1806 of yacc.c */
+#line 553 "sql.y"
{
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_GT, (yyvsp[(3) - (3)].expr) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 61:
-/* Line 1455 of yacc.c */
-#line 574 "sql.y"
+/* Line 1806 of yacc.c */
+#line 559 "sql.y"
{
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_LT, (yyvsp[(3) - (3)].expr) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 62:
-/* Line 1455 of yacc.c */
-#line 580 "sql.y"
+/* Line 1806 of yacc.c */
+#line 565 "sql.y"
{
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_LE, (yyvsp[(3) - (3)].expr) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 63:
-/* Line 1455 of yacc.c */
-#line 586 "sql.y"
+/* Line 1806 of yacc.c */
+#line 571 "sql.y"
{
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_GE, (yyvsp[(3) - (3)].expr) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 64:
-/* Line 1455 of yacc.c */
-#line 592 "sql.y"
+/* Line 1806 of yacc.c */
+#line 577 "sql.y"
{
(yyval.expr) = EXPR_complex( info, (yyvsp[(1) - (3)].expr), OP_NE, (yyvsp[(3) - (3)].expr) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 65:
-/* Line 1455 of yacc.c */
-#line 598 "sql.y"
+/* Line 1806 of yacc.c */
+#line 583 "sql.y"
{
(yyval.expr) = EXPR_unary( info, (yyvsp[(1) - (3)].expr), OP_ISNULL );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 66:
-/* Line 1455 of yacc.c */
-#line 604 "sql.y"
+/* Line 1806 of yacc.c */
+#line 589 "sql.y"
{
(yyval.expr) = EXPR_unary( info, (yyvsp[(1) - (4)].expr), OP_NOTNULL );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 69:
-/* Line 1455 of yacc.c */
-#line 618 "sql.y"
+/* Line 1806 of yacc.c */
+#line 603 "sql.y"
{
(yyval.column_list) = parser_alloc_column( info, NULL, NULL );
if( !(yyval.column_list) )
YYABORT;
(yyval.column_list)->val = (yyvsp[(1) - (1)].expr);
- ;}
+ }
break;
case 70:
-/* Line 1455 of yacc.c */
-#line 625 "sql.y"
+/* Line 1806 of yacc.c */
+#line 610 "sql.y"
{
(yyval.column_list) = parser_alloc_column( info, NULL, NULL );
if( !(yyval.column_list) )
YYABORT;
(yyval.column_list)->val = (yyvsp[(1) - (3)].expr);
(yyval.column_list)->next = (yyvsp[(3) - (3)].column_list);
- ;}
+ }
break;
case 72:
-/* Line 1455 of yacc.c */
-#line 637 "sql.y"
+/* Line 1806 of yacc.c */
+#line 622 "sql.y"
{
(yyval.column_list) = (yyvsp[(1) - (3)].column_list);
(yyval.column_list)->next = (yyvsp[(3) - (3)].column_list);
- ;}
+ }
break;
case 73:
-/* Line 1455 of yacc.c */
-#line 645 "sql.y"
+/* Line 1806 of yacc.c */
+#line 630 "sql.y"
{
(yyval.column_list) = (yyvsp[(1) - (3)].column_list);
(yyval.column_list)->val = (yyvsp[(3) - (3)].expr);
- ;}
+ }
break;
case 74:
-/* Line 1455 of yacc.c */
-#line 653 "sql.y"
+/* Line 1806 of yacc.c */
+#line 638 "sql.y"
{
(yyval.expr) = EXPR_ival( info, (yyvsp[(1) - (1)].integer) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 75:
-/* Line 1455 of yacc.c */
-#line 659 "sql.y"
+/* Line 1806 of yacc.c */
+#line 644 "sql.y"
{
(yyval.expr) = EXPR_ival( info, -(yyvsp[(2) - (2)].integer) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 76:
-/* Line 1455 of yacc.c */
-#line 665 "sql.y"
+/* Line 1806 of yacc.c */
+#line 650 "sql.y"
{
(yyval.expr) = EXPR_sval( info, &(yyvsp[(1) - (1)].str) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 77:
-/* Line 1455 of yacc.c */
-#line 671 "sql.y"
+/* Line 1806 of yacc.c */
+#line 656 "sql.y"
{
(yyval.expr) = EXPR_wildcard( info );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 78:
-/* Line 1455 of yacc.c */
-#line 680 "sql.y"
+/* Line 1806 of yacc.c */
+#line 665 "sql.y"
{
(yyval.expr) = EXPR_column( info, (yyvsp[(1) - (1)].column_list) );
if( !(yyval.expr) )
YYABORT;
- ;}
+ }
break;
case 79:
-/* Line 1455 of yacc.c */
-#line 689 "sql.y"
+/* Line 1806 of yacc.c */
+#line 674 "sql.y"
{
(yyval.column_list) = parser_alloc_column( info, (yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].string) );
if( !(yyval.column_list) )
YYABORT;
- ;}
+ }
break;
case 80:
-/* Line 1455 of yacc.c */
-#line 695 "sql.y"
+/* Line 1806 of yacc.c */
+#line 680 "sql.y"
{
(yyval.column_list) = parser_alloc_column( info, NULL, (yyvsp[(1) - (1)].string) );
if( !(yyval.column_list) )
YYABORT;
- ;}
+ }
break;
case 81:
-/* Line 1455 of yacc.c */
-#line 704 "sql.y"
+/* Line 1806 of yacc.c */
+#line 689 "sql.y"
{
(yyval.column_list) = parser_alloc_column( info, (yyvsp[(1) - (3)].string), (yyvsp[(3) - (3)].string) );
if( !(yyval.column_list) )
YYABORT;
- ;}
+ }
break;
case 82:
-/* Line 1455 of yacc.c */
-#line 710 "sql.y"
+/* Line 1806 of yacc.c */
+#line 695 "sql.y"
{
(yyval.column_list) = parser_alloc_column( info, NULL, (yyvsp[(1) - (1)].string) );
if( !(yyval.column_list) )
YYABORT;
- ;}
+ }
break;
case 83:
-/* Line 1455 of yacc.c */
-#line 716 "sql.y"
+/* Line 1806 of yacc.c */
+#line 701 "sql.y"
{
(yyval.column_list) = parser_alloc_column( info, NULL, (yyvsp[(1) - (1)].string) );
if( !(yyval.column_list) )
YYABORT;
- ;}
+ }
break;
case 84:
-/* Line 1455 of yacc.c */
-#line 725 "sql.y"
+/* Line 1806 of yacc.c */
+#line 710 "sql.y"
{
(yyval.string) = (yyvsp[(1) - (1)].string);
- ;}
+ }
break;
case 85:
-/* Line 1455 of yacc.c */
-#line 732 "sql.y"
+/* Line 1806 of yacc.c */
+#line 717 "sql.y"
{
if ( SQL_getstring( info, &(yyvsp[(1) - (1)].str), &(yyval.string) ) != ERROR_SUCCESS || !(yyval.string) )
YYABORT;
- ;}
+ }
break;
case 86:
-/* Line 1455 of yacc.c */
-#line 740 "sql.y"
+/* Line 1806 of yacc.c */
+#line 725 "sql.y"
{
if ( SQL_getstring( info, &(yyvsp[(1) - (1)].str), &(yyval.string) ) != ERROR_SUCCESS || !(yyval.string) )
YYABORT;
- ;}
+ }
break;
case 87:
-/* Line 1455 of yacc.c */
-#line 748 "sql.y"
+/* Line 1806 of yacc.c */
+#line 733 "sql.y"
{
(yyval.integer) = SQL_getint( info );
- ;}
+ }
break;
-/* Line 1455 of yacc.c */
-#line 2488 "sql.tab.c"
+/* Line 1806 of yacc.c */
+#line 2515 "sql.tab.c"
default: break;
}
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
++yynerrs;
#if ! YYERROR_VERBOSE
- yyerror (YY_("syntax error"));
+ yyerror (info, YY_("syntax error"));
#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
{
- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
- {
- YYSIZE_T yyalloc = 2 * yysize;
- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
- yyalloc = YYSTACK_ALLOC_MAXIMUM;
- if (yymsg != yymsgbuf)
- YYSTACK_FREE (yymsg);
- yymsg = (char *) YYSTACK_ALLOC (yyalloc);
- if (yymsg)
- yymsg_alloc = yyalloc;
- else
- {
- yymsg = yymsgbuf;
- yymsg_alloc = sizeof yymsgbuf;
- }
- }
-
- if (0 < yysize && yysize <= yymsg_alloc)
- {
- (void) yysyntax_error (yymsg, yystate, yychar);
- yyerror (yymsg);
- }
- else
- {
- yyerror (YY_("syntax error"));
- if (yysize != 0)
- goto yyexhaustedlab;
- }
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (info, yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
}
+# undef YYSYNTAX_ERROR
#endif
}
else
{
yydestruct ("Error: discarding",
- yytoken, &yylval);
+ yytoken, &yylval, info);
yychar = YYEMPTY;
}
}
for (;;)
{
yyn = yypact[yystate];
- if (yyn != YYPACT_NINF)
+ if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
yydestruct ("Error: popping",
- yystos[yystate], yyvsp);
+ yystos[yystate], yyvsp, info);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
yyexhaustedlab:
- yyerror (YY_("memory exhausted"));
+ yyerror (info, YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
if (yychar != YYEMPTY)
- yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval);
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, info);
+ }
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp);
+ yystos[*yyssp], yyvsp, info);
YYPOPSTACK (1);
}
#ifndef yyoverflow
-/* Line 1675 of yacc.c */
-#line 753 "sql.y"
+/* Line 2067 of yacc.c */
+#line 738 "sql.y"
static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table )
return r;
}
-static int sql_error( const char *str )
+static int sql_error( SQL_input *info, const char *str )
{
return 0;
}
+/* A Bison parser, made by GNU Bison 2.5. */
-/* A Bison parser, made by GNU Bison 2.4.1. */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
+/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
typedef union YYSTYPE
{
-/* Line 1676 of yacc.c */
-#line 83 "sql.y"
+/* Line 2068 of yacc.c */
+#line 68 "sql.y"
struct sql_str str;
LPWSTR string;
-/* Line 1676 of yacc.c */
-#line 127 "sql.tab.h"
+/* Line 2068 of yacc.c */
+#line 125 "sql.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
#include "wine/debug.h"
#include "wine/unicode.h"
-#define YYLEX_PARAM info
-#define YYPARSE_PARAM info
-
-static int sql_error(const char *str);
-
WINE_DEFAULT_DEBUG_CHANNEL(msi);
-typedef struct tag_SQL_input
-{
- MSIDATABASE *db;
- LPCWSTR command;
- DWORD n, len;
- UINT r;
- MSIVIEW **view; /* View structure for the resulting query. This value
- * tracks the view currently being created so we can free
- * this view on syntax error.
- */
- struct list *mem;
-} SQL_input;
-
static UINT SQL_getstring( void *info, const struct sql_str *strdata, LPWSTR *str );
static INT SQL_getint( void *info );
static int sql_lex( void *SQL_lval, SQL_input *info );
+static int sql_error( SQL_input *info, const char *str);
static LPWSTR parser_add_table( void *info, LPCWSTR list, LPCWSTR table );
static void *parser_alloc( void *info, unsigned int sz );
%}
+%lex-param { SQL_input *info }
+%parse-param { SQL_input *info }
%pure-parser
%union
return r;
}
-static int sql_error( const char *str )
+static int sql_error( SQL_input *info, const char *str )
{
return 0;
}
{
MSICOLUMNINFO columninfo;
UINT r;
+ int ival;
if ( (iField <= 0) ||
(iField > tv->num_cols) ||
}
else if ( bytes_per_column( tv->db, &columninfo, LONG_STR_BYTES ) == 2 )
{
- *pvalue = 0x8000 + MSI_RecordGetInteger( rec, iField );
- if ( *pvalue & 0xffff0000 )
+ ival = MSI_RecordGetInteger( rec, iField );
+ if (ival == 0x80000000) *pvalue = 0x8000;
+ else
{
- ERR("field %u value %d out of range\n", iField, *pvalue - 0x8000);
- return ERROR_FUNCTION_FAILED;
+ *pvalue = 0x8000 + MSI_RecordGetInteger( rec, iField );
+ if (*pvalue & 0xffff0000)
+ {
+ ERR("field %u value %d out of range\n", iField, *pvalue - 0x8000);
+ return ERROR_FUNCTION_FAILED;
+ }
}
}
else
{
- INT ival = MSI_RecordGetInteger( rec, iField );
+ ival = MSI_RecordGetInteger( rec, iField );
*pvalue = ival ^ 0x80000000;
}
reactos/dll/win32/msgsm32.acm # Synced to Wine-1.7.1
reactos/dll/win32/mshtml # Synced to Wine-1.5.26
reactos/dll/win32/mshtml.tlb # Synced to Wine-1.5.26
-reactos/dll/win32/msi # Synced to Wine-1.5.26
+reactos/dll/win32/msi # Synced to Wine-1.7.1
reactos/dll/win32/msimg32 # Synced to Wine-1.5.19
reactos/dll/win32/msimtf # Synced to Wine-1.5.19
reactos/dll/win32/msisip # Synced to Wine-1.5.19