aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile5
-rw-r--r--src/backend/Makefile9
-rw-r--r--src/backend/access/gin/ginarrayproc.c13
-rw-r--r--src/backend/catalog/Makefile4
-rw-r--r--src/backend/catalog/aclchk.c75
-rw-r--r--src/backend/catalog/dependency.c141
-rw-r--r--src/backend/catalog/namespace.c557
-rw-r--r--src/backend/catalog/system_views.sql73
-rw-r--r--src/backend/commands/Makefile5
-rw-r--r--src/backend/commands/alter.c26
-rw-r--r--src/backend/commands/comment.c80
-rw-r--r--src/backend/commands/tablecmds.c7
-rw-r--r--src/backend/commands/tsearchcmds.c1948
-rw-r--r--src/backend/parser/gram.y233
-rw-r--r--src/backend/parser/keywords.c8
-rw-r--r--src/backend/parser/parse_coerce.c8
-rw-r--r--src/backend/snowball/Makefile144
-rw-r--r--src/backend/snowball/README47
-rw-r--r--src/backend/snowball/dict_snowball.c326
-rw-r--r--src/backend/snowball/libstemmer/api.c64
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c337
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c624
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c1117
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c762
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c1246
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c503
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_hungarian.c1230
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c1065
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c297
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c749
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c1017
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c1093
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c307
-rw-r--r--src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c998
-rw-r--r--src/backend/snowball/libstemmer/stem_KOI8_R_russian.c700
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_danish.c339
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_dutch.c634
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_english.c1125
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_finnish.c768
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_french.c1256
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_german.c509
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c1234
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_italian.c1073
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c299
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_porter.c755
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c1023
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_romanian.c1004
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_russian.c694
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_spanish.c1097
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_swedish.c309
-rw-r--r--src/backend/snowball/libstemmer/stem_UTF_8_turkish.c2205
-rw-r--r--src/backend/snowball/libstemmer/utilities.c473
-rw-r--r--src/backend/snowball/snowball.sql.in26
-rw-r--r--src/backend/snowball/snowball_func.sql.in18
-rw-r--r--src/backend/snowball/stopwords/danish.stop94
-rw-r--r--src/backend/snowball/stopwords/dutch.stop101
-rw-r--r--src/backend/snowball/stopwords/english.stop128
-rw-r--r--src/backend/snowball/stopwords/finnish.stop235
-rw-r--r--src/backend/snowball/stopwords/french.stop155
-rw-r--r--src/backend/snowball/stopwords/german.stop231
-rw-r--r--src/backend/snowball/stopwords/hungarian.stop199
-rw-r--r--src/backend/snowball/stopwords/italian.stop279
-rw-r--r--src/backend/snowball/stopwords/norwegian.stop176
-rw-r--r--src/backend/snowball/stopwords/portuguese.stop203
-rw-r--r--src/backend/snowball/stopwords/russian.stop151
-rw-r--r--src/backend/snowball/stopwords/spanish.stop313
-rw-r--r--src/backend/snowball/stopwords/swedish.stop114
-rw-r--r--src/backend/tcop/utility.c118
-rw-r--r--src/backend/tsearch/Makefile51
-rw-r--r--src/backend/tsearch/dict.c131
-rw-r--r--src/backend/tsearch/dict_ispell.c164
-rw-r--r--src/backend/tsearch/dict_simple.c65
-rw-r--r--src/backend/tsearch/dict_synonym.c176
-rw-r--r--src/backend/tsearch/dict_thesaurus.c887
-rw-r--r--src/backend/tsearch/regis.c236
-rw-r--r--src/backend/tsearch/spell.c1747
-rw-r--r--src/backend/tsearch/synonym.syn.sample3
-rw-r--r--src/backend/tsearch/thesaurus.ths.sample20
-rw-r--r--src/backend/tsearch/to_tsany.c363
-rw-r--r--src/backend/tsearch/ts_locale.c241
-rw-r--r--src/backend/tsearch/ts_parse.c626
-rw-r--r--src/backend/tsearch/ts_utils.c330
-rw-r--r--src/backend/tsearch/wparser.c360
-rw-r--r--src/backend/tsearch/wparser_def.c1873
-rw-r--r--src/backend/utils/adt/Makefile9
-rw-r--r--src/backend/utils/adt/regproc.c229
-rw-r--r--src/backend/utils/adt/selfuncs.c6
-rw-r--r--src/backend/utils/adt/tsginidx.c157
-rw-r--r--src/backend/utils/adt/tsgistidx.c784
-rw-r--r--src/backend/utils/adt/tsquery.c767
-rw-r--r--src/backend/utils/adt/tsquery_cleanup.c261
-rw-r--r--src/backend/utils/adt/tsquery_gist.c259
-rw-r--r--src/backend/utils/adt/tsquery_op.c289
-rw-r--r--src/backend/utils/adt/tsquery_rewrite.c524
-rw-r--r--src/backend/utils/adt/tsquery_util.c317
-rw-r--r--src/backend/utils/adt/tsrank.c804
-rw-r--r--src/backend/utils/adt/tsvector.c683
-rw-r--r--src/backend/utils/adt/tsvector_op.c1334
-rw-r--r--src/backend/utils/cache/Makefile4
-rw-r--r--src/backend/utils/cache/catcache.c4
-rw-r--r--src/backend/utils/cache/syscache.c115
-rw-r--r--src/backend/utils/cache/ts_cache.c641
-rw-r--r--src/backend/utils/misc/guc.c18
-rw-r--r--src/backend/utils/misc/postgresql.conf.sample3
-rw-r--r--src/bin/initdb/initdb.c188
-rw-r--r--src/bin/pg_dump/common.c26
-rw-r--r--src/bin/pg_dump/pg_backup_archiver.c10
-rw-r--r--src/bin/pg_dump/pg_dump.c722
-rw-r--r--src/bin/pg_dump/pg_dump.h41
-rw-r--r--src/bin/pg_dump/pg_dump_sort.c30
-rw-r--r--src/bin/psql/command.c23
-rw-r--r--src/bin/psql/describe.c520
-rw-r--r--src/bin/psql/describe.h14
-rw-r--r--src/bin/psql/help.c6
-rw-r--r--src/include/access/gin.h6
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/dependency.h10
-rw-r--r--src/include/catalog/indexing.h25
-rw-r--r--src/include/catalog/namespace.h16
-rw-r--r--src/include/catalog/pg_aggregate.h5
-rw-r--r--src/include/catalog/pg_amop.h37
-rw-r--r--src/include/catalog/pg_amproc.h79
-rw-r--r--src/include/catalog/pg_cast.h16
-rw-r--r--src/include/catalog/pg_opclass.h7
-rw-r--r--src/include/catalog/pg_operator.h30
-rw-r--r--src/include/catalog/pg_opfamily.h10
-rw-r--r--src/include/catalog/pg_proc.h264
-rw-r--r--src/include/catalog/pg_ts_config.h65
-rw-r--r--src/include/catalog/pg_ts_config_map.h83
-rw-r--r--src/include/catalog/pg_ts_dict.h68
-rw-r--r--src/include/catalog/pg_ts_parser.h72
-rw-r--r--src/include/catalog/pg_ts_template.h72
-rw-r--r--src/include/catalog/pg_type.h25
-rw-r--r--src/include/commands/defrem.h31
-rw-r--r--src/include/nodes/nodes.h4
-rw-r--r--src/include/nodes/parsenodes.h37
-rw-r--r--src/include/snowball/header.h62
-rw-r--r--src/include/snowball/libstemmer/api.h26
-rw-r--r--src/include/snowball/libstemmer/header.h58
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_danish.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_dutch.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_english.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_finnish.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_french.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_german.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_hungarian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_italian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_norwegian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_porter.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_portuguese.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_spanish.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_1_swedish.h16
-rw-r--r--src/include/snowball/libstemmer/stem_ISO_8859_2_romanian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_KOI8_R_russian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_danish.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_dutch.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_english.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_finnish.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_french.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_german.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_hungarian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_italian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_norwegian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_porter.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_portuguese.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_romanian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_russian.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_spanish.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_swedish.h16
-rw-r--r--src/include/snowball/libstemmer/stem_UTF_8_turkish.h16
-rw-r--r--src/include/tsearch/dicts/regis.h49
-rw-r--r--src/include/tsearch/dicts/spell.h153
-rw-r--r--src/include/tsearch/ts_cache.h98
-rw-r--r--src/include/tsearch/ts_locale.h88
-rw-r--r--src/include/tsearch/ts_public.h128
-rw-r--r--src/include/tsearch/ts_type.h240
-rw-r--r--src/include/tsearch/ts_utils.h315
-rw-r--r--src/include/utils/acl.h6
-rw-r--r--src/include/utils/builtins.h10
-rw-r--r--src/include/utils/syscache.h15
-rw-r--r--src/makefiles/Makefile.hpux4
-rw-r--r--src/test/regress/data/tsearch.data508
-rw-r--r--src/test/regress/expected/create_table.out4
-rw-r--r--src/test/regress/expected/oidjoins.out136
-rw-r--r--src/test/regress/expected/opr_sanity.out5
-rw-r--r--src/test/regress/expected/sanity_check.out8
-rw-r--r--src/test/regress/expected/tsearch.out893
-rw-r--r--src/test/regress/expected/tstypes.out495
-rw-r--r--src/test/regress/input/copy.source2
-rw-r--r--src/test/regress/output/copy.source1
-rw-r--r--src/test/regress/output/misc.source3
-rw-r--r--src/test/regress/parallel_schedule34
-rw-r--r--src/test/regress/serial_schedule8
-rw-r--r--src/test/regress/sql/create_table.sql6
-rw-r--r--src/test/regress/sql/oidjoins.sql68
-rw-r--r--src/test/regress/sql/tsearch.sql292
-rw-r--r--src/test/regress/sql/tstypes.sql95
-rw-r--r--src/tools/findoidjoins/findoidjoins.c6
198 files changed, 54356 insertions, 139 deletions
diff --git a/src/Makefile b/src/Makefile
index 3539ff1de16..8d66bf62cac 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,7 +4,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
-# $PostgreSQL: pgsql/src/Makefile,v 1.41 2007/01/20 17:16:09 petere Exp $
+# $PostgreSQL: pgsql/src/Makefile,v 1.42 2007/08/21 01:11:12 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -18,6 +18,7 @@ all install installdirs uninstall distprep:
$(MAKE) -C timezone $@
$(MAKE) -C backend $@
$(MAKE) -C backend/utils/mb/conversion_procs $@
+ $(MAKE) -C backend/snowball $@
$(MAKE) -C include $@
$(MAKE) -C interfaces $@
$(MAKE) -C bin $@
@@ -47,6 +48,7 @@ clean:
$(MAKE) -C port $@
$(MAKE) -C timezone $@
$(MAKE) -C backend $@
+ $(MAKE) -C backend/snowball $@
$(MAKE) -C include $@
$(MAKE) -C interfaces $@
$(MAKE) -C bin $@
@@ -60,6 +62,7 @@ distclean maintainer-clean:
-$(MAKE) -C port $@
-$(MAKE) -C timezone $@
-$(MAKE) -C backend $@
+ -$(MAKE) -C backend/snowball $@
-$(MAKE) -C include $@
-$(MAKE) -C interfaces $@
-$(MAKE) -C bin $@
diff --git a/src/backend/Makefile b/src/backend/Makefile
index d2caa7036ce..9d2dbe62fa5 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -2,9 +2,10 @@
#
# Makefile for the postgres backend
#
-# Copyright (c) 1994, Regents of the University of California
+# Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
#
-# $PostgreSQL: pgsql/src/backend/Makefile,v 1.123 2007/07/24 09:00:27 mha Exp $
+# $PostgreSQL: pgsql/src/backend/Makefile,v 1.124 2007/08/21 01:11:12 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -15,7 +16,7 @@ include $(top_builddir)/src/Makefile.global
DIRS = access bootstrap catalog parser commands executor lib libpq \
main nodes optimizer port postmaster regex rewrite \
- storage tcop utils $(top_builddir)/src/timezone
+ storage tcop tsearch utils $(top_builddir)/src/timezone
SUBSYSOBJS = $(DIRS:%=%/SUBSYS.o)
@@ -166,6 +167,7 @@ ifeq ($(MAKE_DLL), true)
endif
endif
$(MAKE) -C catalog install-data
+ $(MAKE) -C tsearch install-data
$(INSTALL_DATA) $(srcdir)/libpq/pg_hba.conf.sample '$(DESTDIR)$(datadir)/pg_hba.conf.sample'
$(INSTALL_DATA) $(srcdir)/libpq/pg_ident.conf.sample '$(DESTDIR)$(datadir)/pg_ident.conf.sample'
$(INSTALL_DATA) $(srcdir)/utils/misc/postgresql.conf.sample '$(DESTDIR)$(datadir)/postgresql.conf.sample'
@@ -220,6 +222,7 @@ ifeq ($(MAKE_DLL), true)
endif
endif
$(MAKE) -C catalog uninstall-data
+ $(MAKE) -C tsearch uninstall-data
rm -f '$(DESTDIR)$(datadir)/pg_hba.conf.sample' \
'$(DESTDIR)$(datadir)/pg_ident.conf.sample' \
'$(DESTDIR)$(datadir)/postgresql.conf.sample' \
diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index a46def63c50..d608bedb605 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.9 2007/01/31 15:09:45 teodor Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.10 2007/08/21 01:11:12 tgl Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
@@ -62,7 +62,7 @@ ginarrayextract(PG_FUNCTION_ARGS)
if ( *nentries == 0 && PG_NARGS() == 3 )
{
- switch( PG_GETARG_UINT16(2) )
+ switch( PG_GETARG_UINT16(2) ) /* StrategyNumber */
{
case GinOverlapStrategy:
*nentries = -1; /* nobody can be found */
@@ -80,6 +80,15 @@ ginarrayextract(PG_FUNCTION_ARGS)
}
Datum
+ginqueryarrayextract(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(DirectFunctionCall3(ginarrayextract,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1),
+ PG_GETARG_DATUM(2)));
+}
+
+Datum
ginarrayconsistent(PG_FUNCTION_ARGS)
{
bool *check = (bool *) PG_GETARG_POINTER(0);
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index 3503385c2ac..6e87b2f6010 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -2,7 +2,7 @@
#
# Makefile for backend/catalog
#
-# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.64 2007/04/02 03:49:37 tgl Exp $
+# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.65 2007/08/21 01:11:13 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -35,6 +35,8 @@ POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
pg_database.h pg_tablespace.h pg_pltemplate.h \
pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \
+ pg_ts_config.h pg_ts_config_map.h pg_ts_dict.h \
+ pg_ts_parser.h pg_ts_template.h \
toasting.h indexing.h \
)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 292a737099e..96d238c7242 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.139 2007/04/20 02:37:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.140 2007/08/21 01:11:13 tgl Exp $
*
* NOTES
* See acl.h.
@@ -34,6 +34,8 @@
#include "catalog/pg_proc.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_dict.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
@@ -1416,7 +1418,11 @@ static const char *const no_priv_msg[MAX_ACL_KIND] =
/* ACL_KIND_CONVERSION */
gettext_noop("permission denied for conversion %s"),
/* ACL_KIND_TABLESPACE */
- gettext_noop("permission denied for tablespace %s")
+ gettext_noop("permission denied for tablespace %s"),
+ /* ACL_KIND_TSDICTIONARY */
+ gettext_noop("permission denied for text search dictionary %s"),
+ /* ACL_KIND_TSCONFIGURATION */
+ gettext_noop("permission denied for text search configuration %s")
};
static const char *const not_owner_msg[MAX_ACL_KIND] =
@@ -1444,7 +1450,11 @@ static const char *const not_owner_msg[MAX_ACL_KIND] =
/* ACL_KIND_CONVERSION */
gettext_noop("must be owner of conversion %s"),
/* ACL_KIND_TABLESPACE */
- gettext_noop("must be owner of tablespace %s")
+ gettext_noop("must be owner of tablespace %s"),
+ /* ACL_KIND_TSDICTIONARY */
+ gettext_noop("must be owner of text search dictionary %s"),
+ /* ACL_KIND_TSCONFIGURATION */
+ gettext_noop("must be owner of text search configuration %s")
};
@@ -2298,6 +2308,65 @@ pg_opfamily_ownercheck(Oid opf_oid, Oid roleid)
}
/*
+ * Ownership check for a text search dictionary (specified by OID).
+ */
+bool
+pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid)
+{
+ HeapTuple tuple;
+ Oid ownerId;
+
+ /* Superusers bypass all permission checking. */
+ if (superuser_arg(roleid))
+ return true;
+
+ tuple = SearchSysCache(TSDICTOID,
+ ObjectIdGetDatum(dict_oid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search dictionary with OID %u does not exist",
+ dict_oid)));
+
+ ownerId = ((Form_pg_ts_dict) GETSTRUCT(tuple))->dictowner;
+
+ ReleaseSysCache(tuple);
+
+ return has_privs_of_role(roleid, ownerId);
+}
+
+/*
+ * Ownership check for a text search configuration (specified by OID).
+ */
+bool
+pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid)
+{
+ HeapTuple tuple;
+ Oid ownerId;
+
+ /* Superusers bypass all permission checking. */
+ if (superuser_arg(roleid))
+ return true;
+
+ tuple = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(cfg_oid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search configuration with OID %u does not exist",
+ cfg_oid)));
+
+ ownerId = ((Form_pg_ts_config) GETSTRUCT(tuple))->cfgowner;
+
+ ReleaseSysCache(tuple);
+
+ return has_privs_of_role(roleid, ownerId);
+}
+
+
+/*
* Ownership check for a database (specified by OID).
*/
bool
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 6b58af65228..51bb4ba17f4 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.66 2007/06/05 21:31:04 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.67 2007/08/21 01:11:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -40,6 +40,10 @@
#include "catalog/pg_rewrite.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_trigger.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
@@ -97,6 +101,10 @@ static const Oid object_classes[MAX_OCLASS] = {
RewriteRelationId, /* OCLASS_REWRITE */
TriggerRelationId, /* OCLASS_TRIGGER */
NamespaceRelationId, /* OCLASS_SCHEMA */
+ TSParserRelationId, /* OCLASS_TSPARSER */
+ TSDictionaryRelationId, /* OCLASS_TSDICT */
+ TSTemplateRelationId, /* OCLASS_TSTEMPLATE */
+ TSConfigRelationId, /* OCLASS_TSCONFIG */
AuthIdRelationId, /* OCLASS_ROLE */
DatabaseRelationId, /* OCLASS_DATABASE */
TableSpaceRelationId /* OCLASS_TBLSPACE */
@@ -988,6 +996,22 @@ doDeletion(const ObjectAddress *object)
RemoveSchemaById(object->objectId);
break;
+ case OCLASS_TSPARSER:
+ RemoveTSParserById(object->objectId);
+ break;
+
+ case OCLASS_TSDICT:
+ RemoveTSDictionaryById(object->objectId);
+ break;
+
+ case OCLASS_TSTEMPLATE:
+ RemoveTSTemplateById(object->objectId);
+ break;
+
+ case OCLASS_TSCONFIG:
+ RemoveTSConfigurationById(object->objectId);
+ break;
+
/* OCLASS_ROLE, OCLASS_DATABASE, OCLASS_TBLSPACE not handled */
default:
@@ -1201,8 +1225,8 @@ find_expr_references_walker(Node *node,
/*
* If it's a regclass or similar literal referring to an existing
* object, add a reference to that object. (Currently, only the
- * regclass case has any likely use, but we may as well handle all the
- * OID-alias datatypes consistently.)
+ * regclass and regconfig cases have any likely use, but we may as
+ * well handle all the OID-alias datatypes consistently.)
*/
if (!con->constisnull)
{
@@ -1242,6 +1266,22 @@ find_expr_references_walker(Node *node,
add_object_address(OCLASS_TYPE, objoid, 0,
context->addrs);
break;
+ case REGCONFIGOID:
+ objoid = DatumGetObjectId(con->constvalue);
+ if (SearchSysCacheExists(TSCONFIGOID,
+ ObjectIdGetDatum(objoid),
+ 0, 0, 0))
+ add_object_address(OCLASS_TSCONFIG, objoid, 0,
+ context->addrs);
+ break;
+ case REGDICTIONARYOID:
+ objoid = DatumGetObjectId(con->constvalue);
+ if (SearchSysCacheExists(TSDICTOID,
+ ObjectIdGetDatum(objoid),
+ 0, 0, 0))
+ add_object_address(OCLASS_TSDICT, objoid, 0,
+ context->addrs);
+ break;
}
}
return false;
@@ -1606,6 +1646,21 @@ object_address_present(const ObjectAddress *object,
}
/*
+ * Record multiple dependencies from an ObjectAddresses array, after first
+ * removing any duplicates.
+ */
+void
+record_object_address_dependencies(const ObjectAddress *depender,
+ ObjectAddresses *referenced,
+ DependencyType behavior)
+{
+ eliminate_duplicate_dependencies(referenced);
+ recordMultipleDependencies(depender,
+ referenced->refs, referenced->numrefs,
+ behavior);
+}
+
+/*
* Clean up when done with an ObjectAddresses array.
*/
void
@@ -1690,6 +1745,22 @@ getObjectClass(const ObjectAddress *object)
Assert(object->objectSubId == 0);
return OCLASS_SCHEMA;
+ case TSParserRelationId:
+ Assert(object->objectSubId == 0);
+ return OCLASS_TSPARSER;
+
+ case TSDictionaryRelationId:
+ Assert(object->objectSubId == 0);
+ return OCLASS_TSDICT;
+
+ case TSTemplateRelationId:
+ Assert(object->objectSubId == 0);
+ return OCLASS_TSTEMPLATE;
+
+ case TSConfigRelationId:
+ Assert(object->objectSubId == 0);
+ return OCLASS_TSCONFIG;
+
case AuthIdRelationId:
Assert(object->objectSubId == 0);
return OCLASS_ROLE;
@@ -2080,6 +2151,70 @@ getObjectDescription(const ObjectAddress *object)
break;
}
+ case OCLASS_TSPARSER:
+ {
+ HeapTuple tup;
+
+ tup = SearchSysCache(TSPARSEROID,
+ ObjectIdGetDatum(object->objectId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search parser %u",
+ object->objectId);
+ appendStringInfo(&buffer, _("text search parser %s"),
+ NameStr(((Form_pg_ts_parser) GETSTRUCT(tup))->prsname));
+ ReleaseSysCache(tup);
+ break;
+ }
+
+ case OCLASS_TSDICT:
+ {
+ HeapTuple tup;
+
+ tup = SearchSysCache(TSDICTOID,
+ ObjectIdGetDatum(object->objectId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ object->objectId);
+ appendStringInfo(&buffer, _("text search dictionary %s"),
+ NameStr(((Form_pg_ts_dict) GETSTRUCT(tup))->dictname));
+ ReleaseSysCache(tup);
+ break;
+ }
+
+ case OCLASS_TSTEMPLATE:
+ {
+ HeapTuple tup;
+
+ tup = SearchSysCache(TSTEMPLATEOID,
+ ObjectIdGetDatum(object->objectId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search template %u",
+ object->objectId);
+ appendStringInfo(&buffer, _("text search template %s"),
+ NameStr(((Form_pg_ts_template) GETSTRUCT(tup))->tmplname));
+ ReleaseSysCache(tup);
+ break;
+ }
+
+ case OCLASS_TSCONFIG:
+ {
+ HeapTuple tup;
+
+ tup = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(object->objectId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ object->objectId);
+ appendStringInfo(&buffer, _("text search configuration %s"),
+ NameStr(((Form_pg_ts_config) GETSTRUCT(tup))->cfgname));
+ ReleaseSysCache(tup);
+ break;
+ }
+
case OCLASS_ROLE:
{
appendStringInfo(&buffer, _("role %s"),
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 2f8753bd2e0..84220bd4ce0 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.97 2007/07/25 22:16:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.98 2007/08/21 01:11:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,6 +29,10 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
@@ -189,6 +193,10 @@ Datum pg_function_is_visible(PG_FUNCTION_ARGS);
Datum pg_operator_is_visible(PG_FUNCTION_ARGS);
Datum pg_opclass_is_visible(PG_FUNCTION_ARGS);
Datum pg_conversion_is_visible(PG_FUNCTION_ARGS);
+Datum pg_ts_parser_is_visible(PG_FUNCTION_ARGS);
+Datum pg_ts_dict_is_visible(PG_FUNCTION_ARGS);
+Datum pg_ts_template_is_visible(PG_FUNCTION_ARGS);
+Datum pg_ts_config_is_visible(PG_FUNCTION_ARGS);
Datum pg_my_temp_schema(PG_FUNCTION_ARGS);
Datum pg_is_other_temp_schema(PG_FUNCTION_ARGS);
@@ -1315,6 +1323,521 @@ ConversionIsVisible(Oid conid)
}
/*
+ * TSParserGetPrsid - find a TS parser by possibly qualified name
+ *
+ * If not found, returns InvalidOid if failOK, else throws error
+ */
+Oid
+TSParserGetPrsid(List *names, bool failOK)
+{
+ char *schemaname;
+ char *parser_name;
+ Oid namespaceId;
+ Oid prsoid = InvalidOid;
+ ListCell *l;
+
+ /* deconstruct the name list */
+ DeconstructQualifiedName(names, &schemaname, &parser_name);
+
+ if (schemaname)
+ {
+ /* use exact schema given */
+ namespaceId = LookupExplicitNamespace(schemaname);
+ prsoid = GetSysCacheOid(TSPARSERNAMENSP,
+ PointerGetDatum(parser_name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0);
+ }
+ else
+ {
+ /* search for it in search path */
+ recomputeNamespacePath();
+
+ foreach(l, activeSearchPath)
+ {
+ namespaceId = lfirst_oid(l);
+
+ if (namespaceId == myTempNamespace)
+ continue; /* do not look in temp namespace */
+
+ prsoid = GetSysCacheOid(TSPARSERNAMENSP,
+ PointerGetDatum(parser_name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0);
+ if (OidIsValid(prsoid))
+ break;
+ }
+ }
+
+ if (!OidIsValid(prsoid) && !failOK)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search parser \"%s\" does not exist",
+ NameListToString(names))));
+
+ return prsoid;
+}
+
+/*
+ * TSParserIsVisible
+ * Determine whether a parser (identified by OID) is visible in the
+ * current search path. Visible means "would be found by searching
+ * for the unqualified parser name".
+ */
+bool
+TSParserIsVisible(Oid prsId)
+{
+ HeapTuple tup;
+ Form_pg_ts_parser form;
+ Oid namespace;
+ bool visible;
+
+ tup = SearchSysCache(TSPARSEROID,
+ ObjectIdGetDatum(prsId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search parser %u", prsId);
+ form = (Form_pg_ts_parser) GETSTRUCT(tup);
+
+ recomputeNamespacePath();
+
+ /*
+ * Quick check: if it ain't in the path at all, it ain't visible. Items in
+ * the system namespace are surely in the path and so we needn't even do
+ * list_member_oid() for them.
+ */
+ namespace = form->prsnamespace;
+ if (namespace != PG_CATALOG_NAMESPACE &&
+ !list_member_oid(activeSearchPath, namespace))
+ visible = false;
+ else
+ {
+ /*
+ * If it is in the path, it might still not be visible; it could be
+ * hidden by another parser of the same name earlier in the path. So we
+ * must do a slow check for conflicting parsers.
+ */
+ char *name = NameStr(form->prsname);
+ ListCell *l;
+
+ visible = false;
+ foreach(l, activeSearchPath)
+ {
+ Oid namespaceId = lfirst_oid(l);
+
+ if (namespaceId == myTempNamespace)
+ continue; /* do not look in temp namespace */
+
+ if (namespaceId == namespace)
+ {
+ /* Found it first in path */
+ visible = true;
+ break;
+ }
+ if (SearchSysCacheExists(TSPARSERNAMENSP,
+ PointerGetDatum(name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0))
+ {
+ /* Found something else first in path */
+ break;
+ }
+ }
+ }
+
+ ReleaseSysCache(tup);
+
+ return visible;
+}
+
+/*
+ * TSDictionaryGetDictid - find a TS dictionary by possibly qualified name
+ *
+ * If not found, returns InvalidOid if failOK, else throws error
+ */
+Oid
+TSDictionaryGetDictid(List *names, bool failOK)
+{
+ char *schemaname;
+ char *dict_name;
+ Oid namespaceId;
+ Oid dictoid = InvalidOid;
+ ListCell *l;
+
+ /* deconstruct the name list */
+ DeconstructQualifiedName(names, &schemaname, &dict_name);
+
+ if (schemaname)
+ {
+ /* use exact schema given */
+ namespaceId = LookupExplicitNamespace(schemaname);
+ dictoid = GetSysCacheOid(TSDICTNAMENSP,
+ PointerGetDatum(dict_name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0);
+ }
+ else
+ {
+ /* search for it in search path */
+ recomputeNamespacePath();
+
+ foreach(l, activeSearchPath)
+ {
+ namespaceId = lfirst_oid(l);
+
+ if (namespaceId == myTempNamespace)
+ continue; /* do not look in temp namespace */
+
+ dictoid = GetSysCacheOid(TSDICTNAMENSP,
+ PointerGetDatum(dict_name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0);
+ if (OidIsValid(dictoid))
+ break;
+ }
+ }
+
+ if (!OidIsValid(dictoid) && !failOK)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search dictionary \"%s\" does not exist",
+ NameListToString(names))));
+
+ return dictoid;
+}
+
+/*
+ * TSDictionaryIsVisible
+ * Determine whether a dictionary (identified by OID) is visible in the
+ * current search path. Visible means "would be found by searching
+ * for the unqualified dictionary name".
+ */
+bool
+TSDictionaryIsVisible(Oid dictId)
+{
+ HeapTuple tup;
+ Form_pg_ts_dict form;
+ Oid namespace;
+ bool visible;
+
+ tup = SearchSysCache(TSDICTOID,
+ ObjectIdGetDatum(dictId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ dictId);
+ form = (Form_pg_ts_dict) GETSTRUCT(tup);
+
+ recomputeNamespacePath();
+
+ /*
+ * Quick check: if it ain't in the path at all, it ain't visible. Items in
+ * the system namespace are surely in the path and so we needn't even do
+ * list_member_oid() for them.
+ */
+ namespace = form->dictnamespace;
+ if (namespace != PG_CATALOG_NAMESPACE &&
+ !list_member_oid(activeSearchPath, namespace))
+ visible = false;
+ else
+ {
+ /*
+ * If it is in the path, it might still not be visible; it could be
+ * hidden by another dictionary of the same name earlier in the
+ * path. So we must do a slow check for conflicting dictionaries.
+ */
+ char *name = NameStr(form->dictname);
+ ListCell *l;
+
+ visible = false;
+ foreach(l, activeSearchPath)
+ {
+ Oid namespaceId = lfirst_oid(l);
+
+ if (namespaceId == myTempNamespace)
+ continue; /* do not look in temp namespace */
+
+ if (namespaceId == namespace)
+ {
+ /* Found it first in path */
+ visible = true;
+ break;
+ }
+ if (SearchSysCacheExists(TSDICTNAMENSP,
+ PointerGetDatum(name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0))
+ {
+ /* Found something else first in path */
+ break;
+ }
+ }
+ }
+
+ ReleaseSysCache(tup);
+
+ return visible;
+}
+
+/*
+ * TSTemplateGetTmplid - find a TS template by possibly qualified name
+ *
+ * If not found, returns InvalidOid if failOK, else throws error
+ */
+Oid
+TSTemplateGetTmplid(List *names, bool failOK)
+{
+ char *schemaname;
+ char *template_name;
+ Oid namespaceId;
+ Oid tmploid = InvalidOid;
+ ListCell *l;
+
+ /* deconstruct the name list */
+ DeconstructQualifiedName(names, &schemaname, &template_name);
+
+ if (schemaname)
+ {
+ /* use exact schema given */
+ namespaceId = LookupExplicitNamespace(schemaname);
+ tmploid = GetSysCacheOid(TSTEMPLATENAMENSP,
+ PointerGetDatum(template_name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0);
+ }
+ else
+ {
+ /* search for it in search path */
+ recomputeNamespacePath();
+
+ foreach(l, activeSearchPath)
+ {
+ namespaceId = lfirst_oid(l);
+
+ if (namespaceId == myTempNamespace)
+ continue; /* do not look in temp namespace */
+
+ tmploid = GetSysCacheOid(TSTEMPLATENAMENSP,
+ PointerGetDatum(template_name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0);
+ if (OidIsValid(tmploid))
+ break;
+ }
+ }
+
+ if (!OidIsValid(tmploid) && !failOK)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search template \"%s\" does not exist",
+ NameListToString(names))));
+
+ return tmploid;
+}
+
+/*
+ * TSTemplateIsVisible
+ * Determine whether a template (identified by OID) is visible in the
+ * current search path. Visible means "would be found by searching
+ * for the unqualified template name".
+ */
+bool
+TSTemplateIsVisible(Oid tmplId)
+{
+ HeapTuple tup;
+ Form_pg_ts_template form;
+ Oid namespace;
+ bool visible;
+
+ tup = SearchSysCache(TSTEMPLATEOID,
+ ObjectIdGetDatum(tmplId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search template %u", tmplId);
+ form = (Form_pg_ts_template) GETSTRUCT(tup);
+
+ recomputeNamespacePath();
+
+ /*
+ * Quick check: if it ain't in the path at all, it ain't visible. Items in
+ * the system namespace are surely in the path and so we needn't even do
+ * list_member_oid() for them.
+ */
+ namespace = form->tmplnamespace;
+ if (namespace != PG_CATALOG_NAMESPACE &&
+ !list_member_oid(activeSearchPath, namespace))
+ visible = false;
+ else
+ {
+ /*
+ * If it is in the path, it might still not be visible; it could be
+ * hidden by another template of the same name earlier in the path.
+ * So we must do a slow check for conflicting templates.
+ */
+ char *name = NameStr(form->tmplname);
+ ListCell *l;
+
+ visible = false;
+ foreach(l, activeSearchPath)
+ {
+ Oid namespaceId = lfirst_oid(l);
+
+ if (namespaceId == myTempNamespace)
+ continue; /* do not look in temp namespace */
+
+ if (namespaceId == namespace)
+ {
+ /* Found it first in path */
+ visible = true;
+ break;
+ }
+ if (SearchSysCacheExists(TSTEMPLATENAMENSP,
+ PointerGetDatum(name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0))
+ {
+ /* Found something else first in path */
+ break;
+ }
+ }
+ }
+
+ ReleaseSysCache(tup);
+
+ return visible;
+}
+
+/*
+ * TSConfigGetCfgid - find a TS config by possibly qualified name
+ *
+ * If not found, returns InvalidOid if failOK, else throws error
+ */
+Oid
+TSConfigGetCfgid(List *names, bool failOK)
+{
+ char *schemaname;
+ char *config_name;
+ Oid namespaceId;
+ Oid cfgoid = InvalidOid;
+ ListCell *l;
+
+ /* deconstruct the name list */
+ DeconstructQualifiedName(names, &schemaname, &config_name);
+
+ if (schemaname)
+ {
+ /* use exact schema given */
+ namespaceId = LookupExplicitNamespace(schemaname);
+ cfgoid = GetSysCacheOid(TSCONFIGNAMENSP,
+ PointerGetDatum(config_name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0);
+ }
+ else
+ {
+ /* search for it in search path */
+ recomputeNamespacePath();
+
+ foreach(l, activeSearchPath)
+ {
+ namespaceId = lfirst_oid(l);
+
+ if (namespaceId == myTempNamespace)
+ continue; /* do not look in temp namespace */
+
+ cfgoid = GetSysCacheOid(TSCONFIGNAMENSP,
+ PointerGetDatum(config_name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0);
+ if (OidIsValid(cfgoid))
+ break;
+ }
+ }
+
+ if (!OidIsValid(cfgoid) && !failOK)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search configuration \"%s\" does not exist",
+ NameListToString(names))));
+
+ return cfgoid;
+}
+
+/*
+ * TSConfigIsVisible
+ * Determine whether a text search configuration (identified by OID)
+ * is visible in the current search path. Visible means "would be found
+ * by searching for the unqualified text search configuration name".
+ */
+bool
+TSConfigIsVisible(Oid cfgid)
+{
+ HeapTuple tup;
+ Form_pg_ts_config form;
+ Oid namespace;
+ bool visible;
+
+ tup = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(cfgid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ cfgid);
+ form = (Form_pg_ts_config) GETSTRUCT(tup);
+
+ recomputeNamespacePath();
+
+ /*
+ * Quick check: if it ain't in the path at all, it ain't visible. Items in
+ * the system namespace are surely in the path and so we needn't even do
+ * list_member_oid() for them.
+ */
+ namespace = form->cfgnamespace;
+ if (namespace != PG_CATALOG_NAMESPACE &&
+ !list_member_oid(activeSearchPath, namespace))
+ visible = false;
+ else
+ {
+ /*
+ * If it is in the path, it might still not be visible; it could be
+ * hidden by another configuration of the same name earlier in the
+ * path. So we must do a slow check for conflicting configurations.
+ */
+ char *name = NameStr(form->cfgname);
+ ListCell *l;
+
+ visible = false;
+ foreach(l, activeSearchPath)
+ {
+ Oid namespaceId = lfirst_oid(l);
+
+ if (namespaceId == myTempNamespace)
+ continue; /* do not look in temp namespace */
+
+ if (namespaceId == namespace)
+ {
+ /* Found it first in path */
+ visible = true;
+ break;
+ }
+ if (SearchSysCacheExists(TSCONFIGNAMENSP,
+ PointerGetDatum(name),
+ ObjectIdGetDatum(namespaceId),
+ 0, 0))
+ {
+ /* Found something else first in path */
+ break;
+ }
+ }
+ }
+
+ ReleaseSysCache(tup);
+
+ return visible;
+}
+
+
+/*
* DeconstructQualifiedName
* Given a possibly-qualified name expressed as a list of String nodes,
* extract the schema name and object name.
@@ -2516,6 +3039,38 @@ pg_conversion_is_visible(PG_FUNCTION_ARGS)
}
Datum
+pg_ts_parser_is_visible(PG_FUNCTION_ARGS)
+{
+ Oid oid = PG_GETARG_OID(0);
+
+ PG_RETURN_BOOL(TSParserIsVisible(oid));
+}
+
+Datum
+pg_ts_dict_is_visible(PG_FUNCTION_ARGS)
+{
+ Oid oid = PG_GETARG_OID(0);
+
+ PG_RETURN_BOOL(TSDictionaryIsVisible(oid));
+}
+
+Datum
+pg_ts_template_is_visible(PG_FUNCTION_ARGS)
+{
+ Oid oid = PG_GETARG_OID(0);
+
+ PG_RETURN_BOOL(TSTemplateIsVisible(oid));
+}
+
+Datum
+pg_ts_config_is_visible(PG_FUNCTION_ARGS)
+{
+ Oid oid = PG_GETARG_OID(0);
+
+ PG_RETURN_BOOL(TSConfigIsVisible(oid));
+}
+
+Datum
pg_my_temp_schema(PG_FUNCTION_ARGS)
{
PG_RETURN_OID(myTempNamespace);
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index c091c855708..756809b8aef 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -3,7 +3,7 @@
*
* Copyright (c) 1996-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.39 2007/07/25 22:16:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.40 2007/08/21 01:11:13 tgl Exp $
*/
CREATE VIEW pg_roles AS
@@ -382,3 +382,74 @@ CREATE VIEW pg_stat_bgwriter AS
pg_stat_get_bgwriter_buf_written_checkpoints() AS buffers_checkpoint,
pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean,
pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean;
+
+-- Tsearch debug function. Defined here because it'd be pretty unwieldy
+-- to put it into pg_proc.h
+
+CREATE TYPE ts_debug AS (
+ "Alias" text,
+ "Description" text,
+ "Token" text,
+ "Dictionaries" regdictionary[],
+ "Lexized token" text
+);
+
+COMMENT ON TYPE ts_debug IS 'returned type from ts_debug() function';
+
+CREATE FUNCTION ts_debug(regconfig, text)
+RETURNS SETOF ts_debug AS
+$$
+SELECT
+ (
+ SELECT
+ tt.alias
+ FROM
+ pg_catalog.ts_token_type(
+ (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 )
+ ) AS tt
+ WHERE
+ tt.tokid = parse.tokid
+ ) AS "Alias",
+ (
+ SELECT
+ tt.description
+ FROM
+ pg_catalog.ts_token_type(
+ (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 )
+ ) AS tt
+ WHERE
+ tt.tokid = parse.tokid
+ ) AS "Description",
+ parse.token AS "Token",
+ ARRAY ( SELECT m.mapdict::pg_catalog.regdictionary
+ FROM pg_catalog.pg_ts_config_map AS m
+ WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid
+ ORDER BY m.mapcfg, m.maptokentype, m.mapseqno )
+ AS "Dictionaries",
+ (
+ SELECT
+ dl.mapdict::pg_catalog.regdictionary || ': ' || dl.lex::pg_catalog.text
+ FROM
+ ( SELECT mapdict, pg_catalog.ts_lexize(mapdict, parse.token) AS lex
+ FROM pg_catalog.pg_ts_config_map AS m
+ WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid
+ ORDER BY m.mapcfg, m.maptokentype, m.mapseqno ) dl
+ WHERE dl.lex IS NOT NULL
+ LIMIT 1
+ ) AS "Lexized token"
+FROM pg_catalog.ts_parse(
+ (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ), $2
+ ) AS parse;
+$$
+LANGUAGE SQL RETURNS NULL ON NULL INPUT;
+
+COMMENT ON FUNCTION ts_debug(regconfig,text) IS 'debug function for text search configuration';
+
+CREATE FUNCTION ts_debug(text)
+RETURNS SETOF ts_debug AS
+$$
+ SELECT * FROM pg_catalog.ts_debug( pg_catalog.get_current_ts_config(), $1 );
+$$
+LANGUAGE SQL RETURNS NULL ON NULL INPUT;
+
+COMMENT ON FUNCTION ts_debug(text) IS 'debug function for current text search configuration';
diff --git a/src/backend/commands/Makefile b/src/backend/commands/Makefile
index 4b25ae6489e..e47b8f91fac 100644
--- a/src/backend/commands/Makefile
+++ b/src/backend/commands/Makefile
@@ -4,7 +4,7 @@
# Makefile for backend/commands
#
# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/commands/Makefile,v 1.36 2007/04/26 16:13:09 neilc Exp $
+# $PostgreSQL: pgsql/src/backend/commands/Makefile,v 1.37 2007/08/21 01:11:14 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -18,7 +18,8 @@ OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o \
indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
portalcmds.o prepare.o proclang.o \
schemacmds.o sequence.o tablecmds.o tablespace.o trigger.o \
- typecmds.o user.o vacuum.o vacuumlazy.o variable.o view.o
+ tsearchcmds.o typecmds.o user.o vacuum.o vacuumlazy.o \
+ variable.o view.o
all: SUBSYS.o
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 7cd347b69f9..65c2bbdb0f2 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.24 2007/07/03 01:30:36 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.25 2007/08/21 01:11:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -138,6 +138,22 @@ ExecRenameStmt(RenameStmt *stmt)
break;
}
+ case OBJECT_TSPARSER:
+ RenameTSParser(stmt->object, stmt->newname);
+ break;
+
+ case OBJECT_TSDICTIONARY:
+ RenameTSDictionary(stmt->object, stmt->newname);
+ break;
+
+ case OBJECT_TSTEMPLATE:
+ RenameTSTemplate(stmt->object, stmt->newname);
+ break;
+
+ case OBJECT_TSCONFIGURATION:
+ RenameTSConfiguration(stmt->object, stmt->newname);
+ break;
+
default:
elog(ERROR, "unrecognized rename stmt type: %d",
(int) stmt->renameType);
@@ -240,6 +256,14 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
AlterTypeOwner(stmt->object, newowner);
break;
+ case OBJECT_TSDICTIONARY:
+ AlterTSDictionaryOwner(stmt->object, newowner);
+ break;
+
+ case OBJECT_TSCONFIGURATION:
+ AlterTSConfigurationOwner(stmt->object, newowner);
+ break;
+
default:
elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
(int) stmt->objectType);
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 344099ebdf6..89158251aa4 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -7,7 +7,7 @@
* Copyright (c) 1996-2007, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.96 2007/02/01 19:10:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.97 2007/08/21 01:11:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,6 +34,10 @@
#include "catalog/pg_shdescription.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_trigger.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
@@ -78,6 +82,10 @@ static void CommentLargeObject(List *qualname, char *comment);
static void CommentCast(List *qualname, List *arguments, char *comment);
static void CommentTablespace(List *qualname, char *comment);
static void CommentRole(List *qualname, char *comment);
+static void CommentTSParser(List *qualname, char *comment);
+static void CommentTSDictionary(List *qualname, char *comment);
+static void CommentTSTemplate(List *qualname, char *comment);
+static void CommentTSConfiguration(List *qualname, char *comment);
/*
@@ -151,6 +159,18 @@ CommentObject(CommentStmt *stmt)
case OBJECT_ROLE:
CommentRole(stmt->objname, stmt->comment);
break;
+ case OBJECT_TSPARSER:
+ CommentTSParser(stmt->objname, stmt->comment);
+ break;
+ case OBJECT_TSDICTIONARY:
+ CommentTSDictionary(stmt->objname, stmt->comment);
+ break;
+ case OBJECT_TSTEMPLATE:
+ CommentTSTemplate(stmt->objname, stmt->comment);
+ break;
+ case OBJECT_TSCONFIGURATION:
+ CommentTSConfiguration(stmt->objname, stmt->comment);
+ break;
default:
elog(ERROR, "unrecognized object type: %d",
(int) stmt->objtype);
@@ -1462,3 +1482,61 @@ CommentCast(List *qualname, List *arguments, char *comment)
/* Call CreateComments() to create/drop the comments */
CreateComments(castOid, CastRelationId, 0, comment);
}
+
+static void
+CommentTSParser(List *qualname, char *comment)
+{
+ Oid prsId;
+
+ prsId = TSParserGetPrsid(qualname, false);
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to comment on text search parser")));
+
+ CreateComments(prsId, TSParserRelationId, 0, comment);
+}
+
+static void
+CommentTSDictionary(List *qualname, char *comment)
+{
+ Oid dictId;
+
+ dictId = TSDictionaryGetDictid(qualname, false);
+
+ if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
+ NameListToString(qualname));
+
+ CreateComments(dictId, TSDictionaryRelationId, 0, comment);
+}
+
+static void
+CommentTSTemplate(List *qualname, char *comment)
+{
+ Oid tmplId;
+
+ tmplId = TSTemplateGetTmplid(qualname, false);
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to comment on text search template")));
+
+ CreateComments(tmplId, TSTemplateRelationId, 0, comment);
+}
+
+static void
+CommentTSConfiguration(List *qualname, char *comment)
+{
+ Oid cfgId;
+
+ cfgId = TSConfigGetCfgid(qualname, false);
+
+ if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
+ NameListToString(qualname));
+
+ CreateComments(cfgId, TSConfigRelationId, 0, comment);
+}
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 07e56620428..006076b01f4 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.230 2007/07/17 05:02:00 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.231 2007/08/21 01:11:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -5079,8 +5079,13 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
case OCLASS_LANGUAGE:
case OCLASS_OPERATOR:
case OCLASS_OPCLASS:
+ case OCLASS_OPFAMILY:
case OCLASS_TRIGGER:
case OCLASS_SCHEMA:
+ case OCLASS_TSPARSER:
+ case OCLASS_TSDICT:
+ case OCLASS_TSTEMPLATE:
+ case OCLASS_TSCONFIG:
/*
* We don't expect any of these sorts of objects to depend on
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
new file mode 100644
index 00000000000..7092da132d8
--- /dev/null
+++ b/src/backend/commands/tsearchcmds.c
@@ -0,0 +1,1948 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsearchcmds.c
+ *
+ * Routines for tsearch manipulation commands
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/commands/tsearchcmds.c,v 1.1 2007/08/21 01:11:15 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+#include "miscadmin.h"
+
+#include "access/heapam.h"
+#include "access/genam.h"
+#include "access/xact.h"
+#include "catalog/dependency.h"
+#include "catalog/indexing.h"
+#include "catalog/namespace.h"
+#include "catalog/pg_namespace.h"
+#include "catalog/pg_proc.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_config_map.h"
+#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_ts_template.h"
+#include "catalog/pg_type.h"
+#include "commands/defrem.h"
+#include "parser/parse_func.h"
+#include "tsearch/ts_cache.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/acl.h"
+#include "utils/builtins.h"
+#include "utils/catcache.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
+#include "utils/syscache.h"
+
+
+static HeapTuple UpdateTSConfiguration(AlterTSConfigurationStmt *stmt,
+ HeapTuple tup);
+static void MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
+ HeapTuple tup);
+static void DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
+ HeapTuple tup);
+
+
+/* --------------------- TS Parser commands ------------------------ */
+
+/*
+ * lookup a parser support function and return its OID (as a Datum)
+ *
+ * attnum is the pg_ts_parser column the function will go into
+ */
+static Datum
+get_ts_parser_func(DefElem *defel, int attnum)
+{
+ List *funcName = defGetQualifiedName(defel);
+ Oid typeId[3];
+ Oid retTypeId;
+ int nargs;
+ Oid procOid;
+
+ retTypeId = INTERNALOID; /* correct for most */
+ typeId[0] = INTERNALOID;
+ switch (attnum)
+ {
+ case Anum_pg_ts_parser_prsstart:
+ nargs = 2;
+ typeId[1] = INT4OID;
+ break;
+ case Anum_pg_ts_parser_prstoken:
+ nargs = 3;
+ typeId[1] = INTERNALOID;
+ typeId[2] = INTERNALOID;
+ break;
+ case Anum_pg_ts_parser_prsend:
+ nargs = 1;
+ retTypeId = VOIDOID;
+ break;
+ case Anum_pg_ts_parser_prsheadline:
+ nargs = 3;
+ typeId[1] = TEXTOID;
+ typeId[2] = TSQUERYOID;
+ break;
+ case Anum_pg_ts_parser_prslextype:
+ nargs = 1;
+ break;
+ default:
+ /* should not be here */
+ elog(ERROR, "unknown attribute for text search parser: %d", attnum);
+ nargs = 0; /* keep compiler quiet */
+ }
+
+ procOid = LookupFuncName(funcName, nargs, typeId, false);
+ if (get_func_rettype(procOid) != retTypeId)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("function %s should return type %s",
+ func_signature_string(funcName, nargs, typeId),
+ format_type_be(retTypeId))));
+
+ return ObjectIdGetDatum(procOid);
+}
+
+/*
+ * make pg_depend entries for a new pg_ts_parser entry
+ */
+static void
+makeParserDependencies(HeapTuple tuple)
+{
+ Form_pg_ts_parser prs = (Form_pg_ts_parser) GETSTRUCT(tuple);
+ ObjectAddress myself,
+ referenced;
+
+ myself.classId = TSParserRelationId;
+ myself.objectId = HeapTupleGetOid(tuple);
+ myself.objectSubId = 0;
+
+ /* dependency on namespace */
+ referenced.classId = NamespaceRelationId;
+ referenced.objectId = prs->prsnamespace;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ /* dependencies on functions */
+ referenced.classId = ProcedureRelationId;
+ referenced.objectSubId = 0;
+
+ referenced.objectId = prs->prsstart;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ referenced.objectId = prs->prstoken;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ referenced.objectId = prs->prsend;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ referenced.objectId = prs->prslextype;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ if (OidIsValid(prs->prsheadline))
+ {
+ referenced.objectId = prs->prsheadline;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+ }
+}
+
+/*
+ * CREATE TEXT SEARCH PARSER
+ */
+void
+DefineTSParser(List *names, List *parameters)
+{
+ char *prsname;
+ ListCell *pl;
+ Relation prsRel;
+ HeapTuple tup;
+ Datum values[Natts_pg_ts_parser];
+ char nulls[Natts_pg_ts_parser];
+ NameData pname;
+ Oid prsOid;
+ Oid namespaceoid;
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to create text search parsers")));
+
+ /* Convert list of names to a name and namespace */
+ namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname);
+
+ /* initialize tuple fields with name/namespace */
+ memset(values, 0, sizeof(values));
+ memset(nulls, ' ', sizeof(nulls));
+
+ namestrcpy(&pname, prsname);
+ values[Anum_pg_ts_parser_prsname - 1] = NameGetDatum(&pname);
+ values[Anum_pg_ts_parser_prsnamespace - 1] = ObjectIdGetDatum(namespaceoid);
+
+ /*
+ * loop over the definition list and extract the information we need.
+ */
+ foreach(pl, parameters)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ if (pg_strcasecmp(defel->defname, "start") == 0)
+ {
+ values[Anum_pg_ts_parser_prsstart - 1] =
+ get_ts_parser_func(defel, Anum_pg_ts_parser_prsstart);
+ }
+ else if (pg_strcasecmp(defel->defname, "gettoken") == 0)
+ {
+ values[Anum_pg_ts_parser_prstoken - 1] =
+ get_ts_parser_func(defel, Anum_pg_ts_parser_prstoken);
+ }
+ else if (pg_strcasecmp(defel->defname, "end") == 0)
+ {
+ values[Anum_pg_ts_parser_prsend - 1] =
+ get_ts_parser_func(defel, Anum_pg_ts_parser_prsend);
+ }
+ else if (pg_strcasecmp(defel->defname, "headline") == 0)
+ {
+ values[Anum_pg_ts_parser_prsheadline - 1] =
+ get_ts_parser_func(defel, Anum_pg_ts_parser_prsheadline);
+ }
+ else if (pg_strcasecmp(defel->defname, "lextypes") == 0)
+ {
+ values[Anum_pg_ts_parser_prslextype - 1] =
+ get_ts_parser_func(defel, Anum_pg_ts_parser_prslextype);
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("text search parser parameter \"%s\" not recognized",
+ defel->defname)));
+ }
+
+ /*
+ * Validation
+ */
+ if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_parser_prsstart - 1])))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("text search parser start method is required")));
+
+ if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_parser_prstoken - 1])))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("text search parser gettoken method is required")));
+
+ if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_parser_prsend - 1])))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("text search parser end method is required")));
+
+ if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_parser_prslextype - 1])))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("text search parser lextypes method is required")));
+
+ /*
+ * Looks good, insert
+ */
+ prsRel = heap_open(TSParserRelationId, RowExclusiveLock);
+
+ tup = heap_formtuple(prsRel->rd_att, values, nulls);
+
+ prsOid = simple_heap_insert(prsRel, tup);
+
+ CatalogUpdateIndexes(prsRel, tup);
+
+ makeParserDependencies(tup);
+
+ heap_freetuple(tup);
+
+ heap_close(prsRel, RowExclusiveLock);
+}
+
+/*
+ * DROP TEXT SEARCH PARSER
+ */
+void
+RemoveTSParser(List *names, DropBehavior behavior, bool missing_ok)
+{
+ Oid prsOid;
+ ObjectAddress object;
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to drop text search parsers")));
+
+ prsOid = TSParserGetPrsid(names, true);
+ if (!OidIsValid(prsOid))
+ {
+ if (!missing_ok)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search parser \"%s\" does not exist",
+ NameListToString(names))));
+ }
+ else
+ {
+ ereport(NOTICE,
+ (errmsg("text search parser \"%s\" does not exist, skipping",
+ NameListToString(names))));
+ }
+ return;
+ }
+
+ object.classId = TSParserRelationId;
+ object.objectId = prsOid;
+ object.objectSubId = 0;
+
+ performDeletion(&object, behavior);
+}
+
+/*
+ * Guts of TS parser deletion.
+ */
+void
+RemoveTSParserById(Oid prsId)
+{
+ Relation relation;
+ HeapTuple tup;
+
+ relation = heap_open(TSParserRelationId, RowExclusiveLock);
+
+ tup = SearchSysCache(TSPARSEROID,
+ ObjectIdGetDatum(prsId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search parser %u", prsId);
+
+ simple_heap_delete(relation, &tup->t_self);
+
+ ReleaseSysCache(tup);
+
+ heap_close(relation, RowExclusiveLock);
+}
+
+/*
+ * ALTER TEXT SEARCH PARSER RENAME
+ */
+void
+RenameTSParser(List *oldname, const char *newname)
+{
+ HeapTuple tup;
+ Relation rel;
+ Oid prsId;
+ Oid namespaceOid;
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to rename text search parsers")));
+
+ rel = heap_open(TSParserRelationId, RowExclusiveLock);
+
+ prsId = TSParserGetPrsid(oldname, false);
+
+ tup = SearchSysCacheCopy(TSPARSEROID,
+ ObjectIdGetDatum(prsId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for text search parser %u", prsId);
+
+ namespaceOid = ((Form_pg_ts_parser) GETSTRUCT(tup))->prsnamespace;
+
+ if (SearchSysCacheExists(TSPARSERNAMENSP,
+ PointerGetDatum(newname),
+ ObjectIdGetDatum(namespaceOid),
+ 0, 0))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("text search parser \"%s\" already exists",
+ newname)));
+
+ namestrcpy(&(((Form_pg_ts_parser) GETSTRUCT(tup))->prsname), newname);
+ simple_heap_update(rel, &tup->t_self, tup);
+ CatalogUpdateIndexes(rel, tup);
+
+ heap_close(rel, NoLock);
+ heap_freetuple(tup);
+}
+
+/* ---------------------- TS Dictionary commands -----------------------*/
+
+/*
+ * make pg_depend entries for a new pg_ts_dict entry
+ */
+static void
+makeDictionaryDependencies(HeapTuple tuple)
+{
+ Form_pg_ts_dict dict = (Form_pg_ts_dict) GETSTRUCT(tuple);
+ ObjectAddress myself,
+ referenced;
+
+ myself.classId = TSDictionaryRelationId;
+ myself.objectId = HeapTupleGetOid(tuple);
+ myself.objectSubId = 0;
+
+ /* dependency on namespace */
+ referenced.classId = NamespaceRelationId;
+ referenced.objectId = dict->dictnamespace;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ /* dependency on owner */
+ recordDependencyOnOwner(myself.classId, myself.objectId, dict->dictowner);
+
+ /* dependency on template */
+ referenced.classId = TSTemplateRelationId;
+ referenced.objectId = dict->dicttemplate;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+}
+
+/*
+ * CREATE TEXT SEARCH DICTIONARY
+ */
+void
+DefineTSDictionary(List *names, List *parameters)
+{
+ ListCell *pl;
+ Relation dictRel;
+ HeapTuple tup;
+ Datum values[Natts_pg_ts_dict];
+ char nulls[Natts_pg_ts_dict];
+ NameData dname;
+ int i;
+ Oid dictOid;
+ Oid namespaceoid;
+ AclResult aclresult;
+ char *dictname;
+
+ /* Convert list of names to a name and namespace */
+ namespaceoid = QualifiedNameGetCreationNamespace(names, &dictname);
+
+ /* Check we have creation rights in target namespace */
+ aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceoid));
+
+ for (i = 0; i < Natts_pg_ts_dict; i++)
+ {
+ nulls[i] = ' ';
+ values[i] = ObjectIdGetDatum(InvalidOid);
+ }
+
+ namestrcpy(&dname, dictname);
+ values[Anum_pg_ts_dict_dictname - 1] = NameGetDatum(&dname);
+ values[Anum_pg_ts_dict_dictnamespace - 1] = ObjectIdGetDatum(namespaceoid);
+ values[Anum_pg_ts_dict_dictowner - 1] = ObjectIdGetDatum(GetUserId());
+ nulls[Anum_pg_ts_dict_dictinitoption - 1] = 'n';
+
+ /*
+ * loop over the definition list and extract the information we need.
+ */
+ foreach(pl, parameters)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ if (pg_strcasecmp(defel->defname, "template") == 0)
+ {
+ Oid templId;
+
+ templId = TSTemplateGetTmplid(defGetQualifiedName(defel), false);
+
+ values[Anum_pg_ts_dict_dicttemplate - 1] = ObjectIdGetDatum(templId);
+ nulls[Anum_pg_ts_dict_dicttemplate - 1] = ' ';
+ }
+ else if (pg_strcasecmp(defel->defname, "option") == 0)
+ {
+ char *opt = defGetString(defel);
+
+ if (pg_strcasecmp(opt, "null") != 0)
+ {
+ values[Anum_pg_ts_dict_dictinitoption - 1] =
+ DirectFunctionCall1(textin, CStringGetDatum(opt));
+ nulls[Anum_pg_ts_dict_dictinitoption - 1] = ' ';
+ }
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("text search dictionary parameter \"%s\" not recognized",
+ defel->defname)));
+ }
+
+ /*
+ * Validation
+ */
+ if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_dict_dicttemplate - 1])))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("text search template is required")));
+
+ /*
+ * Looks good, insert
+ */
+
+ dictRel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+
+ tup = heap_formtuple(dictRel->rd_att, values, nulls);
+
+ dictOid = simple_heap_insert(dictRel, tup);
+
+ CatalogUpdateIndexes(dictRel, tup);
+
+ makeDictionaryDependencies(tup);
+
+ heap_freetuple(tup);
+
+ heap_close(dictRel, RowExclusiveLock);
+}
+
+/*
+ * ALTER TEXT SEARCH DICTIONARY RENAME
+ */
+void
+RenameTSDictionary(List *oldname, const char *newname)
+{
+ HeapTuple tup;
+ Relation rel;
+ Oid dictId;
+ Oid namespaceOid;
+ AclResult aclresult;
+
+ rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+
+ dictId = TSDictionaryGetDictid(oldname, false);
+
+ tup = SearchSysCacheCopy(TSDICTOID,
+ ObjectIdGetDatum(dictId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ dictId);
+
+ namespaceOid = ((Form_pg_ts_dict) GETSTRUCT(tup))->dictnamespace;
+
+ if (SearchSysCacheExists(TSDICTNAMENSP,
+ PointerGetDatum(newname),
+ ObjectIdGetDatum(namespaceOid),
+ 0, 0))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("text search dictionary \"%s\" already exists",
+ newname)));
+
+ /* must be owner */
+ if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
+ NameListToString(oldname));
+
+ /* must have CREATE privilege on namespace */
+ aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceOid));
+
+ namestrcpy(&(((Form_pg_ts_dict) GETSTRUCT(tup))->dictname), newname);
+ simple_heap_update(rel, &tup->t_self, tup);
+ CatalogUpdateIndexes(rel, tup);
+
+ heap_close(rel, NoLock);
+ heap_freetuple(tup);
+}
+
+/*
+ * DROP TEXT SEARCH DICTIONARY
+ */
+void
+RemoveTSDictionary(List *names, DropBehavior behavior, bool missing_ok)
+{
+ Oid dictOid;
+ ObjectAddress object;
+ HeapTuple tup;
+ Oid namespaceId;
+
+ dictOid = TSDictionaryGetDictid(names, true);
+ if (!OidIsValid(dictOid))
+ {
+ if (!missing_ok)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search dictionary \"%s\" does not exist",
+ NameListToString(names))));
+ }
+ else
+ {
+ ereport(NOTICE,
+ (errmsg("text search dictionary \"%s\" does not exist, skipping",
+ NameListToString(names))));
+ }
+ return;
+ }
+
+ tup = SearchSysCache(TSDICTOID,
+ ObjectIdGetDatum(dictOid),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ dictOid);
+
+ /* Permission check: must own dictionary or its namespace */
+ namespaceId = ((Form_pg_ts_dict) GETSTRUCT(tup))->dictnamespace;
+ if (!pg_ts_dict_ownercheck(dictOid, GetUserId()) &&
+ !pg_namespace_ownercheck(namespaceId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
+ NameListToString(names));
+
+ ReleaseSysCache(tup);
+
+ object.classId = TSDictionaryRelationId;
+ object.objectId = dictOid;
+ object.objectSubId = 0;
+
+ performDeletion(&object, behavior);
+}
+
+/*
+ * Guts of TS dictionary deletion.
+ */
+void
+RemoveTSDictionaryById(Oid dictId)
+{
+ Relation relation;
+ HeapTuple tup;
+
+ relation = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+
+ tup = SearchSysCache(TSDICTOID,
+ ObjectIdGetDatum(dictId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ dictId);
+
+ simple_heap_delete(relation, &tup->t_self);
+
+ ReleaseSysCache(tup);
+
+ heap_close(relation, RowExclusiveLock);
+}
+
+/*
+ * ALTER TEXT SEARCH DICTIONARY
+ */
+void
+AlterTSDictionary(AlterTSDictionaryStmt * stmt)
+{
+ HeapTuple tup,
+ newtup;
+ Relation rel;
+ Oid dictId;
+ ListCell *pl;
+ Datum repl_val[Natts_pg_ts_dict];
+ char repl_null[Natts_pg_ts_dict];
+ char repl_repl[Natts_pg_ts_dict];
+
+ dictId = TSDictionaryGetDictid(stmt->dictname, false);
+
+ rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+
+ tup = SearchSysCache(TSDICTOID,
+ ObjectIdGetDatum(dictId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ dictId);
+
+ /* must be owner */
+ if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
+ NameListToString(stmt->dictname));
+
+ memset(repl_val, 0, sizeof(repl_val));
+ memset(repl_null, ' ', sizeof(repl_null));
+ memset(repl_repl, ' ', sizeof(repl_repl));
+
+ /*
+ * NOTE: because we only support altering the option, not the template,
+ * there is no need to update dependencies.
+ */
+ foreach(pl, stmt->options)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ if (pg_strcasecmp(defel->defname, "option") == 0)
+ {
+ char *opt = defGetString(defel);
+
+ if (pg_strcasecmp(opt, "null") == 0)
+ {
+ repl_null[Anum_pg_ts_dict_dictinitoption - 1] = 'n';
+ }
+ else
+ {
+ repl_val[Anum_pg_ts_dict_dictinitoption - 1] =
+ DirectFunctionCall1(textin, CStringGetDatum(opt));
+ repl_null[Anum_pg_ts_dict_dictinitoption - 1] = ' ';
+ }
+ repl_repl[Anum_pg_ts_dict_dictinitoption - 1] = 'r';
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("text search dictionary parameter \"%s\" not recognized",
+ defel->defname)));
+ }
+
+ newtup = heap_modifytuple(tup, RelationGetDescr(rel),
+ repl_val, repl_null, repl_repl);
+
+ simple_heap_update(rel, &newtup->t_self, newtup);
+
+ CatalogUpdateIndexes(rel, newtup);
+
+ heap_freetuple(newtup);
+ ReleaseSysCache(tup);
+
+ heap_close(rel, RowExclusiveLock);
+}
+
+/*
+ * ALTER TEXT SEARCH DICTIONARY OWNER
+ */
+void
+AlterTSDictionaryOwner(List *name, Oid newOwnerId)
+{
+ HeapTuple tup;
+ Relation rel;
+ Oid dictId;
+ Oid namespaceOid;
+ AclResult aclresult;
+ Form_pg_ts_dict form;
+
+ rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+
+ dictId = TSDictionaryGetDictid(name, false);
+
+ tup = SearchSysCacheCopy(TSDICTOID,
+ ObjectIdGetDatum(dictId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ dictId);
+
+ form = (Form_pg_ts_dict) GETSTRUCT(tup);
+ namespaceOid = form->dictnamespace;
+
+ if (form->dictowner != newOwnerId)
+ {
+ /* Superusers can always do it */
+ if (!superuser())
+ {
+ /* must be owner */
+ if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY,
+ NameListToString(name));
+
+ /* Must be able to become new owner */
+ check_is_member_of_role(GetUserId(), newOwnerId);
+
+ /* New owner must have CREATE privilege on namespace */
+ aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceOid));
+ }
+
+ form->dictowner = newOwnerId;
+
+ simple_heap_update(rel, &tup->t_self, tup);
+ CatalogUpdateIndexes(rel, tup);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(TSDictionaryRelationId, HeapTupleGetOid(tup),
+ newOwnerId);
+ }
+
+ heap_close(rel, NoLock);
+ heap_freetuple(tup);
+}
+
+/* ---------------------- TS Template commands -----------------------*/
+
+/*
+ * lookup a template support function and return its OID (as a Datum)
+ *
+ * attnum is the pg_ts_template column the function will go into
+ */
+static Datum
+get_ts_template_func(DefElem *defel, int attnum)
+{
+ List *funcName = defGetQualifiedName(defel);
+ Oid typeId[4];
+ Oid retTypeId;
+ int nargs;
+ Oid procOid;
+
+ retTypeId = INTERNALOID;
+ typeId[0] = INTERNALOID;
+ typeId[1] = INTERNALOID;
+ typeId[2] = INTERNALOID;
+ typeId[3] = INTERNALOID;
+ switch (attnum)
+ {
+ case Anum_pg_ts_template_tmplinit:
+ nargs = 1;
+ break;
+ case Anum_pg_ts_template_tmpllexize:
+ nargs = 4;
+ break;
+ default:
+ /* should not be here */
+ elog(ERROR, "unknown attribute for text search template: %d",
+ attnum);
+ nargs = 0; /* keep compiler quiet */
+ }
+
+ procOid = LookupFuncName(funcName, nargs, typeId, false);
+ if (get_func_rettype(procOid) != retTypeId)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("function %s should return type %s",
+ func_signature_string(funcName, nargs, typeId),
+ format_type_be(retTypeId))));
+
+ return ObjectIdGetDatum(procOid);
+}
+
+/*
+ * make pg_depend entries for a new pg_ts_template entry
+ */
+static void
+makeTSTemplateDependencies(HeapTuple tuple)
+{
+ Form_pg_ts_template tmpl = (Form_pg_ts_template) GETSTRUCT(tuple);
+ ObjectAddress myself,
+ referenced;
+
+ myself.classId = TSTemplateRelationId;
+ myself.objectId = HeapTupleGetOid(tuple);
+ myself.objectSubId = 0;
+
+ /* dependency on namespace */
+ referenced.classId = NamespaceRelationId;
+ referenced.objectId = tmpl->tmplnamespace;
+ referenced.objectSubId = 0;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ /* dependencies on functions */
+ referenced.classId = ProcedureRelationId;
+ referenced.objectSubId = 0;
+
+ referenced.objectId = tmpl->tmpllexize;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+
+ if (OidIsValid(tmpl->tmplinit))
+ {
+ referenced.objectId = tmpl->tmplinit;
+ recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
+ }
+}
+
+/*
+ * CREATE TEXT SEARCH TEMPLATE
+ */
+void
+DefineTSTemplate(List *names, List *parameters)
+{
+ ListCell *pl;
+ Relation tmplRel;
+ HeapTuple tup;
+ Datum values[Natts_pg_ts_template];
+ char nulls[Natts_pg_ts_template];
+ NameData dname;
+ int i;
+ Oid dictOid;
+ Oid namespaceoid;
+ char *tmplname;
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to create text search templates")));
+
+ /* Convert list of names to a name and namespace */
+ namespaceoid = QualifiedNameGetCreationNamespace(names, &tmplname);
+
+ for (i = 0; i < Natts_pg_ts_template; i++)
+ {
+ nulls[i] = ' ';
+ values[i] = ObjectIdGetDatum(InvalidOid);
+ }
+
+ namestrcpy(&dname, tmplname);
+ values[Anum_pg_ts_template_tmplname - 1] = NameGetDatum(&dname);
+ values[Anum_pg_ts_template_tmplnamespace - 1] = ObjectIdGetDatum(namespaceoid);
+
+ /*
+ * loop over the definition list and extract the information we need.
+ */
+ foreach(pl, parameters)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ if (pg_strcasecmp(defel->defname, "init") == 0)
+ {
+ values[Anum_pg_ts_template_tmplinit - 1] =
+ get_ts_template_func(defel, Anum_pg_ts_template_tmplinit);
+ nulls[Anum_pg_ts_template_tmplinit - 1] = ' ';
+ }
+ else if (pg_strcasecmp(defel->defname, "lexize") == 0)
+ {
+ values[Anum_pg_ts_template_tmpllexize - 1] =
+ get_ts_template_func(defel, Anum_pg_ts_template_tmpllexize);
+ nulls[Anum_pg_ts_template_tmpllexize - 1] = ' ';
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("text search template parameter \"%s\" not recognized",
+ defel->defname)));
+ }
+
+ /*
+ * Validation
+ */
+ if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_template_tmpllexize - 1])))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("text search template lexize method is required")));
+
+ /*
+ * Looks good, insert
+ */
+
+ tmplRel = heap_open(TSTemplateRelationId, RowExclusiveLock);
+
+ tup = heap_formtuple(tmplRel->rd_att, values, nulls);
+
+ dictOid = simple_heap_insert(tmplRel, tup);
+
+ CatalogUpdateIndexes(tmplRel, tup);
+
+ makeTSTemplateDependencies(tup);
+
+ heap_freetuple(tup);
+
+ heap_close(tmplRel, RowExclusiveLock);
+}
+
+/*
+ * ALTER TEXT SEARCH TEMPLATE RENAME
+ */
+void
+RenameTSTemplate(List *oldname, const char *newname)
+{
+ HeapTuple tup;
+ Relation rel;
+ Oid tmplId;
+ Oid namespaceOid;
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to rename text search templates")));
+
+ rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
+
+ tmplId = TSTemplateGetTmplid(oldname, false);
+
+ tup = SearchSysCacheCopy(TSTEMPLATEOID,
+ ObjectIdGetDatum(tmplId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for text search template %u",
+ tmplId);
+
+ namespaceOid = ((Form_pg_ts_template) GETSTRUCT(tup))->tmplnamespace;
+
+ if (SearchSysCacheExists(TSTEMPLATENAMENSP,
+ PointerGetDatum(newname),
+ ObjectIdGetDatum(namespaceOid),
+ 0, 0))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("text search template \"%s\" already exists",
+ newname)));
+
+ namestrcpy(&(((Form_pg_ts_template) GETSTRUCT(tup))->tmplname), newname);
+ simple_heap_update(rel, &tup->t_self, tup);
+ CatalogUpdateIndexes(rel, tup);
+
+ heap_close(rel, NoLock);
+ heap_freetuple(tup);
+}
+
+/*
+ * DROP TEXT SEARCH TEMPLATE
+ */
+void
+RemoveTSTemplate(List *names, DropBehavior behavior, bool missing_ok)
+{
+ Oid tmplOid;
+ ObjectAddress object;
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to drop text search templates")));
+
+ tmplOid = TSTemplateGetTmplid(names, true);
+ if (!OidIsValid(tmplOid))
+ {
+ if (!missing_ok)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search template \"%s\" does not exist",
+ NameListToString(names))));
+ }
+ else
+ {
+ ereport(NOTICE,
+ (errmsg("text search template \"%s\" does not exist, skipping",
+ NameListToString(names))));
+ }
+ return;
+ }
+
+ object.classId = TSTemplateRelationId;
+ object.objectId = tmplOid;
+ object.objectSubId = 0;
+
+ performDeletion(&object, behavior);
+}
+
+/*
+ * Guts of TS template deletion.
+ */
+void
+RemoveTSTemplateById(Oid tmplId)
+{
+ Relation relation;
+ HeapTuple tup;
+
+ relation = heap_open(TSTemplateRelationId, RowExclusiveLock);
+
+ tup = SearchSysCache(TSTEMPLATEOID,
+ ObjectIdGetDatum(tmplId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search template %u",
+ tmplId);
+
+ simple_heap_delete(relation, &tup->t_self);
+
+ ReleaseSysCache(tup);
+
+ heap_close(relation, RowExclusiveLock);
+}
+
+/* ---------------------- TS Configuration commands -----------------------*/
+
+/*
+ * Finds syscache tuple of configuration.
+ * Returns NULL if no such cfg.
+ */
+static HeapTuple
+GetTSConfigTuple(List *names)
+{
+ HeapTuple tup;
+ Oid cfgId;
+
+ cfgId = TSConfigGetCfgid(names, true);
+ if (!OidIsValid(cfgId))
+ return NULL;
+
+ tup = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(cfgId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ cfgId);
+
+ return tup;
+}
+
+/*
+ * make pg_depend entries for a new or updated pg_ts_config entry
+ *
+ * Pass opened pg_ts_config_map relation if there might be any config map
+ * entries for the config.
+ */
+static void
+makeConfigurationDependencies(HeapTuple tuple, bool removeOld,
+ Relation mapRel)
+{
+ Form_pg_ts_config cfg = (Form_pg_ts_config) GETSTRUCT(tuple);
+ ObjectAddresses *addrs;
+ ObjectAddress myself,
+ referenced;
+
+ myself.classId = TSConfigRelationId;
+ myself.objectId = HeapTupleGetOid(tuple);
+ myself.objectSubId = 0;
+
+ /* for ALTER case, first flush old dependencies */
+ if (removeOld)
+ {
+ deleteDependencyRecordsFor(myself.classId, myself.objectId);
+ deleteSharedDependencyRecordsFor(myself.classId, myself.objectId);
+ }
+
+ /*
+ * We use an ObjectAddresses list to remove possible duplicate
+ * dependencies from the config map info. The pg_ts_config items
+ * shouldn't be duplicates, but might as well fold them all into one call.
+ */
+ addrs = new_object_addresses();
+
+ /* dependency on namespace */
+ referenced.classId = NamespaceRelationId;
+ referenced.objectId = cfg->cfgnamespace;
+ referenced.objectSubId = 0;
+ add_exact_object_address(&referenced, addrs);
+
+ /* dependency on owner */
+ recordDependencyOnOwner(myself.classId, myself.objectId, cfg->cfgowner);
+
+ /* dependency on parser */
+ referenced.classId = TSParserRelationId;
+ referenced.objectId = cfg->cfgparser;
+ referenced.objectSubId = 0;
+ add_exact_object_address(&referenced, addrs);
+
+ /* dependencies on dictionaries listed in config map */
+ if (mapRel)
+ {
+ ScanKeyData skey;
+ SysScanDesc scan;
+ HeapTuple maptup;
+
+ /* CCI to ensure we can see effects of caller's changes */
+ CommandCounterIncrement();
+
+ ScanKeyInit(&skey,
+ Anum_pg_ts_config_map_mapcfg,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(myself.objectId));
+
+ scan = systable_beginscan(mapRel, TSConfigMapIndexId, true,
+ SnapshotNow, 1, &skey);
+
+ while (HeapTupleIsValid((maptup = systable_getnext(scan))))
+ {
+ Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
+
+ referenced.classId = TSDictionaryRelationId;
+ referenced.objectId = cfgmap->mapdict;
+ referenced.objectSubId = 0;
+ add_exact_object_address(&referenced, addrs);
+ }
+
+ systable_endscan(scan);
+ }
+
+ /* Record 'em (this includes duplicate elimination) */
+ record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL);
+
+ free_object_addresses(addrs);
+}
+
+/*
+ * CREATE TEXT SEARCH CONFIGURATION
+ */
+void
+DefineTSConfiguration(List *names, List *parameters)
+{
+ Relation cfgRel;
+ Relation mapRel = NULL;
+ HeapTuple tup;
+ Datum values[Natts_pg_ts_config];
+ char nulls[Natts_pg_ts_config];
+ AclResult aclresult;
+ Oid namespaceoid;
+ char *cfgname;
+ NameData cname;
+ List *templateName = NIL;
+ Oid templateOid = InvalidOid;
+ Oid prsOid = InvalidOid;
+ bool with_map = false;
+ Oid cfgOid;
+ ListCell *pl;
+
+ /* Convert list of names to a name and namespace */
+ namespaceoid = QualifiedNameGetCreationNamespace(names, &cfgname);
+
+ /* Check we have creation rights in target namespace */
+ aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceoid));
+
+ /*
+ * loop over the definition list and extract the information we need.
+ */
+ foreach(pl, parameters)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ if (pg_strcasecmp(defel->defname, "parser") == 0)
+ prsOid = TSParserGetPrsid(defGetQualifiedName(defel), false);
+ else if (pg_strcasecmp(defel->defname, "template") == 0)
+ templateName = defGetQualifiedName(defel);
+ else if (pg_strcasecmp(defel->defname, "map") == 0)
+ with_map = defGetBoolean(defel);
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("text search configuration parameter \"%s\" not recognized",
+ defel->defname)));
+ }
+
+ /*
+ * Look up template if given. XXX the "template" is an existing config
+ * that we copy, not a pg_ts_template entry. This seems confusing.
+ * Maybe should use "source" or some other word?
+ */
+ if (templateName)
+ {
+ Form_pg_ts_config cfg;
+
+ templateOid = TSConfigGetCfgid(templateName, false);
+
+ tup = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(templateOid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ templateOid);
+
+ cfg = (Form_pg_ts_config) GETSTRUCT(tup);
+
+ /* Use template's parser if no other was specified */
+ if (!OidIsValid(prsOid))
+ prsOid = cfg->cfgparser;
+
+ ReleaseSysCache(tup);
+ }
+
+ /*
+ * Validation
+ */
+ if (!OidIsValid(prsOid))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+ errmsg("text search parser is required")));
+
+ /*
+ * Looks good, build tuple and insert
+ */
+ memset(values, 0, sizeof(values));
+ memset(nulls, ' ', sizeof(nulls));
+
+ namestrcpy(&cname, cfgname);
+ values[Anum_pg_ts_config_cfgname - 1] = NameGetDatum(&cname);
+ values[Anum_pg_ts_config_cfgnamespace - 1] = ObjectIdGetDatum(namespaceoid);
+ values[Anum_pg_ts_config_cfgowner - 1] = ObjectIdGetDatum(GetUserId());
+ values[Anum_pg_ts_config_cfgparser - 1] = ObjectIdGetDatum(prsOid);
+
+ cfgRel = heap_open(TSConfigRelationId, RowExclusiveLock);
+
+ tup = heap_formtuple(cfgRel->rd_att, values, nulls);
+
+ cfgOid = simple_heap_insert(cfgRel, tup);
+
+ CatalogUpdateIndexes(cfgRel, tup);
+
+ if (OidIsValid(templateOid) && with_map)
+ {
+ /*
+ * Copy token-dicts map from template
+ */
+ ScanKeyData skey;
+ SysScanDesc scan;
+ HeapTuple maptup;
+
+ mapRel = heap_open(TSConfigMapRelationId, RowExclusiveLock);
+
+ ScanKeyInit(&skey,
+ Anum_pg_ts_config_map_mapcfg,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(templateOid));
+
+ scan = systable_beginscan(mapRel, TSConfigMapIndexId, true,
+ SnapshotNow, 1, &skey);
+
+ while (HeapTupleIsValid((maptup = systable_getnext(scan))))
+ {
+ Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
+ HeapTuple newmaptup;
+ Datum mapvalues[Natts_pg_ts_config_map];
+ char mapnulls[Natts_pg_ts_config_map];
+
+ memset(mapvalues, 0, sizeof(mapvalues));
+ memset(mapnulls, ' ', sizeof(mapnulls));
+
+ mapvalues[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
+ mapvalues[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
+ mapvalues[Anum_pg_ts_config_map_mapseqno - 1] = cfgmap->mapseqno;
+ mapvalues[Anum_pg_ts_config_map_mapdict - 1] = cfgmap->mapdict;
+
+ newmaptup = heap_formtuple(mapRel->rd_att, mapvalues, mapnulls);
+
+ simple_heap_insert(mapRel, newmaptup);
+
+ CatalogUpdateIndexes(mapRel, newmaptup);
+
+ heap_freetuple(newmaptup);
+ }
+
+ systable_endscan(scan);
+ }
+
+ makeConfigurationDependencies(tup, false, mapRel);
+
+ heap_freetuple(tup);
+
+ if (mapRel)
+ heap_close(mapRel, RowExclusiveLock);
+ heap_close(cfgRel, RowExclusiveLock);
+}
+
+/*
+ * ALTER TEXT SEARCH CONFIGURATION RENAME
+ */
+void
+RenameTSConfiguration(List *oldname, const char *newname)
+{
+ HeapTuple tup;
+ Relation rel;
+ Oid cfgId;
+ AclResult aclresult;
+ Oid namespaceOid;
+
+ rel = heap_open(TSConfigRelationId, RowExclusiveLock);
+
+ cfgId = TSConfigGetCfgid(oldname, false);
+
+ tup = SearchSysCacheCopy(TSCONFIGOID,
+ ObjectIdGetDatum(cfgId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ cfgId);
+
+ namespaceOid = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgnamespace;
+
+ if (SearchSysCacheExists(TSCONFIGNAMENSP,
+ PointerGetDatum(newname),
+ ObjectIdGetDatum(namespaceOid),
+ 0, 0))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("text search configuration \"%s\" already exists",
+ newname)));
+
+ /* must be owner */
+ if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
+ NameListToString(oldname));
+
+ /* must have CREATE privilege on namespace */
+ aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceOid));
+
+ namestrcpy(&(((Form_pg_ts_config) GETSTRUCT(tup))->cfgname), newname);
+ simple_heap_update(rel, &tup->t_self, tup);
+ CatalogUpdateIndexes(rel, tup);
+
+ heap_close(rel, NoLock);
+ heap_freetuple(tup);
+}
+
+/*
+ * DROP TEXT SEARCH CONFIGURATION
+ */
+void
+RemoveTSConfiguration(List *names, DropBehavior behavior, bool missing_ok)
+{
+ Oid cfgOid;
+ Oid namespaceId;
+ ObjectAddress object;
+ HeapTuple tup;
+
+ tup = GetTSConfigTuple(names);
+
+ if (!HeapTupleIsValid(tup))
+ {
+ if (!missing_ok)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search configuration \"%s\" does not exist",
+ NameListToString(names))));
+ }
+ else
+ {
+ ereport(NOTICE,
+ (errmsg("text search configuration \"%s\" does not exist, skipping",
+ NameListToString(names))));
+ }
+ return;
+ }
+
+ /* Permission check: must own configuration or its namespace */
+ cfgOid = HeapTupleGetOid(tup);
+ namespaceId = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgnamespace;
+ if (!pg_ts_config_ownercheck(cfgOid, GetUserId()) &&
+ !pg_namespace_ownercheck(namespaceId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
+ NameListToString(names));
+
+ ReleaseSysCache(tup);
+
+ object.classId = TSConfigRelationId;
+ object.objectId = cfgOid;
+ object.objectSubId = 0;
+
+ performDeletion(&object, behavior);
+}
+
+/*
+ * Guts of TS configuration deletion.
+ */
+void
+RemoveTSConfigurationById(Oid cfgId)
+{
+ Relation relCfg,
+ relMap;
+ HeapTuple tup;
+ ScanKeyData skey;
+ SysScanDesc scan;
+
+ /* Remove the pg_ts_config entry */
+ relCfg = heap_open(TSConfigRelationId, RowExclusiveLock);
+
+ tup = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(cfgId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ cfgId);
+
+ simple_heap_delete(relCfg, &tup->t_self);
+
+ ReleaseSysCache(tup);
+
+ heap_close(relCfg, RowExclusiveLock);
+
+ /* Remove any pg_ts_config_map entries */
+ relMap = heap_open(TSConfigMapRelationId, RowExclusiveLock);
+
+ ScanKeyInit(&skey,
+ Anum_pg_ts_config_map_mapcfg,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(cfgId));
+
+ scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
+ SnapshotNow, 1, &skey);
+
+ while (HeapTupleIsValid((tup = systable_getnext(scan))))
+ {
+ simple_heap_delete(relMap, &tup->t_self);
+ }
+
+ systable_endscan(scan);
+
+ heap_close(relMap, RowExclusiveLock);
+}
+
+/*
+ * ALTER TEXT SEARCH CONFIGURATION OWNER
+ */
+void
+AlterTSConfigurationOwner(List *name, Oid newOwnerId)
+{
+ HeapTuple tup;
+ Relation rel;
+ Oid cfgId;
+ AclResult aclresult;
+ Oid namespaceOid;
+ Form_pg_ts_config form;
+
+ rel = heap_open(TSConfigRelationId, RowExclusiveLock);
+
+ cfgId = TSConfigGetCfgid(name, false);
+
+ tup = SearchSysCacheCopy(TSCONFIGOID,
+ ObjectIdGetDatum(cfgId),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(tup)) /* should not happen */
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ cfgId);
+
+ form = (Form_pg_ts_config) GETSTRUCT(tup);
+ namespaceOid = form->cfgnamespace;
+
+ if (form->cfgowner != newOwnerId)
+ {
+ /* Superusers can always do it */
+ if (!superuser())
+ {
+ /* must be owner */
+ if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
+ NameListToString(name));
+
+ /* Must be able to become new owner */
+ check_is_member_of_role(GetUserId(), newOwnerId);
+
+ /* New owner must have CREATE privilege on namespace */
+ aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ get_namespace_name(namespaceOid));
+ }
+
+ form->cfgowner = newOwnerId;
+
+ simple_heap_update(rel, &tup->t_self, tup);
+ CatalogUpdateIndexes(rel, tup);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(TSConfigRelationId, HeapTupleGetOid(tup),
+ newOwnerId);
+ }
+
+ heap_close(rel, NoLock);
+ heap_freetuple(tup);
+}
+
+/*
+ * ALTER TEXT SEARCH CONFIGURATION - main entry point
+ */
+void
+AlterTSConfiguration(AlterTSConfigurationStmt *stmt)
+{
+ HeapTuple tup;
+ HeapTuple newtup;
+ Relation mapRel;
+
+ /* Find the configuration */
+ tup = GetTSConfigTuple(stmt->cfgname);
+ if (!HeapTupleIsValid(tup))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("text search configuration \"%s\" does not exist",
+ NameListToString(stmt->cfgname))));
+
+ /* must be owner */
+ if (!pg_ts_config_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION,
+ NameListToString(stmt->cfgname));
+
+ /* Update fields of config tuple? */
+ if (stmt->options)
+ newtup = UpdateTSConfiguration(stmt, tup);
+ else
+ newtup = tup;
+
+ /* Add or drop mappings? */
+ if (stmt->dicts)
+ MakeConfigurationMapping(stmt, newtup);
+ else if (stmt->tokentype)
+ DropConfigurationMapping(stmt, newtup);
+
+ /*
+ * Even if we aren't changing mappings, there could already be some,
+ * so makeConfigurationDependencies always has to look.
+ */
+ mapRel = heap_open(TSConfigMapRelationId, AccessShareLock);
+
+ /* Update dependencies */
+ makeConfigurationDependencies(newtup, true, mapRel);
+
+ heap_close(mapRel, AccessShareLock);
+
+ ReleaseSysCache(tup);
+}
+
+/*
+ * ALTER TEXT SEARCH CONFIGURATION - update fields of pg_ts_config tuple
+ */
+static HeapTuple
+UpdateTSConfiguration(AlterTSConfigurationStmt *stmt, HeapTuple tup)
+{
+ Relation cfgRel;
+ ListCell *pl;
+ Datum repl_val[Natts_pg_ts_config];
+ char repl_null[Natts_pg_ts_config];
+ char repl_repl[Natts_pg_ts_config];
+ HeapTuple newtup;
+
+ memset(repl_val, 0, sizeof(repl_val));
+ memset(repl_null, ' ', sizeof(repl_null));
+ memset(repl_repl, ' ', sizeof(repl_repl));
+
+ cfgRel = heap_open(TSConfigRelationId, RowExclusiveLock);
+
+ foreach(pl, stmt->options)
+ {
+ DefElem *defel = (DefElem *) lfirst(pl);
+
+ if (pg_strcasecmp(defel->defname, "parser") == 0)
+ {
+ Oid newPrs;
+
+ newPrs = TSParserGetPrsid(defGetQualifiedName(defel), false);
+ repl_val[Anum_pg_ts_config_cfgparser - 1] = ObjectIdGetDatum(newPrs);
+ repl_repl[Anum_pg_ts_config_cfgparser - 1] = 'r';
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("text search configuration parameter \"%s\" not recognized",
+ defel->defname)));
+ }
+
+ newtup = heap_modifytuple(tup, RelationGetDescr(cfgRel),
+ repl_val, repl_null, repl_repl);
+
+ simple_heap_update(cfgRel, &newtup->t_self, newtup);
+
+ CatalogUpdateIndexes(cfgRel, newtup);
+
+ heap_close(cfgRel, RowExclusiveLock);
+
+ return newtup;
+}
+
+/*------------------- TS Configuration mapping stuff ----------------*/
+
+/*
+ * Translate a list of token type names to an array of token type numbers
+ */
+static int *
+getTokenTypes(Oid prsId, List *tokennames)
+{
+ TSParserCacheEntry *prs = lookup_ts_parser_cache(prsId);
+ LexDescr *list;
+ int *res,
+ i,
+ ntoken;
+ ListCell *tn;
+
+ ntoken = list_length(tokennames);
+ if (ntoken == 0)
+ return NULL;
+ res = (int *) palloc(sizeof(int) * ntoken);
+
+ if (!OidIsValid(prs->lextypeOid))
+ elog(ERROR, "method lextype isn't defined for text search parser %u",
+ prsId);
+
+ /* OidFunctionCall0 is absent */
+ list = (LexDescr *) DatumGetPointer(OidFunctionCall1(prs->lextypeOid,
+ (Datum) 0));
+
+ i = 0;
+ foreach(tn, tokennames)
+ {
+ Value *val = (Value *) lfirst(tn);
+ bool found = false;
+ int j;
+
+ j = 0;
+ while (list && list[j].lexid)
+ {
+ /* XXX should we use pg_strcasecmp here? */
+ if (strcmp(strVal(val), list[j].alias) == 0)
+ {
+ res[i] = list[j].lexid;
+ found = true;
+ break;
+ }
+ j++;
+ }
+ if (!found)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("token type \"%s\" does not exist",
+ strVal(val))));
+ i++;
+ }
+
+ return res;
+}
+
+/*
+ * ALTER TEXT SEARCH CONFIGURATION ADD/ALTER MAPPING
+ */
+static void
+MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup)
+{
+ Oid cfgId = HeapTupleGetOid(tup);
+ Relation relMap;
+ ScanKeyData skey[2];
+ SysScanDesc scan;
+ HeapTuple maptup;
+ int i;
+ int j;
+ Oid prsId;
+ int *tokens,
+ ntoken;
+ Oid *dictIds;
+ int ndict;
+ ListCell *c;
+
+ prsId = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgparser;
+
+ tokens = getTokenTypes(prsId, stmt->tokentype);
+ ntoken = list_length(stmt->tokentype);
+
+ relMap = heap_open(TSConfigMapRelationId, RowExclusiveLock);
+
+ if (stmt->override)
+ {
+ /*
+ * delete maps for tokens if they exist and command was ALTER
+ */
+ for (i = 0; i < ntoken; i++)
+ {
+ ScanKeyInit(&skey[0],
+ Anum_pg_ts_config_map_mapcfg,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(cfgId));
+ ScanKeyInit(&skey[1],
+ Anum_pg_ts_config_map_maptokentype,
+ BTEqualStrategyNumber, F_INT4EQ,
+ Int32GetDatum(tokens[i]));
+
+ scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
+ SnapshotNow, 2, skey);
+
+ while (HeapTupleIsValid((maptup = systable_getnext(scan))))
+ {
+ simple_heap_delete(relMap, &maptup->t_self);
+ }
+
+ systable_endscan(scan);
+ }
+ }
+
+ /*
+ * Convert list of dictionary names to array of dict OIDs
+ */
+ ndict = list_length(stmt->dicts);
+ dictIds = (Oid *) palloc(sizeof(Oid) * ndict);
+ i = 0;
+ foreach(c, stmt->dicts)
+ {
+ List *names = (List *) lfirst(c);
+
+ dictIds[i] = TSDictionaryGetDictid(names, false);
+ i++;
+ }
+
+ if (stmt->replace)
+ {
+ /*
+ * Replace a specific dictionary in existing entries
+ */
+ Oid dictOld = dictIds[0],
+ dictNew = dictIds[1];
+
+ ScanKeyInit(&skey[0],
+ Anum_pg_ts_config_map_mapcfg,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(cfgId));
+
+ scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
+ SnapshotNow, 1, skey);
+
+ while (HeapTupleIsValid((maptup = systable_getnext(scan))))
+ {
+ Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
+
+ /*
+ * check if it's one of target token types
+ */
+ if (tokens)
+ {
+ bool tokmatch = false;
+
+ for (j = 0; j < ntoken; j++)
+ {
+ if (cfgmap->maptokentype == tokens[j])
+ {
+ tokmatch = true;
+ break;
+ }
+ }
+ if (!tokmatch)
+ continue;
+ }
+
+ /*
+ * replace dictionary if match
+ */
+ if (cfgmap->mapdict == dictOld)
+ {
+ Datum repl_val[Natts_pg_ts_config_map];
+ char repl_null[Natts_pg_ts_config_map];
+ char repl_repl[Natts_pg_ts_config_map];
+ HeapTuple newtup;
+
+ memset(repl_val, 0, sizeof(repl_val));
+ memset(repl_null, ' ', sizeof(repl_null));
+ memset(repl_repl, ' ', sizeof(repl_repl));
+
+ repl_val[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictNew);
+ repl_repl[Anum_pg_ts_config_map_mapdict - 1] = 'r';
+
+ newtup = heap_modifytuple(maptup,
+ RelationGetDescr(relMap),
+ repl_val, repl_null, repl_repl);
+ simple_heap_update(relMap, &newtup->t_self, newtup);
+
+ CatalogUpdateIndexes(relMap, newtup);
+ }
+ }
+
+ systable_endscan(scan);
+ }
+ else
+ {
+ /*
+ * Insertion of new entries
+ */
+ for (i = 0; i < ntoken; i++)
+ {
+ for (j = 0; j < ndict; j++)
+ {
+ Datum values[Natts_pg_ts_config_map];
+ char nulls[Natts_pg_ts_config_map];
+
+ memset(nulls, ' ', sizeof(nulls));
+ values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
+ values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
+ values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
+ values[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictIds[j]);
+
+ tup = heap_formtuple(relMap->rd_att, values, nulls);
+ simple_heap_insert(relMap, tup);
+ CatalogUpdateIndexes(relMap, tup);
+
+ heap_freetuple(tup);
+ }
+ }
+ }
+
+ heap_close(relMap, RowExclusiveLock);
+}
+
+/*
+ * ALTER TEXT SEARCH CONFIGURATION DROP MAPPING
+ */
+static void
+DropConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup)
+{
+ Oid cfgId = HeapTupleGetOid(tup);
+ Relation relMap;
+ ScanKeyData skey[2];
+ SysScanDesc scan;
+ HeapTuple maptup;
+ int i;
+ Oid prsId;
+ int *tokens,
+ ntoken;
+ ListCell *c;
+
+ prsId = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgparser;
+
+ tokens = getTokenTypes(prsId, stmt->tokentype);
+ ntoken = list_length(stmt->tokentype);
+
+ relMap = heap_open(TSConfigMapRelationId, RowExclusiveLock);
+
+ i = 0;
+ foreach(c, stmt->tokentype)
+ {
+ Value *val = (Value *) lfirst(c);
+ bool found = false;
+
+ ScanKeyInit(&skey[0],
+ Anum_pg_ts_config_map_mapcfg,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(cfgId));
+ ScanKeyInit(&skey[1],
+ Anum_pg_ts_config_map_maptokentype,
+ BTEqualStrategyNumber, F_INT4EQ,
+ Int32GetDatum(tokens[i]));
+
+ scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
+ SnapshotNow, 2, skey);
+
+ while (HeapTupleIsValid((maptup = systable_getnext(scan))))
+ {
+ simple_heap_delete(relMap, &maptup->t_self);
+ found = true;
+ }
+
+ systable_endscan(scan);
+
+ if (!found)
+ {
+ if (!stmt->missing_ok)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("mapping for token type \"%s\" does not exist",
+ strVal(val))));
+ }
+ else
+ {
+ ereport(NOTICE,
+ (errmsg("mapping for token type \"%s\" does not exist, skipping",
+ strVal(val))));
+ }
+ }
+
+ i++;
+ }
+
+ heap_close(relMap, RowExclusiveLock);
+}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 324f89a2566..ed3d55c9d7b 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.597 2007/07/03 01:30:36 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.598 2007/08/21 01:11:15 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -173,6 +173,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
ViewStmt CheckPointStmt CreateConversionStmt
DeallocateStmt PrepareStmt ExecuteStmt
DropOwnedStmt ReassignOwnedStmt
+ AlterTSConfigurationStmt AlterTSDictionaryStmt
%type <node> select_no_parens select_with_parens select_clause
simple_select values_clause
@@ -375,14 +376,14 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
- COMMITTED CONCURRENTLY CONNECTION CONSTRAINT CONSTRAINTS
+ COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
CONTENT_P CONVERSION_P CONVERT COPY COST CREATE CREATEDB
CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
- DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
- DESC DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
+ DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC
+ DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EXCEPT EXCLUDING
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
@@ -407,7 +408,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
LOCK_P LOGIN_P
- MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
+ MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
@@ -416,7 +417,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
- PARTIAL PASSWORD PLACING PLANS POSITION
+ PARSER PARTIAL PASSWORD PLACING PLANS POSITION
PRECISION PRESERVE PREPARE PREPARED PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE
@@ -426,13 +427,13 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
RIGHT ROLE ROLLBACK ROW ROWS RULE
- SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
+ SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
SYMMETRIC SYSID SYSTEM_P
- TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP
+ TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT THEN TIME TIMESTAMP
TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
TRUNCATE TRUSTED TYPE_P
@@ -537,6 +538,8 @@ stmt :
| AlterTableStmt
| AlterRoleSetStmt
| AlterRoleStmt
+ | AlterTSConfigurationStmt
+ | AlterTSDictionaryStmt
| AlterUserSetStmt
| AlterUserStmt
| AnalyzeStmt
@@ -2972,6 +2975,42 @@ DefineStmt:
n->vals = $7;
$$ = (Node *)n;
}
+ | CREATE TEXT SEARCH PARSER any_name definition
+ {
+ DefineStmt *n = makeNode(DefineStmt);
+ n->kind = OBJECT_TSPARSER;
+ n->args = NIL;
+ n->defnames = $5;
+ n->definition = $6;
+ $$ = (Node *)n;
+ }
+ | CREATE TEXT SEARCH DICTIONARY any_name definition
+ {
+ DefineStmt *n = makeNode(DefineStmt);
+ n->kind = OBJECT_TSDICTIONARY;
+ n->args = NIL;
+ n->defnames = $5;
+ n->definition = $6;
+ $$ = (Node *)n;
+ }
+ | CREATE TEXT SEARCH TEMPLATE any_name definition
+ {
+ DefineStmt *n = makeNode(DefineStmt);
+ n->kind = OBJECT_TSTEMPLATE;
+ n->args = NIL;
+ n->defnames = $5;
+ n->definition = $6;
+ $$ = (Node *)n;
+ }
+ | CREATE TEXT SEARCH CONFIGURATION any_name definition
+ {
+ DefineStmt *n = makeNode(DefineStmt);
+ n->kind = OBJECT_TSCONFIGURATION;
+ n->args = NIL;
+ n->defnames = $5;
+ n->definition = $6;
+ $$ = (Node *)n;
+ }
;
definition: '(' def_list ')' { $$ = $2; }
@@ -3281,6 +3320,10 @@ drop_type: TABLE { $$ = OBJECT_TABLE; }
| DOMAIN_P { $$ = OBJECT_DOMAIN; }
| CONVERSION_P { $$ = OBJECT_CONVERSION; }
| SCHEMA { $$ = OBJECT_SCHEMA; }
+ | TEXT SEARCH PARSER { $$ = OBJECT_TSPARSER; }
+ | TEXT SEARCH DICTIONARY { $$ = OBJECT_TSDICTIONARY; }
+ | TEXT SEARCH TEMPLATE { $$ = OBJECT_TSTEMPLATE; }
+ | TEXT SEARCH CONFIGURATION { $$ = OBJECT_TSCONFIGURATION; }
;
any_name_list:
@@ -3323,7 +3366,10 @@ TruncateStmt:
*
* COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW |
* CONVERSION | LANGUAGE | OPERATOR CLASS | LARGE OBJECT |
- * CAST | COLUMN | SCHEMA | TABLESPACE | ROLE ] <objname> |
+ * CAST | COLUMN | SCHEMA | TABLESPACE | ROLE |
+ * TEXT SEARCH PARSER | TEXT SEARCH DICTIONARY |
+ * TEXT SEARCH TEMPLATE |
+ * TEXT SEARCH CONFIGURATION ] <objname> |
* AGGREGATE <aggname> (arg1, ...) |
* FUNCTION <funcname> (arg1, arg2, ...) |
* OPERATOR <op> (leftoperand_typ, rightoperand_typ) |
@@ -3454,6 +3500,38 @@ CommentStmt:
n->comment = $7;
$$ = (Node *) n;
}
+ | COMMENT ON TEXT SEARCH PARSER any_name IS comment_text
+ {
+ CommentStmt *n = makeNode(CommentStmt);
+ n->objtype = OBJECT_TSPARSER;
+ n->objname = $6;
+ n->comment = $8;
+ $$ = (Node *) n;
+ }
+ | COMMENT ON TEXT SEARCH DICTIONARY any_name IS comment_text
+ {
+ CommentStmt *n = makeNode(CommentStmt);
+ n->objtype = OBJECT_TSDICTIONARY;
+ n->objname = $6;
+ n->comment = $8;
+ $$ = (Node *) n;
+ }
+ | COMMENT ON TEXT SEARCH TEMPLATE any_name IS comment_text
+ {
+ CommentStmt *n = makeNode(CommentStmt);
+ n->objtype = OBJECT_TSTEMPLATE;
+ n->objname = $6;
+ n->comment = $8;
+ $$ = (Node *) n;
+ }
+ | COMMENT ON TEXT SEARCH CONFIGURATION any_name IS comment_text
+ {
+ CommentStmt *n = makeNode(CommentStmt);
+ n->objtype = OBJECT_TSCONFIGURATION;
+ n->objname = $6;
+ n->comment = $8;
+ $$ = (Node *) n;
+ }
;
comment_type:
@@ -4615,6 +4693,38 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
n->newname = $6;
$$ = (Node *)n;
}
+ | ALTER TEXT SEARCH PARSER any_name RENAME TO name
+ {
+ RenameStmt *n = makeNode(RenameStmt);
+ n->renameType = OBJECT_TSPARSER;
+ n->object = $5;
+ n->newname = $8;
+ $$ = (Node *)n;
+ }
+ | ALTER TEXT SEARCH DICTIONARY any_name RENAME TO name
+ {
+ RenameStmt *n = makeNode(RenameStmt);
+ n->renameType = OBJECT_TSDICTIONARY;
+ n->object = $5;
+ n->newname = $8;
+ $$ = (Node *)n;
+ }
+ | ALTER TEXT SEARCH TEMPLATE any_name RENAME TO name
+ {
+ RenameStmt *n = makeNode(RenameStmt);
+ n->renameType = OBJECT_TSTEMPLATE;
+ n->object = $5;
+ n->newname = $8;
+ $$ = (Node *)n;
+ }
+ | ALTER TEXT SEARCH CONFIGURATION any_name RENAME TO name
+ {
+ RenameStmt *n = makeNode(RenameStmt);
+ n->renameType = OBJECT_TSCONFIGURATION;
+ n->object = $5;
+ n->newname = $8;
+ $$ = (Node *)n;
+ }
;
opt_column: COLUMN { $$ = COLUMN; }
@@ -4787,6 +4897,22 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
n->newowner = $6;
$$ = (Node *)n;
}
+ | ALTER TEXT SEARCH DICTIONARY any_name OWNER TO RoleId
+ {
+ AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
+ n->objectType = OBJECT_TSDICTIONARY;
+ n->object = $5;
+ n->newowner = $8;
+ $$ = (Node *)n;
+ }
+ | ALTER TEXT SEARCH CONFIGURATION any_name OWNER TO RoleId
+ {
+ AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
+ n->objectType = OBJECT_TSCONFIGURATION;
+ n->object = $5;
+ n->newowner = $8;
+ $$ = (Node *)n;
+ }
;
@@ -5382,6 +5508,89 @@ opt_as: AS {}
/*****************************************************************************
*
+ * Manipulate a text search dictionary or configuration
+ *
+ *****************************************************************************/
+
+AlterTSDictionaryStmt:
+ ALTER TEXT SEARCH DICTIONARY any_name definition
+ {
+ AlterTSDictionaryStmt *n = makeNode(AlterTSDictionaryStmt);
+ n->dictname = $5;
+ n->options = $6;
+ $$ = (Node *)n;
+ }
+ ;
+
+AlterTSConfigurationStmt:
+ ALTER TEXT SEARCH CONFIGURATION any_name definition
+ {
+ AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+ n->cfgname = $5;
+ n->options = $6;
+ $$ = (Node *)n;
+ }
+ | ALTER TEXT SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list WITH any_name_list
+ {
+ AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+ n->cfgname = $5;
+ n->tokentype = $9;
+ n->dicts = $11;
+ n->override = false;
+ n->replace = false;
+ $$ = (Node*)n;
+ }
+ | ALTER TEXT SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list WITH any_name_list
+ {
+ AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+ n->cfgname = $5;
+ n->tokentype = $9;
+ n->dicts = $11;
+ n->override = true;
+ n->replace = false;
+ $$ = (Node*)n;
+ }
+ | ALTER TEXT SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name WITH any_name
+ {
+ AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+ n->cfgname = $5;
+ n->tokentype = NIL;
+ n->dicts = list_make2($9,$11);
+ n->override = false;
+ n->replace = true;
+ $$ = (Node*)n;
+ }
+ | ALTER TEXT SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name WITH any_name
+ {
+ AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+ n->cfgname = $5;
+ n->tokentype = $9;
+ n->dicts = list_make2($11,$13);
+ n->override = false;
+ n->replace = true;
+ $$ = (Node*)n;
+ }
+ | ALTER TEXT SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list
+ {
+ AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+ n->cfgname = $5;
+ n->tokentype = $9;
+ n->missing_ok = false;
+ $$ = (Node*)n;
+ }
+ | ALTER TEXT SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list
+ {
+ AlterTSConfigurationStmt *n = makeNode(AlterTSConfigurationStmt);
+ n->cfgname = $5;
+ n->tokentype = $11;
+ n->missing_ok = true;
+ $$ = (Node*)n;
+ }
+ ;
+
+
+/*****************************************************************************
+ *
* Manipulate a conversion
*
* CREATE [DEFAULT] CONVERSION <conversion_name>
@@ -8853,6 +9062,7 @@ unreserved_keyword:
| COMMIT
| COMMITTED
| CONCURRENTLY
+ | CONFIGURATION
| CONNECTION
| CONSTRAINTS
| CONTENT_P
@@ -8876,6 +9086,7 @@ unreserved_keyword:
| DELETE_P
| DELIMITER
| DELIMITERS
+ | DICTIONARY
| DISABLE_P
| DISCARD
| DOCUMENT_P
@@ -8933,6 +9144,7 @@ unreserved_keyword:
| LOCATION
| LOCK_P
| LOGIN_P
+ | MAPPING
| MATCH
| MAXVALUE
| MINUTE_P
@@ -8961,6 +9173,7 @@ unreserved_keyword:
| OPTION
| OWNED
| OWNER
+ | PARSER
| PARTIAL
| PASSWORD
| PLANS
@@ -8994,6 +9207,7 @@ unreserved_keyword:
| SAVEPOINT
| SCHEMA
| SCROLL
+ | SEARCH
| SECOND_P
| SECURITY
| SEQUENCE
@@ -9020,6 +9234,7 @@ unreserved_keyword:
| TEMP
| TEMPLATE
| TEMPORARY
+ | TEXT
| TRANSACTION
| TRIGGER
| TRUNCATE
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 5b62a9c7c98..1e97d854465 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.189 2007/06/18 21:40:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.190 2007/08/21 01:11:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -87,6 +87,7 @@ static const ScanKeyword ScanKeywords[] = {
{"commit", COMMIT, UNRESERVED_KEYWORD},
{"committed", COMMITTED, UNRESERVED_KEYWORD},
{"concurrently", CONCURRENTLY, UNRESERVED_KEYWORD},
+ {"configuration", CONFIGURATION, UNRESERVED_KEYWORD},
{"connection", CONNECTION, UNRESERVED_KEYWORD},
{"constraint", CONSTRAINT, RESERVED_KEYWORD},
{"constraints", CONSTRAINTS, UNRESERVED_KEYWORD},
@@ -124,6 +125,7 @@ static const ScanKeyword ScanKeywords[] = {
{"delimiter", DELIMITER, UNRESERVED_KEYWORD},
{"delimiters", DELIMITERS, UNRESERVED_KEYWORD},
{"desc", DESC, RESERVED_KEYWORD},
+ {"dictionary", DICTIONARY, UNRESERVED_KEYWORD},
{"disable", DISABLE_P, UNRESERVED_KEYWORD},
{"discard", DISCARD, UNRESERVED_KEYWORD},
{"distinct", DISTINCT, RESERVED_KEYWORD},
@@ -219,6 +221,7 @@ static const ScanKeyword ScanKeywords[] = {
{"location", LOCATION, UNRESERVED_KEYWORD},
{"lock", LOCK_P, UNRESERVED_KEYWORD},
{"login", LOGIN_P, UNRESERVED_KEYWORD},
+ {"mapping", MAPPING, UNRESERVED_KEYWORD},
{"match", MATCH, UNRESERVED_KEYWORD},
{"maxvalue", MAXVALUE, UNRESERVED_KEYWORD},
{"minute", MINUTE_P, UNRESERVED_KEYWORD},
@@ -268,6 +271,7 @@ static const ScanKeyword ScanKeywords[] = {
{"overlay", OVERLAY, COL_NAME_KEYWORD},
{"owned", OWNED, UNRESERVED_KEYWORD},
{"owner", OWNER, UNRESERVED_KEYWORD},
+ {"parser", PARSER, UNRESERVED_KEYWORD},
{"partial", PARTIAL, UNRESERVED_KEYWORD},
{"password", PASSWORD, UNRESERVED_KEYWORD},
{"placing", PLACING, RESERVED_KEYWORD},
@@ -310,6 +314,7 @@ static const ScanKeyword ScanKeywords[] = {
{"savepoint", SAVEPOINT, UNRESERVED_KEYWORD},
{"schema", SCHEMA, UNRESERVED_KEYWORD},
{"scroll", SCROLL, UNRESERVED_KEYWORD},
+ {"search", SEARCH, UNRESERVED_KEYWORD},
{"second", SECOND_P, UNRESERVED_KEYWORD},
{"security", SECURITY, UNRESERVED_KEYWORD},
{"select", SELECT, RESERVED_KEYWORD},
@@ -345,6 +350,7 @@ static const ScanKeyword ScanKeywords[] = {
{"temp", TEMP, UNRESERVED_KEYWORD},
{"template", TEMPLATE, UNRESERVED_KEYWORD},
{"temporary", TEMPORARY, UNRESERVED_KEYWORD},
+ {"text", TEXT, UNRESERVED_KEYWORD},
{"then", THEN, RESERVED_KEYWORD},
{"time", TIME, COL_NAME_KEYWORD},
{"timestamp", TIMESTAMP, COL_NAME_KEYWORD},
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index abc05685811..6fb7bd9b59f 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.155 2007/06/06 23:00:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.156 2007/08/21 01:11:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1554,6 +1554,8 @@ TypeCategory(Oid inType)
case (REGOPERATOROID):
case (REGCLASSOID):
case (REGTYPEOID):
+ case (REGCONFIGOID):
+ case (REGDICTIONARYOID):
case (INT2OID):
case (INT4OID):
case (INT8OID):
@@ -1672,7 +1674,9 @@ IsPreferredType(CATEGORY category, Oid type)
type == REGOPEROID ||
type == REGOPERATOROID ||
type == REGCLASSOID ||
- type == REGTYPEOID)
+ type == REGTYPEOID ||
+ type == REGCONFIGOID ||
+ type == REGDICTIONARYOID)
preftype = OIDOID;
else
preftype = FLOAT8OID;
diff --git a/src/backend/snowball/Makefile b/src/backend/snowball/Makefile
new file mode 100644
index 00000000000..f1d54eb0998
--- /dev/null
+++ b/src/backend/snowball/Makefile
@@ -0,0 +1,144 @@
+#-------------------------------------------------------------------------
+#
+# Makefile for src/backend/snowball
+#
+# $PostgreSQL: pgsql/src/backend/snowball/Makefile,v 1.1 2007/08/21 01:11:15 tgl Exp $
+#
+#-------------------------------------------------------------------------
+
+subdir = src/backend/snowball
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+override CPPFLAGS := -I$(top_srcdir)/src/include/snowball \
+ -I$(top_srcdir)/src/include/snowball/libstemmer $(CPPFLAGS)
+
+OBJS= dict_snowball.o api.o utilities.o \
+ stem_ISO_8859_1_danish.o \
+ stem_ISO_8859_1_dutch.o \
+ stem_ISO_8859_1_english.o \
+ stem_ISO_8859_1_finnish.o \
+ stem_ISO_8859_1_french.o \
+ stem_ISO_8859_1_german.o \
+ stem_ISO_8859_1_hungarian.o \
+ stem_ISO_8859_1_italian.o \
+ stem_ISO_8859_1_norwegian.o \
+ stem_ISO_8859_1_porter.o \
+ stem_ISO_8859_1_portuguese.o \
+ stem_ISO_8859_1_spanish.o \
+ stem_ISO_8859_1_swedish.o \
+ stem_ISO_8859_2_romanian.o \
+ stem_KOI8_R_russian.o \
+ stem_UTF_8_danish.o \
+ stem_UTF_8_dutch.o \
+ stem_UTF_8_english.o \
+ stem_UTF_8_finnish.o \
+ stem_UTF_8_french.o \
+ stem_UTF_8_german.o \
+ stem_UTF_8_hungarian.o \
+ stem_UTF_8_italian.o \
+ stem_UTF_8_norwegian.o \
+ stem_UTF_8_porter.o \
+ stem_UTF_8_portuguese.o \
+ stem_UTF_8_romanian.o \
+ stem_UTF_8_russian.o \
+ stem_UTF_8_spanish.o \
+ stem_UTF_8_swedish.o \
+ stem_UTF_8_turkish.o
+
+# second column is name of latin dictionary, if different
+LANGUAGES= \
+ danish danish \
+ dutch dutch \
+ english english \
+ finnish finnish \
+ french french \
+ german german \
+ hungarian hungarian \
+ italian italian \
+ norwegian norwegian \
+ portuguese portuguese \
+ romanian romanian \
+ russian english \
+ spanish spanish \
+ swedish swedish \
+ turkish turkish \
+
+
+SQLSCRIPT= snowball_create.sql
+DICTDIR=tsearch_data
+
+ifdef VPATH
+override VPATH := $(srcdir)/libstemmer:$(VPATH)
+else
+VPATH = $(srcdir)/libstemmer
+endif
+
+SHLIB_LINK := $(BE_DLLLIBS)
+
+NAME := dict_snowball
+SO_MAJOR_VERSION := 0
+SO_MINOR_VERSION := 0
+rpath =
+
+all: all-shared-lib $(SQLSCRIPT)
+
+include $(top_srcdir)/src/Makefile.shlib
+
+$(SQLSCRIPT): Makefile snowball_func.sql.in snowball.sql.in
+ifeq ($(enable_shared), yes)
+ echo '-- Language-specific snowball dictionaries' > $@
+ cat $(srcdir)/snowball_func.sql.in >> $@
+ @set $(LANGUAGES) ; \
+ while [ "$$#" -gt 0 ] ; \
+ do \
+ lang=$$1; shift; \
+ if [ -s $(srcdir)/stopwords/$${lang}.stop ] ; then \
+ stop=", StopWords=$${lang}" ; \
+ else \
+ stop=""; \
+ fi; \
+ nonlatdictname=$$lang; \
+ latdictname=$$1; shift; \
+ cat $(srcdir)/snowball.sql.in | \
+ sed -e "s#_DICTNAME_#$$lang#g" | \
+ sed -e "s#_CFGNAME_#$$lang#g" | \
+ sed -e "s#_LATDICTNAME_#$$latdictname#g" | \
+ sed -e "s#_NONLATDICTNAME_#$$nonlatdictname#g" | \
+ sed -e "s#_STOPWORDS_#$$stop#g" ; \
+ done >> $@
+else
+ echo "-- No language-specific snowball dictionaries, for lack of shared library support" > $@
+endif
+
+install: all installdirs
+ifeq ($(enable_shared), yes)
+ $(INSTALL_SHLIB) $(shlib) '$(DESTDIR)$(pkglibdir)/$(NAME)$(DLSUFFIX)'
+endif
+ $(INSTALL_DATA) $(SQLSCRIPT) '$(DESTDIR)$(datadir)'
+ @set $(LANGUAGES) ; \
+ while [ "$$#" -gt 0 ] ; \
+ do \
+ lang=$$1; shift; shift; \
+ if [ -s $(srcdir)/stopwords/$${lang}.stop ] ; then \
+ $(INSTALL_DATA) $(srcdir)/stopwords/$${lang}.stop '$(DESTDIR)$(datadir)/$(DICTDIR)' ; \
+ fi \
+ done
+
+installdirs:
+ $(mkinstalldirs) '$(DESTDIR)$(pkglibdir)' '$(DESTDIR)$(datadir)' '$(DESTDIR)$(datadir)/$(DICTDIR)'
+
+uninstall:
+ rm -f '$(DESTDIR)$(pkglibdir)/$(NAME)$(DLSUFFIX)'
+ rm -f '$(DESTDIR)$(datadir)/$(SQLSCRIPT)'
+ @set $(LANGUAGES) ; \
+ while [ "$$#" -gt 0 ] ; \
+ do \
+ lang=$$1; shift; shift; \
+ if [ -s $(srcdir)/stopwords/$${lang}.stop ] ; then \
+ rm -f '$(DESTDIR)$(datadir)/$(DICTDIR)/'$${lang}.stop ; \
+ fi \
+ done
+
+clean distclean maintainer-clean: clean-lib
+ rm -f $(OBJS) $(SQLSCRIPT)
diff --git a/src/backend/snowball/README b/src/backend/snowball/README
new file mode 100644
index 00000000000..099925ad8f0
--- /dev/null
+++ b/src/backend/snowball/README
@@ -0,0 +1,47 @@
+Snowball-based stemming
+-----------------------
+
+This module uses the word stemming code developed by the Snowball project,
+http://snowball.tartarus.org/
+which is released by them under a BSD-style license.
+
+The files under src/backend/snowball/libstemmer/ and
+src/include/snowball/libstemmer/ are taken directly from their libstemmer_c
+distribution, with only some minor adjustments of file inclusions. Note
+that most of these files are in fact derived files, not master source.
+The master sources are in the Snowball language, and are available along
+with the Snowball-to-C compiler from the Snowball project. We choose to
+include the derived files in the PostgreSQL distribution because most
+installations will not have the Snowball compiler available.
+
+To update the PostgreSQL sources from a new Snowball libstemmer_c
+distribution:
+
+1. Copy the *.c files in libstemmer_c/src_c/ to src/backend/snowball/libstemmer
+with replacement of "../runtime/header.h" by "header.h", for example
+
+for f in libstemmer_c/src_c/*.c
+do
+ sed 's|\.\./runtime/header\.h|header.h|' $f >libstemmer/`basename $f`
+done
+
+(Alternatively, if you rebuild the stemmer files from the master Snowball
+sources, just omit "-r ../runtime" from the Snowball compiler switches.)
+
+2. Copy the *.c files in libstemmer_c/runtime/ to
+src/backend/snowball/libstemmer, and edit them to remove direct inclusions
+of system headers such as <stdio.h> --- they should only include "header.h".
+(This removal avoids portability problems on some platforms where <stdio.h>
+is sensitive to largefile compilation options.)
+
+3. Copy the *.h files in libstemmer_c/src_c/ and libstemmer_c/runtime/
+to src/include/snowball/libstemmer. At this writing the header files
+do not require any changes.
+
+4. Check whether any stemmer modules have been added or removed. If so, edit
+the OBJS list in Makefile, the list of #include's in dict_snowball.c, and the
+stemmer_modules[] table in dict_snowball.c.
+
+5. The various stopword files in stopwords/ must be downloaded
+individually from pages on the snowball.tartarus.org website.
+Be careful that these files must be stored in UTF-8 encoding.
diff --git a/src/backend/snowball/dict_snowball.c b/src/backend/snowball/dict_snowball.c
new file mode 100644
index 00000000000..f0bc2feedec
--- /dev/null
+++ b/src/backend/snowball/dict_snowball.c
@@ -0,0 +1,326 @@
+/*-------------------------------------------------------------------------
+ *
+ * dict_snowball.c
+ * Snowball dictionary
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/snowball/dict_snowball.c,v 1.1 2007/08/21 01:11:16 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+
+/* Some platforms define MAXINT and/or MININT, causing conflicts */
+#ifdef MAXINT
+#undef MAXINT
+#endif
+#ifdef MININT
+#undef MININT
+#endif
+
+/* Now we can include the original Snowball header.h */
+#include "snowball/libstemmer/header.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_danish.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_dutch.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_english.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_finnish.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_french.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_german.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_hungarian.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_italian.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_norwegian.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_porter.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_portuguese.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_spanish.h"
+#include "snowball/libstemmer/stem_ISO_8859_1_swedish.h"
+#include "snowball/libstemmer/stem_ISO_8859_2_romanian.h"
+#include "snowball/libstemmer/stem_KOI8_R_russian.h"
+#include "snowball/libstemmer/stem_UTF_8_danish.h"
+#include "snowball/libstemmer/stem_UTF_8_dutch.h"
+#include "snowball/libstemmer/stem_UTF_8_english.h"
+#include "snowball/libstemmer/stem_UTF_8_finnish.h"
+#include "snowball/libstemmer/stem_UTF_8_french.h"
+#include "snowball/libstemmer/stem_UTF_8_german.h"
+#include "snowball/libstemmer/stem_UTF_8_hungarian.h"
+#include "snowball/libstemmer/stem_UTF_8_italian.h"
+#include "snowball/libstemmer/stem_UTF_8_norwegian.h"
+#include "snowball/libstemmer/stem_UTF_8_porter.h"
+#include "snowball/libstemmer/stem_UTF_8_portuguese.h"
+#include "snowball/libstemmer/stem_UTF_8_romanian.h"
+#include "snowball/libstemmer/stem_UTF_8_russian.h"
+#include "snowball/libstemmer/stem_UTF_8_spanish.h"
+#include "snowball/libstemmer/stem_UTF_8_swedish.h"
+#include "snowball/libstemmer/stem_UTF_8_turkish.h"
+
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(dsnowball_init);
+Datum dsnowball_init(PG_FUNCTION_ARGS);
+PG_FUNCTION_INFO_V1(dsnowball_lexize);
+Datum dsnowball_lexize(PG_FUNCTION_ARGS);
+
+/* List of supported modules */
+typedef struct stemmer_module
+{
+ const char *name;
+ pg_enc enc;
+ struct SN_env *(*create) (void);
+ void (*close) (struct SN_env *);
+ int (*stem) (struct SN_env *);
+} stemmer_module;
+
+static const stemmer_module stemmer_modules[] =
+{
+ /*
+ * Stemmers list from Snowball distribution
+ */
+ {"danish", PG_LATIN1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem},
+ {"dutch", PG_LATIN1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem},
+ {"english", PG_LATIN1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem},
+ {"finnish", PG_LATIN1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem},
+ {"french", PG_LATIN1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem},
+ {"german", PG_LATIN1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem},
+ {"hungarian", PG_LATIN1, hungarian_ISO_8859_1_create_env, hungarian_ISO_8859_1_close_env, hungarian_ISO_8859_1_stem},
+ {"italian", PG_LATIN1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem},
+ {"norwegian", PG_LATIN1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem},
+ {"porter", PG_LATIN1, porter_ISO_8859_1_create_env, porter_ISO_8859_1_close_env, porter_ISO_8859_1_stem},
+ {"portuguese", PG_LATIN1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem},
+ {"spanish", PG_LATIN1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem},
+ {"swedish", PG_LATIN1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem},
+ {"romanian", PG_LATIN2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem},
+ {"russian", PG_KOI8R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem},
+ {"danish", PG_UTF8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem},
+ {"dutch", PG_UTF8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem},
+ {"english", PG_UTF8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem},
+ {"finnish", PG_UTF8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem},
+ {"french", PG_UTF8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem},
+ {"german", PG_UTF8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem},
+ {"hungarian", PG_UTF8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem},
+ {"italian", PG_UTF8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem},
+ {"norwegian", PG_UTF8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem},
+ {"porter", PG_UTF8, porter_UTF_8_create_env, porter_UTF_8_close_env, porter_UTF_8_stem},
+ {"portuguese", PG_UTF8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem},
+ {"romanian", PG_UTF8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem},
+ {"russian", PG_UTF8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem},
+ {"spanish", PG_UTF8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem},
+ {"swedish", PG_UTF8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem},
+ {"turkish", PG_UTF8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem},
+
+ /*
+ * Stemmer with PG_SQL_ASCII encoding should be valid for any server
+ * encoding
+ */
+ {"english", PG_SQL_ASCII, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem},
+
+ {NULL, 0, NULL, NULL, NULL} /* list end marker */
+};
+
+
+typedef struct DictSnowball
+{
+ struct SN_env *z;
+ StopList stoplist;
+ bool needrecode; /* needs recoding before/after call stem */
+ int (*stem) (struct SN_env * z);
+
+ /*
+ * snowball saves alloced memory between calls, so we should run it in our
+ * private memory context. Note, init function is executed in long lived
+ * context, so we just remember CurrentMemoryContext
+ */
+ MemoryContext dictCtx;
+} DictSnowball;
+
+
+static void
+locate_stem_module(DictSnowball * d, char *lang)
+{
+ const stemmer_module *m;
+
+ /*
+ * First, try to find exact match of stemmer module. Stemmer with
+ * PG_SQL_ASCII encoding is treated as working with any server encoding
+ */
+ for (m = stemmer_modules; m->name; m++)
+ {
+ if ((m->enc == PG_SQL_ASCII || m->enc == GetDatabaseEncoding()) &&
+ pg_strcasecmp(m->name, lang) == 0)
+ {
+ d->stem = m->stem;
+ d->z = m->create();
+ d->needrecode = false;
+ return;
+ }
+ }
+
+ /*
+ * Second, try to find stemmer for needed language for UTF8 encoding.
+ */
+ for (m = stemmer_modules; m->name; m++)
+ {
+ if (m->enc == PG_UTF8 && pg_strcasecmp(m->name, lang) == 0)
+ {
+ d->stem = m->stem;
+ d->z = m->create();
+ d->needrecode = true;
+ return;
+ }
+ }
+
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("no Snowball stemmer available for language \"%s\" and encoding \"%s\"",
+ lang, GetDatabaseEncodingName())));
+}
+
+Datum
+dsnowball_init(PG_FUNCTION_ARGS)
+{
+ text *in;
+ DictSnowball *d;
+ Map *cfg,
+ *pcfg;
+ bool stoploaded = false;
+
+ /* init functions must defend against NULLs for themselves */
+ if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("NULL config not allowed for Snowball")));
+ in = PG_GETARG_TEXT_P(0);
+
+ d = (DictSnowball *) palloc0(sizeof(DictSnowball));
+ d->stoplist.wordop = recode_and_lowerstr;
+
+ parse_keyvalpairs(in, &cfg);
+ pcfg = cfg;
+ PG_FREE_IF_COPY(in, 0);
+
+ while (pcfg && pcfg->key)
+ {
+ if (pg_strcasecmp("StopWords", pcfg->key) == 0)
+ {
+ if (stoploaded)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("multiple StopWords parameters")));
+ readstoplist(pcfg->value, &d->stoplist);
+ sortstoplist(&d->stoplist);
+ stoploaded = true;
+ }
+ else if (pg_strcasecmp("Language", pcfg->key) == 0)
+ {
+ if (d->stem)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("multiple Language parameters")));
+ locate_stem_module(d, pcfg->value);
+ }
+ else
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized Snowball parameter: \"%s\"",
+ pcfg->key)));
+ }
+
+ pfree(pcfg->key);
+ pfree(pcfg->value);
+ pcfg++;
+ }
+ pfree(cfg);
+
+ if (!d->stem)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("missing Language parameter")));
+
+ d->dictCtx = CurrentMemoryContext;
+
+ PG_RETURN_POINTER(d);
+}
+
+Datum
+dsnowball_lexize(PG_FUNCTION_ARGS)
+{
+ DictSnowball *d = (DictSnowball *) PG_GETARG_POINTER(0);
+ char *in = (char *) PG_GETARG_POINTER(1);
+ int32 len = PG_GETARG_INT32(2);
+ char *txt = lowerstr_with_len(in, len);
+ TSLexeme *res = palloc0(sizeof(TSLexeme) * 2);
+
+ if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
+ {
+ pfree(txt);
+ }
+ else
+ {
+ MemoryContext saveCtx;
+
+ /*
+ * recode to utf8 if stemmer is utf8 and doesn't match server encoding
+ */
+ if (d->needrecode)
+ {
+ char *recoded;
+
+ recoded = (char *) pg_do_encoding_conversion((unsigned char *) txt,
+ strlen(txt),
+ GetDatabaseEncoding(),
+ PG_UTF8);
+ if (recoded == NULL)
+ elog(ERROR, "encoding conversion failed");
+
+ if (recoded != txt)
+ {
+ pfree(txt);
+ txt = recoded;
+ }
+ }
+
+ /* see comment about d->dictCtx */
+ saveCtx = MemoryContextSwitchTo(d->dictCtx);
+ SN_set_current(d->z, strlen(txt), (symbol *) txt);
+ d->stem(d->z);
+ MemoryContextSwitchTo(saveCtx);
+
+ if (d->z->p && d->z->l)
+ {
+ txt = repalloc(txt, d->z->l + 1);
+ memcpy(txt, d->z->p, d->z->l);
+ txt[d->z->l] = '\0';
+ }
+
+ /* back recode if needed */
+ if (d->needrecode)
+ {
+ char *recoded;
+
+ recoded = (char *) pg_do_encoding_conversion((unsigned char *) txt,
+ strlen(txt),
+ PG_UTF8,
+ GetDatabaseEncoding());
+ if (recoded == NULL)
+ elog(ERROR, "encoding conversion failed");
+
+ if (recoded != txt)
+ {
+ pfree(txt);
+ txt = recoded;
+ }
+ }
+
+ res->lexeme = txt;
+ }
+
+ PG_RETURN_POINTER(res);
+}
diff --git a/src/backend/snowball/libstemmer/api.c b/src/backend/snowball/libstemmer/api.c
new file mode 100644
index 00000000000..530b427a466
--- /dev/null
+++ b/src/backend/snowball/libstemmer/api.c
@@ -0,0 +1,64 @@
+#include "header.h"
+
+extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size)
+{
+ struct SN_env * z = (struct SN_env *) calloc(1, sizeof(struct SN_env));
+ if (z == NULL) return NULL;
+ z->p = create_s();
+ if (z->p == NULL) goto error;
+ if (S_size)
+ {
+ int i;
+ z->S = (symbol * *) calloc(S_size, sizeof(symbol *));
+ if (z->S == NULL) goto error;
+
+ for (i = 0; i < S_size; i++)
+ {
+ z->S[i] = create_s();
+ if (z->S[i] == NULL) goto error;
+ }
+ }
+
+ if (I_size)
+ {
+ z->I = (int *) calloc(I_size, sizeof(int));
+ if (z->I == NULL) goto error;
+ }
+
+ if (B_size)
+ {
+ z->B = (unsigned char *) calloc(B_size, sizeof(unsigned char));
+ if (z->B == NULL) goto error;
+ }
+
+ return z;
+error:
+ SN_close_env(z, S_size);
+ return NULL;
+}
+
+extern void SN_close_env(struct SN_env * z, int S_size)
+{
+ if (z == NULL) return;
+ if (S_size)
+ {
+ int i;
+ for (i = 0; i < S_size; i++)
+ {
+ lose_s(z->S[i]);
+ }
+ free(z->S);
+ }
+ free(z->I);
+ free(z->B);
+ if (z->p) lose_s(z->p);
+ free(z);
+}
+
+extern int SN_set_current(struct SN_env * z, int size, const symbol * s)
+{
+ int err = replace_s(z, 0, z->l, size, s, NULL);
+ z->c = 0;
+ return err;
+}
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c
new file mode 100644
index 00000000000..36a9f99276f
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c
@@ -0,0 +1,337 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int danish_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_undouble(struct SN_env * z);
+static int r_other_suffix(struct SN_env * z);
+static int r_consonant_pair(struct SN_env * z);
+static int r_main_suffix(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * danish_ISO_8859_1_create_env(void);
+extern void danish_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[3] = { 'h', 'e', 'd' };
+static const symbol s_0_1[5] = { 'e', 't', 'h', 'e', 'd' };
+static const symbol s_0_2[4] = { 'e', 'r', 'e', 'd' };
+static const symbol s_0_3[1] = { 'e' };
+static const symbol s_0_4[5] = { 'e', 'r', 'e', 'd', 'e' };
+static const symbol s_0_5[4] = { 'e', 'n', 'd', 'e' };
+static const symbol s_0_6[6] = { 'e', 'r', 'e', 'n', 'd', 'e' };
+static const symbol s_0_7[3] = { 'e', 'n', 'e' };
+static const symbol s_0_8[4] = { 'e', 'r', 'n', 'e' };
+static const symbol s_0_9[3] = { 'e', 'r', 'e' };
+static const symbol s_0_10[2] = { 'e', 'n' };
+static const symbol s_0_11[5] = { 'h', 'e', 'd', 'e', 'n' };
+static const symbol s_0_12[4] = { 'e', 'r', 'e', 'n' };
+static const symbol s_0_13[2] = { 'e', 'r' };
+static const symbol s_0_14[5] = { 'h', 'e', 'd', 'e', 'r' };
+static const symbol s_0_15[4] = { 'e', 'r', 'e', 'r' };
+static const symbol s_0_16[1] = { 's' };
+static const symbol s_0_17[4] = { 'h', 'e', 'd', 's' };
+static const symbol s_0_18[2] = { 'e', 's' };
+static const symbol s_0_19[5] = { 'e', 'n', 'd', 'e', 's' };
+static const symbol s_0_20[7] = { 'e', 'r', 'e', 'n', 'd', 'e', 's' };
+static const symbol s_0_21[4] = { 'e', 'n', 'e', 's' };
+static const symbol s_0_22[5] = { 'e', 'r', 'n', 'e', 's' };
+static const symbol s_0_23[4] = { 'e', 'r', 'e', 's' };
+static const symbol s_0_24[3] = { 'e', 'n', 's' };
+static const symbol s_0_25[6] = { 'h', 'e', 'd', 'e', 'n', 's' };
+static const symbol s_0_26[5] = { 'e', 'r', 'e', 'n', 's' };
+static const symbol s_0_27[3] = { 'e', 'r', 's' };
+static const symbol s_0_28[3] = { 'e', 't', 's' };
+static const symbol s_0_29[5] = { 'e', 'r', 'e', 't', 's' };
+static const symbol s_0_30[2] = { 'e', 't' };
+static const symbol s_0_31[4] = { 'e', 'r', 'e', 't' };
+
+static const struct among a_0[32] =
+{
+/* 0 */ { 3, s_0_0, -1, 1, 0},
+/* 1 */ { 5, s_0_1, 0, 1, 0},
+/* 2 */ { 4, s_0_2, -1, 1, 0},
+/* 3 */ { 1, s_0_3, -1, 1, 0},
+/* 4 */ { 5, s_0_4, 3, 1, 0},
+/* 5 */ { 4, s_0_5, 3, 1, 0},
+/* 6 */ { 6, s_0_6, 5, 1, 0},
+/* 7 */ { 3, s_0_7, 3, 1, 0},
+/* 8 */ { 4, s_0_8, 3, 1, 0},
+/* 9 */ { 3, s_0_9, 3, 1, 0},
+/* 10 */ { 2, s_0_10, -1, 1, 0},
+/* 11 */ { 5, s_0_11, 10, 1, 0},
+/* 12 */ { 4, s_0_12, 10, 1, 0},
+/* 13 */ { 2, s_0_13, -1, 1, 0},
+/* 14 */ { 5, s_0_14, 13, 1, 0},
+/* 15 */ { 4, s_0_15, 13, 1, 0},
+/* 16 */ { 1, s_0_16, -1, 2, 0},
+/* 17 */ { 4, s_0_17, 16, 1, 0},
+/* 18 */ { 2, s_0_18, 16, 1, 0},
+/* 19 */ { 5, s_0_19, 18, 1, 0},
+/* 20 */ { 7, s_0_20, 19, 1, 0},
+/* 21 */ { 4, s_0_21, 18, 1, 0},
+/* 22 */ { 5, s_0_22, 18, 1, 0},
+/* 23 */ { 4, s_0_23, 18, 1, 0},
+/* 24 */ { 3, s_0_24, 16, 1, 0},
+/* 25 */ { 6, s_0_25, 24, 1, 0},
+/* 26 */ { 5, s_0_26, 24, 1, 0},
+/* 27 */ { 3, s_0_27, 16, 1, 0},
+/* 28 */ { 3, s_0_28, 16, 1, 0},
+/* 29 */ { 5, s_0_29, 28, 1, 0},
+/* 30 */ { 2, s_0_30, -1, 1, 0},
+/* 31 */ { 4, s_0_31, 30, 1, 0}
+};
+
+static const symbol s_1_0[2] = { 'g', 'd' };
+static const symbol s_1_1[2] = { 'd', 't' };
+static const symbol s_1_2[2] = { 'g', 't' };
+static const symbol s_1_3[2] = { 'k', 't' };
+
+static const struct among a_1[4] =
+{
+/* 0 */ { 2, s_1_0, -1, -1, 0},
+/* 1 */ { 2, s_1_1, -1, -1, 0},
+/* 2 */ { 2, s_1_2, -1, -1, 0},
+/* 3 */ { 2, s_1_3, -1, -1, 0}
+};
+
+static const symbol s_2_0[2] = { 'i', 'g' };
+static const symbol s_2_1[3] = { 'l', 'i', 'g' };
+static const symbol s_2_2[4] = { 'e', 'l', 'i', 'g' };
+static const symbol s_2_3[3] = { 'e', 'l', 's' };
+static const symbol s_2_4[4] = { 'l', 0xF8, 's', 't' };
+
+static const struct among a_2[5] =
+{
+/* 0 */ { 2, s_2_0, -1, 1, 0},
+/* 1 */ { 3, s_2_1, 0, 1, 0},
+/* 2 */ { 4, s_2_2, 1, 1, 0},
+/* 3 */ { 3, s_2_3, -1, 1, 0},
+/* 4 */ { 4, s_2_4, -1, 2, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 };
+
+static const unsigned char g_s_ending[] = { 239, 254, 42, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 };
+
+static const symbol s_0[] = { 's', 't' };
+static const symbol s_1[] = { 'i', 'g' };
+static const symbol s_2[] = { 'l', 0xF8, 's' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ { int c_test = z->c; /* test, line 33 */
+ { int ret = z->c + 3;
+ if (0 > ret || ret > z->l) return 0;
+ z->c = ret; /* hop, line 33 */
+ }
+ z->I[1] = z->c; /* setmark x, line 33 */
+ z->c = c_test;
+ }
+ if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 34 */
+ { /* gopast */ /* non v, line 34 */
+ int ret = in_grouping(z, g_v, 97, 248, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 34 */
+ /* try, line 35 */
+ if (!(z->I[0] < z->I[1])) goto lab0;
+ z->I[0] = z->I[1];
+lab0:
+ return 1;
+}
+
+static int r_main_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 41 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 41 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 41 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_0, 32); /* substring, line 41 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 41 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 48 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (in_grouping_b(z, g_s_ending, 97, 229, 0)) return 0;
+ { int ret = slice_del(z); /* delete, line 50 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_consonant_pair(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 55 */
+ { int mlimit; /* setlimit, line 56 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 56 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 56 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit; return 0; }
+ if (!(find_among_b(z, a_1, 4))) { z->lb = mlimit; return 0; } /* substring, line 56 */
+ z->bra = z->c; /* ], line 56 */
+ z->lb = mlimit;
+ }
+ z->c = z->l - m_test;
+ }
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 62 */
+ z->bra = z->c; /* ], line 62 */
+ { int ret = slice_del(z); /* delete, line 62 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_other_suffix(struct SN_env * z) {
+ int among_var;
+ { int m1 = z->l - z->c; (void)m1; /* do, line 66 */
+ z->ket = z->c; /* [, line 66 */
+ if (!(eq_s_b(z, 2, s_0))) goto lab0;
+ z->bra = z->c; /* ], line 66 */
+ if (!(eq_s_b(z, 2, s_1))) goto lab0;
+ { int ret = slice_del(z); /* delete, line 66 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = z->l - m1;
+ }
+ { int mlimit; /* setlimit, line 67 */
+ int m2 = z->l - z->c; (void)m2;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 67 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m2;
+ z->ket = z->c; /* [, line 67 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_2, 5); /* substring, line 67 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 67 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 70 */
+ if (ret < 0) return ret;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 70 */
+ { int ret = r_consonant_pair(z);
+ if (ret == 0) goto lab1; /* call consonant_pair, line 70 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m3;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 3, s_2); /* <-, line 72 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_undouble(struct SN_env * z) {
+ { int mlimit; /* setlimit, line 76 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 76 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 76 */
+ if (out_grouping_b(z, g_v, 97, 248, 0)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 76 */
+ z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 76 */
+ if (z->S[0] == 0) return -1; /* -> ch, line 76 */
+ z->lb = mlimit;
+ }
+ if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 77 */
+ { int ret = slice_del(z); /* delete, line 78 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern int danish_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 84 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 84 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 85 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 86 */
+ { int ret = r_main_suffix(z);
+ if (ret == 0) goto lab1; /* call main_suffix, line 86 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 87 */
+ { int ret = r_consonant_pair(z);
+ if (ret == 0) goto lab2; /* call consonant_pair, line 87 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 88 */
+ { int ret = r_other_suffix(z);
+ if (ret == 0) goto lab3; /* call other_suffix, line 88 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 89 */
+ { int ret = r_undouble(z);
+ if (ret == 0) goto lab4; /* call undouble, line 89 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ z->c = z->l - m5;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * danish_ISO_8859_1_create_env(void) { return SN_create_env(1, 2, 0); }
+
+extern void danish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 1); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c
new file mode 100644
index 00000000000..e5ba288b1f5
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c
@@ -0,0 +1,624 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int dutch_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_standard_suffix(struct SN_env * z);
+static int r_undouble(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_en_ending(struct SN_env * z);
+static int r_e_ending(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * dutch_ISO_8859_1_create_env(void);
+extern void dutch_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[1] = { 0xE1 };
+static const symbol s_0_2[1] = { 0xE4 };
+static const symbol s_0_3[1] = { 0xE9 };
+static const symbol s_0_4[1] = { 0xEB };
+static const symbol s_0_5[1] = { 0xED };
+static const symbol s_0_6[1] = { 0xEF };
+static const symbol s_0_7[1] = { 0xF3 };
+static const symbol s_0_8[1] = { 0xF6 };
+static const symbol s_0_9[1] = { 0xFA };
+static const symbol s_0_10[1] = { 0xFC };
+
+static const struct among a_0[11] =
+{
+/* 0 */ { 0, 0, -1, 6, 0},
+/* 1 */ { 1, s_0_1, 0, 1, 0},
+/* 2 */ { 1, s_0_2, 0, 1, 0},
+/* 3 */ { 1, s_0_3, 0, 2, 0},
+/* 4 */ { 1, s_0_4, 0, 2, 0},
+/* 5 */ { 1, s_0_5, 0, 3, 0},
+/* 6 */ { 1, s_0_6, 0, 3, 0},
+/* 7 */ { 1, s_0_7, 0, 4, 0},
+/* 8 */ { 1, s_0_8, 0, 4, 0},
+/* 9 */ { 1, s_0_9, 0, 5, 0},
+/* 10 */ { 1, s_0_10, 0, 5, 0}
+};
+
+static const symbol s_1_1[1] = { 'I' };
+static const symbol s_1_2[1] = { 'Y' };
+
+static const struct among a_1[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 1, s_1_1, 0, 2, 0},
+/* 2 */ { 1, s_1_2, 0, 1, 0}
+};
+
+static const symbol s_2_0[2] = { 'd', 'd' };
+static const symbol s_2_1[2] = { 'k', 'k' };
+static const symbol s_2_2[2] = { 't', 't' };
+
+static const struct among a_2[3] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 2, s_2_1, -1, -1, 0},
+/* 2 */ { 2, s_2_2, -1, -1, 0}
+};
+
+static const symbol s_3_0[3] = { 'e', 'n', 'e' };
+static const symbol s_3_1[2] = { 's', 'e' };
+static const symbol s_3_2[2] = { 'e', 'n' };
+static const symbol s_3_3[5] = { 'h', 'e', 'd', 'e', 'n' };
+static const symbol s_3_4[1] = { 's' };
+
+static const struct among a_3[5] =
+{
+/* 0 */ { 3, s_3_0, -1, 2, 0},
+/* 1 */ { 2, s_3_1, -1, 3, 0},
+/* 2 */ { 2, s_3_2, -1, 2, 0},
+/* 3 */ { 5, s_3_3, 2, 1, 0},
+/* 4 */ { 1, s_3_4, -1, 3, 0}
+};
+
+static const symbol s_4_0[3] = { 'e', 'n', 'd' };
+static const symbol s_4_1[2] = { 'i', 'g' };
+static const symbol s_4_2[3] = { 'i', 'n', 'g' };
+static const symbol s_4_3[4] = { 'l', 'i', 'j', 'k' };
+static const symbol s_4_4[4] = { 'b', 'a', 'a', 'r' };
+static const symbol s_4_5[3] = { 'b', 'a', 'r' };
+
+static const struct among a_4[6] =
+{
+/* 0 */ { 3, s_4_0, -1, 1, 0},
+/* 1 */ { 2, s_4_1, -1, 2, 0},
+/* 2 */ { 3, s_4_2, -1, 1, 0},
+/* 3 */ { 4, s_4_3, -1, 3, 0},
+/* 4 */ { 4, s_4_4, -1, 4, 0},
+/* 5 */ { 3, s_4_5, -1, 5, 0}
+};
+
+static const symbol s_5_0[2] = { 'a', 'a' };
+static const symbol s_5_1[2] = { 'e', 'e' };
+static const symbol s_5_2[2] = { 'o', 'o' };
+static const symbol s_5_3[2] = { 'u', 'u' };
+
+static const struct among a_5[4] =
+{
+/* 0 */ { 2, s_5_0, -1, -1, 0},
+/* 1 */ { 2, s_5_1, -1, -1, 0},
+/* 2 */ { 2, s_5_2, -1, -1, 0},
+/* 3 */ { 2, s_5_3, -1, -1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
+
+static const unsigned char g_v_I[] = { 1, 0, 0, 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
+
+static const unsigned char g_v_j[] = { 17, 67, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
+
+static const symbol s_0[] = { 'a' };
+static const symbol s_1[] = { 'e' };
+static const symbol s_2[] = { 'i' };
+static const symbol s_3[] = { 'o' };
+static const symbol s_4[] = { 'u' };
+static const symbol s_5[] = { 'y' };
+static const symbol s_6[] = { 'Y' };
+static const symbol s_7[] = { 'i' };
+static const symbol s_8[] = { 'I' };
+static const symbol s_9[] = { 'y' };
+static const symbol s_10[] = { 'Y' };
+static const symbol s_11[] = { 'y' };
+static const symbol s_12[] = { 'i' };
+static const symbol s_13[] = { 'e' };
+static const symbol s_14[] = { 'g', 'e', 'm' };
+static const symbol s_15[] = { 'h', 'e', 'i', 'd' };
+static const symbol s_16[] = { 'h', 'e', 'i', 'd' };
+static const symbol s_17[] = { 'c' };
+static const symbol s_18[] = { 'e', 'n' };
+static const symbol s_19[] = { 'i', 'g' };
+static const symbol s_20[] = { 'e' };
+static const symbol s_21[] = { 'e' };
+
+static int r_prelude(struct SN_env * z) {
+ int among_var;
+ { int c_test = z->c; /* test, line 42 */
+ while(1) { /* repeat, line 42 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 43 */
+ if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((340306450 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else
+ among_var = find_among(z, a_0, 11); /* substring, line 43 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 43 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_0); /* <-, line 45 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 47 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 49 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 51 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 53 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 54 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ z->c = c_test;
+ }
+ { int c_keep = z->c; /* try, line 57 */
+ z->bra = z->c; /* [, line 57 */
+ if (!(eq_s(z, 1, s_5))) { z->c = c_keep; goto lab1; }
+ z->ket = z->c; /* ], line 57 */
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 57 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ ;
+ }
+ while(1) { /* repeat, line 58 */
+ int c2 = z->c;
+ while(1) { /* goto, line 58 */
+ int c3 = z->c;
+ if (in_grouping(z, g_v, 97, 232, 0)) goto lab3;
+ z->bra = z->c; /* [, line 59 */
+ { int c4 = z->c; /* or, line 59 */
+ if (!(eq_s(z, 1, s_7))) goto lab5;
+ z->ket = z->c; /* ], line 59 */
+ if (in_grouping(z, g_v, 97, 232, 0)) goto lab5;
+ { int ret = slice_from_s(z, 1, s_8); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab5:
+ z->c = c4;
+ if (!(eq_s(z, 1, s_9))) goto lab3;
+ z->ket = z->c; /* ], line 60 */
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 60 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab4:
+ z->c = c3;
+ break;
+ lab3:
+ z->c = c3;
+ if (z->c >= z->l) goto lab2;
+ z->c++; /* goto, line 58 */
+ }
+ continue;
+ lab2:
+ z->c = c2;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { /* gopast */ /* grouping v, line 69 */
+ int ret = out_grouping(z, g_v, 97, 232, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 69 */
+ int ret = in_grouping(z, g_v, 97, 232, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 69 */
+ /* try, line 70 */
+ if (!(z->I[0] < 3)) goto lab0;
+ z->I[0] = 3;
+lab0:
+ { /* gopast */ /* grouping v, line 71 */
+ int ret = out_grouping(z, g_v, 97, 232, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 71 */
+ int ret = in_grouping(z, g_v, 97, 232, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 71 */
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 75 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 77 */
+ if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else
+ among_var = find_among(z, a_1, 3); /* substring, line 77 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 77 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_11); /* <-, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_12); /* <-, line 79 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 80 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_undouble(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 91 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_2, 3))) return 0; /* among, line 91 */
+ z->c = z->l - m_test;
+ }
+ z->ket = z->c; /* [, line 91 */
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 91 */
+ z->bra = z->c; /* ], line 91 */
+ { int ret = slice_del(z); /* delete, line 91 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_e_ending(struct SN_env * z) {
+ z->B[0] = 0; /* unset e_found, line 95 */
+ z->ket = z->c; /* [, line 96 */
+ if (!(eq_s_b(z, 1, s_13))) return 0;
+ z->bra = z->c; /* ], line 96 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 96 */
+ if (ret < 0) return ret;
+ }
+ { int m_test = z->l - z->c; /* test, line 96 */
+ if (out_grouping_b(z, g_v, 97, 232, 0)) return 0;
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 96 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set e_found, line 97 */
+ { int ret = r_undouble(z);
+ if (ret == 0) return 0; /* call undouble, line 98 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_en_ending(struct SN_env * z) {
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int m1 = z->l - z->c; (void)m1; /* and, line 102 */
+ if (out_grouping_b(z, g_v, 97, 232, 0)) return 0;
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* not, line 102 */
+ if (!(eq_s_b(z, 3, s_14))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m2;
+ }
+ }
+ { int ret = slice_del(z); /* delete, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_undouble(z);
+ if (ret == 0) return 0; /* call undouble, line 103 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ { int m1 = z->l - z->c; (void)m1; /* do, line 107 */
+ z->ket = z->c; /* [, line 108 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0;
+ among_var = find_among_b(z, a_3, 5); /* substring, line 108 */
+ if (!(among_var)) goto lab0;
+ z->bra = z->c; /* ], line 108 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = r_R1(z);
+ if (ret == 0) goto lab0; /* call R1, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 4, s_15); /* <-, line 110 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_en_ending(z);
+ if (ret == 0) goto lab0; /* call en_ending, line 113 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = r_R1(z);
+ if (ret == 0) goto lab0; /* call R1, line 116 */
+ if (ret < 0) return ret;
+ }
+ if (out_grouping_b(z, g_v_j, 97, 232, 0)) goto lab0;
+ { int ret = slice_del(z); /* delete, line 116 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ z->c = z->l - m1;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* do, line 120 */
+ { int ret = r_e_ending(z);
+ if (ret == 0) goto lab1; /* call e_ending, line 120 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 122 */
+ z->ket = z->c; /* [, line 122 */
+ if (!(eq_s_b(z, 4, s_16))) goto lab2;
+ z->bra = z->c; /* ], line 122 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab2; /* call R2, line 122 */
+ if (ret < 0) return ret;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* not, line 122 */
+ if (!(eq_s_b(z, 1, s_17))) goto lab3;
+ goto lab2;
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int ret = slice_del(z); /* delete, line 122 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 123 */
+ if (!(eq_s_b(z, 2, s_18))) goto lab2;
+ z->bra = z->c; /* ], line 123 */
+ { int ret = r_en_ending(z);
+ if (ret == 0) goto lab2; /* call en_ending, line 123 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 126 */
+ z->ket = z->c; /* [, line 127 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab4;
+ among_var = find_among_b(z, a_4, 6); /* substring, line 127 */
+ if (!(among_var)) goto lab4;
+ z->bra = z->c; /* ], line 127 */
+ switch(among_var) {
+ case 0: goto lab4;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 129 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 129 */
+ if (ret < 0) return ret;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* or, line 130 */
+ z->ket = z->c; /* [, line 130 */
+ if (!(eq_s_b(z, 2, s_19))) goto lab6;
+ z->bra = z->c; /* ], line 130 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab6; /* call R2, line 130 */
+ if (ret < 0) return ret;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* not, line 130 */
+ if (!(eq_s_b(z, 1, s_20))) goto lab7;
+ goto lab6;
+ lab7:
+ z->c = z->l - m7;
+ }
+ { int ret = slice_del(z); /* delete, line 130 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int ret = r_undouble(z);
+ if (ret == 0) goto lab4; /* call undouble, line 130 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 133 */
+ if (ret < 0) return ret;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* not, line 133 */
+ if (!(eq_s_b(z, 1, s_21))) goto lab8;
+ goto lab4;
+ lab8:
+ z->c = z->l - m8;
+ }
+ { int ret = slice_del(z); /* delete, line 133 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 136 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 136 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_e_ending(z);
+ if (ret == 0) goto lab4; /* call e_ending, line 136 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 139 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 139 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 142 */
+ if (ret < 0) return ret;
+ }
+ if (!(z->B[0])) goto lab4; /* Boolean test e_found, line 142 */
+ { int ret = slice_del(z); /* delete, line 142 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab4:
+ z->c = z->l - m5;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 146 */
+ if (out_grouping_b(z, g_v_I, 73, 232, 0)) goto lab9;
+ { int m_test = z->l - z->c; /* test, line 148 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab9;
+ if (!(find_among_b(z, a_5, 4))) goto lab9; /* among, line 149 */
+ if (out_grouping_b(z, g_v, 97, 232, 0)) goto lab9;
+ z->c = z->l - m_test;
+ }
+ z->ket = z->c; /* [, line 152 */
+ if (z->c <= z->lb) goto lab9;
+ z->c--; /* next, line 152 */
+ z->bra = z->c; /* ], line 152 */
+ { int ret = slice_del(z); /* delete, line 152 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m9;
+ }
+ return 1;
+}
+
+extern int dutch_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 159 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 159 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 160 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 160 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 161 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 162 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab2; /* call standard_suffix, line 162 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ z->c = z->lb;
+ { int c4 = z->c; /* do, line 163 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab3; /* call postlude, line 163 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = c4;
+ }
+ return 1;
+}
+
+extern struct SN_env * dutch_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); }
+
+extern void dutch_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c
new file mode 100644
index 00000000000..141c45dc275
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c
@@ -0,0 +1,1117 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int english_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_exception2(struct SN_env * z);
+static int r_exception1(struct SN_env * z);
+static int r_Step_5(struct SN_env * z);
+static int r_Step_4(struct SN_env * z);
+static int r_Step_3(struct SN_env * z);
+static int r_Step_2(struct SN_env * z);
+static int r_Step_1c(struct SN_env * z);
+static int r_Step_1b(struct SN_env * z);
+static int r_Step_1a(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_shortv(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * english_ISO_8859_1_create_env(void);
+extern void english_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[5] = { 'a', 'r', 's', 'e', 'n' };
+static const symbol s_0_1[6] = { 'c', 'o', 'm', 'm', 'u', 'n' };
+static const symbol s_0_2[5] = { 'g', 'e', 'n', 'e', 'r' };
+
+static const struct among a_0[3] =
+{
+/* 0 */ { 5, s_0_0, -1, -1, 0},
+/* 1 */ { 6, s_0_1, -1, -1, 0},
+/* 2 */ { 5, s_0_2, -1, -1, 0}
+};
+
+static const symbol s_1_0[1] = { '\'' };
+static const symbol s_1_1[3] = { '\'', 's', '\'' };
+static const symbol s_1_2[2] = { '\'', 's' };
+
+static const struct among a_1[3] =
+{
+/* 0 */ { 1, s_1_0, -1, 1, 0},
+/* 1 */ { 3, s_1_1, 0, 1, 0},
+/* 2 */ { 2, s_1_2, -1, 1, 0}
+};
+
+static const symbol s_2_0[3] = { 'i', 'e', 'd' };
+static const symbol s_2_1[1] = { 's' };
+static const symbol s_2_2[3] = { 'i', 'e', 's' };
+static const symbol s_2_3[4] = { 's', 's', 'e', 's' };
+static const symbol s_2_4[2] = { 's', 's' };
+static const symbol s_2_5[2] = { 'u', 's' };
+
+static const struct among a_2[6] =
+{
+/* 0 */ { 3, s_2_0, -1, 2, 0},
+/* 1 */ { 1, s_2_1, -1, 3, 0},
+/* 2 */ { 3, s_2_2, 1, 2, 0},
+/* 3 */ { 4, s_2_3, 1, 1, 0},
+/* 4 */ { 2, s_2_4, 1, -1, 0},
+/* 5 */ { 2, s_2_5, 1, -1, 0}
+};
+
+static const symbol s_3_1[2] = { 'b', 'b' };
+static const symbol s_3_2[2] = { 'd', 'd' };
+static const symbol s_3_3[2] = { 'f', 'f' };
+static const symbol s_3_4[2] = { 'g', 'g' };
+static const symbol s_3_5[2] = { 'b', 'l' };
+static const symbol s_3_6[2] = { 'm', 'm' };
+static const symbol s_3_7[2] = { 'n', 'n' };
+static const symbol s_3_8[2] = { 'p', 'p' };
+static const symbol s_3_9[2] = { 'r', 'r' };
+static const symbol s_3_10[2] = { 'a', 't' };
+static const symbol s_3_11[2] = { 't', 't' };
+static const symbol s_3_12[2] = { 'i', 'z' };
+
+static const struct among a_3[13] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 2, s_3_1, 0, 2, 0},
+/* 2 */ { 2, s_3_2, 0, 2, 0},
+/* 3 */ { 2, s_3_3, 0, 2, 0},
+/* 4 */ { 2, s_3_4, 0, 2, 0},
+/* 5 */ { 2, s_3_5, 0, 1, 0},
+/* 6 */ { 2, s_3_6, 0, 2, 0},
+/* 7 */ { 2, s_3_7, 0, 2, 0},
+/* 8 */ { 2, s_3_8, 0, 2, 0},
+/* 9 */ { 2, s_3_9, 0, 2, 0},
+/* 10 */ { 2, s_3_10, 0, 1, 0},
+/* 11 */ { 2, s_3_11, 0, 2, 0},
+/* 12 */ { 2, s_3_12, 0, 1, 0}
+};
+
+static const symbol s_4_0[2] = { 'e', 'd' };
+static const symbol s_4_1[3] = { 'e', 'e', 'd' };
+static const symbol s_4_2[3] = { 'i', 'n', 'g' };
+static const symbol s_4_3[4] = { 'e', 'd', 'l', 'y' };
+static const symbol s_4_4[5] = { 'e', 'e', 'd', 'l', 'y' };
+static const symbol s_4_5[5] = { 'i', 'n', 'g', 'l', 'y' };
+
+static const struct among a_4[6] =
+{
+/* 0 */ { 2, s_4_0, -1, 2, 0},
+/* 1 */ { 3, s_4_1, 0, 1, 0},
+/* 2 */ { 3, s_4_2, -1, 2, 0},
+/* 3 */ { 4, s_4_3, -1, 2, 0},
+/* 4 */ { 5, s_4_4, 3, 1, 0},
+/* 5 */ { 5, s_4_5, -1, 2, 0}
+};
+
+static const symbol s_5_0[4] = { 'a', 'n', 'c', 'i' };
+static const symbol s_5_1[4] = { 'e', 'n', 'c', 'i' };
+static const symbol s_5_2[3] = { 'o', 'g', 'i' };
+static const symbol s_5_3[2] = { 'l', 'i' };
+static const symbol s_5_4[3] = { 'b', 'l', 'i' };
+static const symbol s_5_5[4] = { 'a', 'b', 'l', 'i' };
+static const symbol s_5_6[4] = { 'a', 'l', 'l', 'i' };
+static const symbol s_5_7[5] = { 'f', 'u', 'l', 'l', 'i' };
+static const symbol s_5_8[6] = { 'l', 'e', 's', 's', 'l', 'i' };
+static const symbol s_5_9[5] = { 'o', 'u', 's', 'l', 'i' };
+static const symbol s_5_10[5] = { 'e', 'n', 't', 'l', 'i' };
+static const symbol s_5_11[5] = { 'a', 'l', 'i', 't', 'i' };
+static const symbol s_5_12[6] = { 'b', 'i', 'l', 'i', 't', 'i' };
+static const symbol s_5_13[5] = { 'i', 'v', 'i', 't', 'i' };
+static const symbol s_5_14[6] = { 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_5_15[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_5_16[5] = { 'a', 'l', 'i', 's', 'm' };
+static const symbol s_5_17[5] = { 'a', 't', 'i', 'o', 'n' };
+static const symbol s_5_18[7] = { 'i', 'z', 'a', 't', 'i', 'o', 'n' };
+static const symbol s_5_19[4] = { 'i', 'z', 'e', 'r' };
+static const symbol s_5_20[4] = { 'a', 't', 'o', 'r' };
+static const symbol s_5_21[7] = { 'i', 'v', 'e', 'n', 'e', 's', 's' };
+static const symbol s_5_22[7] = { 'f', 'u', 'l', 'n', 'e', 's', 's' };
+static const symbol s_5_23[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' };
+
+static const struct among a_5[24] =
+{
+/* 0 */ { 4, s_5_0, -1, 3, 0},
+/* 1 */ { 4, s_5_1, -1, 2, 0},
+/* 2 */ { 3, s_5_2, -1, 13, 0},
+/* 3 */ { 2, s_5_3, -1, 16, 0},
+/* 4 */ { 3, s_5_4, 3, 12, 0},
+/* 5 */ { 4, s_5_5, 4, 4, 0},
+/* 6 */ { 4, s_5_6, 3, 8, 0},
+/* 7 */ { 5, s_5_7, 3, 14, 0},
+/* 8 */ { 6, s_5_8, 3, 15, 0},
+/* 9 */ { 5, s_5_9, 3, 10, 0},
+/* 10 */ { 5, s_5_10, 3, 5, 0},
+/* 11 */ { 5, s_5_11, -1, 8, 0},
+/* 12 */ { 6, s_5_12, -1, 12, 0},
+/* 13 */ { 5, s_5_13, -1, 11, 0},
+/* 14 */ { 6, s_5_14, -1, 1, 0},
+/* 15 */ { 7, s_5_15, 14, 7, 0},
+/* 16 */ { 5, s_5_16, -1, 8, 0},
+/* 17 */ { 5, s_5_17, -1, 7, 0},
+/* 18 */ { 7, s_5_18, 17, 6, 0},
+/* 19 */ { 4, s_5_19, -1, 6, 0},
+/* 20 */ { 4, s_5_20, -1, 7, 0},
+/* 21 */ { 7, s_5_21, -1, 11, 0},
+/* 22 */ { 7, s_5_22, -1, 9, 0},
+/* 23 */ { 7, s_5_23, -1, 10, 0}
+};
+
+static const symbol s_6_0[5] = { 'i', 'c', 'a', 't', 'e' };
+static const symbol s_6_1[5] = { 'a', 't', 'i', 'v', 'e' };
+static const symbol s_6_2[5] = { 'a', 'l', 'i', 'z', 'e' };
+static const symbol s_6_3[5] = { 'i', 'c', 'i', 't', 'i' };
+static const symbol s_6_4[4] = { 'i', 'c', 'a', 'l' };
+static const symbol s_6_5[6] = { 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_6_6[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_6_7[3] = { 'f', 'u', 'l' };
+static const symbol s_6_8[4] = { 'n', 'e', 's', 's' };
+
+static const struct among a_6[9] =
+{
+/* 0 */ { 5, s_6_0, -1, 4, 0},
+/* 1 */ { 5, s_6_1, -1, 6, 0},
+/* 2 */ { 5, s_6_2, -1, 3, 0},
+/* 3 */ { 5, s_6_3, -1, 4, 0},
+/* 4 */ { 4, s_6_4, -1, 4, 0},
+/* 5 */ { 6, s_6_5, -1, 1, 0},
+/* 6 */ { 7, s_6_6, 5, 2, 0},
+/* 7 */ { 3, s_6_7, -1, 5, 0},
+/* 8 */ { 4, s_6_8, -1, 5, 0}
+};
+
+static const symbol s_7_0[2] = { 'i', 'c' };
+static const symbol s_7_1[4] = { 'a', 'n', 'c', 'e' };
+static const symbol s_7_2[4] = { 'e', 'n', 'c', 'e' };
+static const symbol s_7_3[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_7_4[4] = { 'i', 'b', 'l', 'e' };
+static const symbol s_7_5[3] = { 'a', 't', 'e' };
+static const symbol s_7_6[3] = { 'i', 'v', 'e' };
+static const symbol s_7_7[3] = { 'i', 'z', 'e' };
+static const symbol s_7_8[3] = { 'i', 't', 'i' };
+static const symbol s_7_9[2] = { 'a', 'l' };
+static const symbol s_7_10[3] = { 'i', 's', 'm' };
+static const symbol s_7_11[3] = { 'i', 'o', 'n' };
+static const symbol s_7_12[2] = { 'e', 'r' };
+static const symbol s_7_13[3] = { 'o', 'u', 's' };
+static const symbol s_7_14[3] = { 'a', 'n', 't' };
+static const symbol s_7_15[3] = { 'e', 'n', 't' };
+static const symbol s_7_16[4] = { 'm', 'e', 'n', 't' };
+static const symbol s_7_17[5] = { 'e', 'm', 'e', 'n', 't' };
+
+static const struct among a_7[18] =
+{
+/* 0 */ { 2, s_7_0, -1, 1, 0},
+/* 1 */ { 4, s_7_1, -1, 1, 0},
+/* 2 */ { 4, s_7_2, -1, 1, 0},
+/* 3 */ { 4, s_7_3, -1, 1, 0},
+/* 4 */ { 4, s_7_4, -1, 1, 0},
+/* 5 */ { 3, s_7_5, -1, 1, 0},
+/* 6 */ { 3, s_7_6, -1, 1, 0},
+/* 7 */ { 3, s_7_7, -1, 1, 0},
+/* 8 */ { 3, s_7_8, -1, 1, 0},
+/* 9 */ { 2, s_7_9, -1, 1, 0},
+/* 10 */ { 3, s_7_10, -1, 1, 0},
+/* 11 */ { 3, s_7_11, -1, 2, 0},
+/* 12 */ { 2, s_7_12, -1, 1, 0},
+/* 13 */ { 3, s_7_13, -1, 1, 0},
+/* 14 */ { 3, s_7_14, -1, 1, 0},
+/* 15 */ { 3, s_7_15, -1, 1, 0},
+/* 16 */ { 4, s_7_16, 15, 1, 0},
+/* 17 */ { 5, s_7_17, 16, 1, 0}
+};
+
+static const symbol s_8_0[1] = { 'e' };
+static const symbol s_8_1[1] = { 'l' };
+
+static const struct among a_8[2] =
+{
+/* 0 */ { 1, s_8_0, -1, 1, 0},
+/* 1 */ { 1, s_8_1, -1, 2, 0}
+};
+
+static const symbol s_9_0[7] = { 's', 'u', 'c', 'c', 'e', 'e', 'd' };
+static const symbol s_9_1[7] = { 'p', 'r', 'o', 'c', 'e', 'e', 'd' };
+static const symbol s_9_2[6] = { 'e', 'x', 'c', 'e', 'e', 'd' };
+static const symbol s_9_3[7] = { 'c', 'a', 'n', 'n', 'i', 'n', 'g' };
+static const symbol s_9_4[6] = { 'i', 'n', 'n', 'i', 'n', 'g' };
+static const symbol s_9_5[7] = { 'e', 'a', 'r', 'r', 'i', 'n', 'g' };
+static const symbol s_9_6[7] = { 'h', 'e', 'r', 'r', 'i', 'n', 'g' };
+static const symbol s_9_7[6] = { 'o', 'u', 't', 'i', 'n', 'g' };
+
+static const struct among a_9[8] =
+{
+/* 0 */ { 7, s_9_0, -1, -1, 0},
+/* 1 */ { 7, s_9_1, -1, -1, 0},
+/* 2 */ { 6, s_9_2, -1, -1, 0},
+/* 3 */ { 7, s_9_3, -1, -1, 0},
+/* 4 */ { 6, s_9_4, -1, -1, 0},
+/* 5 */ { 7, s_9_5, -1, -1, 0},
+/* 6 */ { 7, s_9_6, -1, -1, 0},
+/* 7 */ { 6, s_9_7, -1, -1, 0}
+};
+
+static const symbol s_10_0[5] = { 'a', 'n', 'd', 'e', 's' };
+static const symbol s_10_1[5] = { 'a', 't', 'l', 'a', 's' };
+static const symbol s_10_2[4] = { 'b', 'i', 'a', 's' };
+static const symbol s_10_3[6] = { 'c', 'o', 's', 'm', 'o', 's' };
+static const symbol s_10_4[5] = { 'd', 'y', 'i', 'n', 'g' };
+static const symbol s_10_5[5] = { 'e', 'a', 'r', 'l', 'y' };
+static const symbol s_10_6[6] = { 'g', 'e', 'n', 't', 'l', 'y' };
+static const symbol s_10_7[4] = { 'h', 'o', 'w', 'e' };
+static const symbol s_10_8[4] = { 'i', 'd', 'l', 'y' };
+static const symbol s_10_9[5] = { 'l', 'y', 'i', 'n', 'g' };
+static const symbol s_10_10[4] = { 'n', 'e', 'w', 's' };
+static const symbol s_10_11[4] = { 'o', 'n', 'l', 'y' };
+static const symbol s_10_12[6] = { 's', 'i', 'n', 'g', 'l', 'y' };
+static const symbol s_10_13[5] = { 's', 'k', 'i', 'e', 's' };
+static const symbol s_10_14[4] = { 's', 'k', 'i', 's' };
+static const symbol s_10_15[3] = { 's', 'k', 'y' };
+static const symbol s_10_16[5] = { 't', 'y', 'i', 'n', 'g' };
+static const symbol s_10_17[4] = { 'u', 'g', 'l', 'y' };
+
+static const struct among a_10[18] =
+{
+/* 0 */ { 5, s_10_0, -1, -1, 0},
+/* 1 */ { 5, s_10_1, -1, -1, 0},
+/* 2 */ { 4, s_10_2, -1, -1, 0},
+/* 3 */ { 6, s_10_3, -1, -1, 0},
+/* 4 */ { 5, s_10_4, -1, 3, 0},
+/* 5 */ { 5, s_10_5, -1, 9, 0},
+/* 6 */ { 6, s_10_6, -1, 7, 0},
+/* 7 */ { 4, s_10_7, -1, -1, 0},
+/* 8 */ { 4, s_10_8, -1, 6, 0},
+/* 9 */ { 5, s_10_9, -1, 4, 0},
+/* 10 */ { 4, s_10_10, -1, -1, 0},
+/* 11 */ { 4, s_10_11, -1, 10, 0},
+/* 12 */ { 6, s_10_12, -1, 11, 0},
+/* 13 */ { 5, s_10_13, -1, 2, 0},
+/* 14 */ { 4, s_10_14, -1, 1, 0},
+/* 15 */ { 3, s_10_15, -1, -1, 0},
+/* 16 */ { 5, s_10_16, -1, 5, 0},
+/* 17 */ { 4, s_10_17, -1, 8, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1 };
+
+static const unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 };
+
+static const unsigned char g_valid_LI[] = { 55, 141, 2 };
+
+static const symbol s_0[] = { '\'' };
+static const symbol s_1[] = { 'y' };
+static const symbol s_2[] = { 'Y' };
+static const symbol s_3[] = { 'y' };
+static const symbol s_4[] = { 'Y' };
+static const symbol s_5[] = { 's', 's' };
+static const symbol s_6[] = { 'i' };
+static const symbol s_7[] = { 'i', 'e' };
+static const symbol s_8[] = { 'e', 'e' };
+static const symbol s_9[] = { 'e' };
+static const symbol s_10[] = { 'e' };
+static const symbol s_11[] = { 'y' };
+static const symbol s_12[] = { 'Y' };
+static const symbol s_13[] = { 'i' };
+static const symbol s_14[] = { 't', 'i', 'o', 'n' };
+static const symbol s_15[] = { 'e', 'n', 'c', 'e' };
+static const symbol s_16[] = { 'a', 'n', 'c', 'e' };
+static const symbol s_17[] = { 'a', 'b', 'l', 'e' };
+static const symbol s_18[] = { 'e', 'n', 't' };
+static const symbol s_19[] = { 'i', 'z', 'e' };
+static const symbol s_20[] = { 'a', 't', 'e' };
+static const symbol s_21[] = { 'a', 'l' };
+static const symbol s_22[] = { 'f', 'u', 'l' };
+static const symbol s_23[] = { 'o', 'u', 's' };
+static const symbol s_24[] = { 'i', 'v', 'e' };
+static const symbol s_25[] = { 'b', 'l', 'e' };
+static const symbol s_26[] = { 'l' };
+static const symbol s_27[] = { 'o', 'g' };
+static const symbol s_28[] = { 'f', 'u', 'l' };
+static const symbol s_29[] = { 'l', 'e', 's', 's' };
+static const symbol s_30[] = { 't', 'i', 'o', 'n' };
+static const symbol s_31[] = { 'a', 't', 'e' };
+static const symbol s_32[] = { 'a', 'l' };
+static const symbol s_33[] = { 'i', 'c' };
+static const symbol s_34[] = { 's' };
+static const symbol s_35[] = { 't' };
+static const symbol s_36[] = { 'l' };
+static const symbol s_37[] = { 's', 'k', 'i' };
+static const symbol s_38[] = { 's', 'k', 'y' };
+static const symbol s_39[] = { 'd', 'i', 'e' };
+static const symbol s_40[] = { 'l', 'i', 'e' };
+static const symbol s_41[] = { 't', 'i', 'e' };
+static const symbol s_42[] = { 'i', 'd', 'l' };
+static const symbol s_43[] = { 'g', 'e', 'n', 't', 'l' };
+static const symbol s_44[] = { 'u', 'g', 'l', 'i' };
+static const symbol s_45[] = { 'e', 'a', 'r', 'l', 'i' };
+static const symbol s_46[] = { 'o', 'n', 'l', 'i' };
+static const symbol s_47[] = { 's', 'i', 'n', 'g', 'l' };
+static const symbol s_48[] = { 'Y' };
+static const symbol s_49[] = { 'y' };
+
+static int r_prelude(struct SN_env * z) {
+ z->B[0] = 0; /* unset Y_found, line 26 */
+ { int c1 = z->c; /* do, line 27 */
+ z->bra = z->c; /* [, line 27 */
+ if (!(eq_s(z, 1, s_0))) goto lab0;
+ z->ket = z->c; /* ], line 27 */
+ { int ret = slice_del(z); /* delete, line 27 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 28 */
+ z->bra = z->c; /* [, line 28 */
+ if (!(eq_s(z, 1, s_1))) goto lab1;
+ z->ket = z->c; /* ], line 28 */
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 28 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set Y_found, line 28 */
+ lab1:
+ z->c = c2;
+ }
+ { int c3 = z->c; /* do, line 29 */
+ while(1) { /* repeat, line 29 */
+ int c4 = z->c;
+ while(1) { /* goto, line 29 */
+ int c5 = z->c;
+ if (in_grouping(z, g_v, 97, 121, 0)) goto lab4;
+ z->bra = z->c; /* [, line 29 */
+ if (!(eq_s(z, 1, s_3))) goto lab4;
+ z->ket = z->c; /* ], line 29 */
+ z->c = c5;
+ break;
+ lab4:
+ z->c = c5;
+ if (z->c >= z->l) goto lab3;
+ z->c++; /* goto, line 29 */
+ }
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 29 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set Y_found, line 29 */
+ continue;
+ lab3:
+ z->c = c4;
+ break;
+ }
+ z->c = c3;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { int c1 = z->c; /* do, line 35 */
+ { int c2 = z->c; /* or, line 41 */
+ if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2;
+ if (!(find_among(z, a_0, 3))) goto lab2; /* among, line 36 */
+ goto lab1;
+ lab2:
+ z->c = c2;
+ { /* gopast */ /* grouping v, line 41 */
+ int ret = out_grouping(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 41 */
+ int ret = in_grouping(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark p1, line 42 */
+ { /* gopast */ /* grouping v, line 43 */
+ int ret = out_grouping(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 43 */
+ int ret = in_grouping(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 43 */
+ lab0:
+ z->c = c1;
+ }
+ return 1;
+}
+
+static int r_shortv(struct SN_env * z) {
+ { int m1 = z->l - z->c; (void)m1; /* or, line 51 */
+ if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) goto lab1;
+ if (in_grouping_b(z, g_v, 97, 121, 0)) goto lab1;
+ if (out_grouping_b(z, g_v, 97, 121, 0)) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (out_grouping_b(z, g_v, 97, 121, 0)) return 0;
+ if (in_grouping_b(z, g_v, 97, 121, 0)) return 0;
+ if (z->c > z->lb) return 0; /* atlimit, line 52 */
+ }
+lab0:
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_Step_1a(struct SN_env * z) {
+ int among_var;
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 59 */
+ z->ket = z->c; /* [, line 60 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m_keep; goto lab0; }
+ among_var = find_among_b(z, a_1, 3); /* substring, line 60 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 60 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab0; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 62 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ ;
+ }
+ z->ket = z->c; /* [, line 65 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0;
+ among_var = find_among_b(z, a_2, 6); /* substring, line 65 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 65 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_5); /* <-, line 66 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 68 */
+ { int ret = z->c - 2;
+ if (z->lb > ret || ret > z->l) goto lab2;
+ z->c = ret; /* hop, line 68 */
+ }
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 68 */
+ if (ret < 0) return ret;
+ }
+ goto lab1;
+ lab2:
+ z->c = z->l - m1;
+ { int ret = slice_from_s(z, 2, s_7); /* <-, line 68 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab1:
+ break;
+ case 3:
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 69 */
+ { /* gopast */ /* grouping v, line 69 */
+ int ret = out_grouping_b(z, g_v, 97, 121, 1);
+ if (ret < 0) return 0;
+ z->c -= ret;
+ }
+ { int ret = slice_del(z); /* delete, line 69 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_1b(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 75 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_4, 6); /* substring, line 75 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 75 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 77 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 2, s_8); /* <-, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m_test = z->l - z->c; /* test, line 80 */
+ { /* gopast */ /* grouping v, line 80 */
+ int ret = out_grouping_b(z, g_v, 97, 121, 1);
+ if (ret < 0) return 0;
+ z->c -= ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 80 */
+ if (ret < 0) return ret;
+ }
+ { int m_test = z->l - z->c; /* test, line 81 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else
+ among_var = find_among_b(z, a_3, 13); /* substring, line 81 */
+ if (!(among_var)) return 0;
+ z->c = z->l - m_test;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_9); /* <+, line 83 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ z->ket = z->c; /* [, line 86 */
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 86 */
+ z->bra = z->c; /* ], line 86 */
+ { int ret = slice_del(z); /* delete, line 86 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c != z->I[0]) return 0; /* atmark, line 87 */
+ { int m_test = z->l - z->c; /* test, line 87 */
+ { int ret = r_shortv(z);
+ if (ret == 0) return 0; /* call shortv, line 87 */
+ if (ret < 0) return ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_10); /* <+, line 87 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_1c(struct SN_env * z) {
+ z->ket = z->c; /* [, line 94 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 94 */
+ if (!(eq_s_b(z, 1, s_11))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_12))) return 0;
+ }
+lab0:
+ z->bra = z->c; /* ], line 94 */
+ if (out_grouping_b(z, g_v, 97, 121, 0)) return 0;
+ { int m2 = z->l - z->c; (void)m2; /* not, line 95 */
+ if (z->c > z->lb) goto lab2; /* atlimit, line 95 */
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 96 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_Step_2(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 100 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_5, 24); /* substring, line 100 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 100 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 100 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 4, s_14); /* <-, line 101 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 4, s_15); /* <-, line 102 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 4, s_16); /* <-, line 103 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 4, s_17); /* <-, line 104 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 3, s_18); /* <-, line 105 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 3, s_19); /* <-, line 107 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 3, s_20); /* <-, line 109 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 2, s_21); /* <-, line 111 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_from_s(z, 3, s_22); /* <-, line 112 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_from_s(z, 3, s_23); /* <-, line 114 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_from_s(z, 3, s_24); /* <-, line 116 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 12:
+ { int ret = slice_from_s(z, 3, s_25); /* <-, line 118 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ if (!(eq_s_b(z, 1, s_26))) return 0;
+ { int ret = slice_from_s(z, 2, s_27); /* <-, line 119 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 14:
+ { int ret = slice_from_s(z, 3, s_28); /* <-, line 120 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 15:
+ { int ret = slice_from_s(z, 4, s_29); /* <-, line 121 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 16:
+ if (in_grouping_b(z, g_valid_LI, 99, 116, 0)) return 0;
+ { int ret = slice_del(z); /* delete, line 122 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_3(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 127 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_6, 9); /* substring, line 127 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 127 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 127 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 4, s_30); /* <-, line 128 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 3, s_31); /* <-, line 129 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 2, s_32); /* <-, line 130 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 2, s_33); /* <-, line 132 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 136 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 136 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_4(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 141 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_7, 18); /* substring, line 141 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 141 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 141 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 144 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 145 */
+ if (!(eq_s_b(z, 1, s_34))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_35))) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 145 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_5(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 150 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0;
+ among_var = find_among_b(z, a_8, 2); /* substring, line 150 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 150 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 151 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab1; /* call R2, line 151 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 151 */
+ if (ret < 0) return ret;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* not, line 151 */
+ { int ret = r_shortv(z);
+ if (ret == 0) goto lab2; /* call shortv, line 151 */
+ if (ret < 0) return ret;
+ }
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 151 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 152 */
+ if (ret < 0) return ret;
+ }
+ if (!(eq_s_b(z, 1, s_36))) return 0;
+ { int ret = slice_del(z); /* delete, line 152 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_exception2(struct SN_env * z) {
+ z->ket = z->c; /* [, line 158 */
+ if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0;
+ if (!(find_among_b(z, a_9, 8))) return 0; /* substring, line 158 */
+ z->bra = z->c; /* ], line 158 */
+ if (z->c > z->lb) return 0; /* atlimit, line 158 */
+ return 1;
+}
+
+static int r_exception1(struct SN_env * z) {
+ int among_var;
+ z->bra = z->c; /* [, line 170 */
+ if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0;
+ among_var = find_among(z, a_10, 18); /* substring, line 170 */
+ if (!(among_var)) return 0;
+ z->ket = z->c; /* ], line 170 */
+ if (z->c < z->l) return 0; /* atlimit, line 170 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 3, s_37); /* <-, line 174 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 3, s_38); /* <-, line 175 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 3, s_39); /* <-, line 176 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 3, s_40); /* <-, line 177 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 3, s_41); /* <-, line 178 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 3, s_42); /* <-, line 182 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 5, s_43); /* <-, line 183 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 4, s_44); /* <-, line 184 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_from_s(z, 5, s_45); /* <-, line 185 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_from_s(z, 4, s_46); /* <-, line 186 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_from_s(z, 5, s_47); /* <-, line 187 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ if (!(z->B[0])) return 0; /* Boolean test Y_found, line 203 */
+ while(1) { /* repeat, line 203 */
+ int c1 = z->c;
+ while(1) { /* goto, line 203 */
+ int c2 = z->c;
+ z->bra = z->c; /* [, line 203 */
+ if (!(eq_s(z, 1, s_48))) goto lab1;
+ z->ket = z->c; /* ], line 203 */
+ z->c = c2;
+ break;
+ lab1:
+ z->c = c2;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* goto, line 203 */
+ }
+ { int ret = slice_from_s(z, 1, s_49); /* <-, line 203 */
+ if (ret < 0) return ret;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+extern int english_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* or, line 207 */
+ { int ret = r_exception1(z);
+ if (ret == 0) goto lab1; /* call exception1, line 207 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab1:
+ z->c = c1;
+ { int c2 = z->c; /* not, line 208 */
+ { int ret = z->c + 3;
+ if (0 > ret || ret > z->l) goto lab3;
+ z->c = ret; /* hop, line 208 */
+ }
+ goto lab2;
+ lab3:
+ z->c = c2;
+ }
+ goto lab0;
+ lab2:
+ z->c = c1;
+ { int c3 = z->c; /* do, line 209 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab4; /* call prelude, line 209 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ z->c = c3;
+ }
+ { int c4 = z->c; /* do, line 210 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab5; /* call mark_regions, line 210 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ z->c = c4;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 211 */
+
+ { int m5 = z->l - z->c; (void)m5; /* do, line 213 */
+ { int ret = r_Step_1a(z);
+ if (ret == 0) goto lab6; /* call Step_1a, line 213 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m5;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* or, line 215 */
+ { int ret = r_exception2(z);
+ if (ret == 0) goto lab8; /* call exception2, line 215 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab8:
+ z->c = z->l - m6;
+ { int m7 = z->l - z->c; (void)m7; /* do, line 217 */
+ { int ret = r_Step_1b(z);
+ if (ret == 0) goto lab9; /* call Step_1b, line 217 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m7;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 218 */
+ { int ret = r_Step_1c(z);
+ if (ret == 0) goto lab10; /* call Step_1c, line 218 */
+ if (ret < 0) return ret;
+ }
+ lab10:
+ z->c = z->l - m8;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 220 */
+ { int ret = r_Step_2(z);
+ if (ret == 0) goto lab11; /* call Step_2, line 220 */
+ if (ret < 0) return ret;
+ }
+ lab11:
+ z->c = z->l - m9;
+ }
+ { int m10 = z->l - z->c; (void)m10; /* do, line 221 */
+ { int ret = r_Step_3(z);
+ if (ret == 0) goto lab12; /* call Step_3, line 221 */
+ if (ret < 0) return ret;
+ }
+ lab12:
+ z->c = z->l - m10;
+ }
+ { int m11 = z->l - z->c; (void)m11; /* do, line 222 */
+ { int ret = r_Step_4(z);
+ if (ret == 0) goto lab13; /* call Step_4, line 222 */
+ if (ret < 0) return ret;
+ }
+ lab13:
+ z->c = z->l - m11;
+ }
+ { int m12 = z->l - z->c; (void)m12; /* do, line 224 */
+ { int ret = r_Step_5(z);
+ if (ret == 0) goto lab14; /* call Step_5, line 224 */
+ if (ret < 0) return ret;
+ }
+ lab14:
+ z->c = z->l - m12;
+ }
+ }
+ lab7:
+ z->c = z->lb;
+ { int c13 = z->c; /* do, line 227 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab15; /* call postlude, line 227 */
+ if (ret < 0) return ret;
+ }
+ lab15:
+ z->c = c13;
+ }
+ }
+lab0:
+ return 1;
+}
+
+extern struct SN_env * english_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); }
+
+extern void english_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c
new file mode 100644
index 00000000000..9621771d282
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c
@@ -0,0 +1,762 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int finnish_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_tidy(struct SN_env * z);
+static int r_other_endings(struct SN_env * z);
+static int r_t_plural(struct SN_env * z);
+static int r_i_plural(struct SN_env * z);
+static int r_case_ending(struct SN_env * z);
+static int r_VI(struct SN_env * z);
+static int r_LONG(struct SN_env * z);
+static int r_possessive(struct SN_env * z);
+static int r_particle_etc(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * finnish_ISO_8859_1_create_env(void);
+extern void finnish_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[2] = { 'p', 'a' };
+static const symbol s_0_1[3] = { 's', 't', 'i' };
+static const symbol s_0_2[4] = { 'k', 'a', 'a', 'n' };
+static const symbol s_0_3[3] = { 'h', 'a', 'n' };
+static const symbol s_0_4[3] = { 'k', 'i', 'n' };
+static const symbol s_0_5[3] = { 'h', 0xE4, 'n' };
+static const symbol s_0_6[4] = { 'k', 0xE4, 0xE4, 'n' };
+static const symbol s_0_7[2] = { 'k', 'o' };
+static const symbol s_0_8[2] = { 'p', 0xE4 };
+static const symbol s_0_9[2] = { 'k', 0xF6 };
+
+static const struct among a_0[10] =
+{
+/* 0 */ { 2, s_0_0, -1, 1, 0},
+/* 1 */ { 3, s_0_1, -1, 2, 0},
+/* 2 */ { 4, s_0_2, -1, 1, 0},
+/* 3 */ { 3, s_0_3, -1, 1, 0},
+/* 4 */ { 3, s_0_4, -1, 1, 0},
+/* 5 */ { 3, s_0_5, -1, 1, 0},
+/* 6 */ { 4, s_0_6, -1, 1, 0},
+/* 7 */ { 2, s_0_7, -1, 1, 0},
+/* 8 */ { 2, s_0_8, -1, 1, 0},
+/* 9 */ { 2, s_0_9, -1, 1, 0}
+};
+
+static const symbol s_1_0[3] = { 'l', 'l', 'a' };
+static const symbol s_1_1[2] = { 'n', 'a' };
+static const symbol s_1_2[3] = { 's', 's', 'a' };
+static const symbol s_1_3[2] = { 't', 'a' };
+static const symbol s_1_4[3] = { 'l', 't', 'a' };
+static const symbol s_1_5[3] = { 's', 't', 'a' };
+
+static const struct among a_1[6] =
+{
+/* 0 */ { 3, s_1_0, -1, -1, 0},
+/* 1 */ { 2, s_1_1, -1, -1, 0},
+/* 2 */ { 3, s_1_2, -1, -1, 0},
+/* 3 */ { 2, s_1_3, -1, -1, 0},
+/* 4 */ { 3, s_1_4, 3, -1, 0},
+/* 5 */ { 3, s_1_5, 3, -1, 0}
+};
+
+static const symbol s_2_0[3] = { 'l', 'l', 0xE4 };
+static const symbol s_2_1[2] = { 'n', 0xE4 };
+static const symbol s_2_2[3] = { 's', 's', 0xE4 };
+static const symbol s_2_3[2] = { 't', 0xE4 };
+static const symbol s_2_4[3] = { 'l', 't', 0xE4 };
+static const symbol s_2_5[3] = { 's', 't', 0xE4 };
+
+static const struct among a_2[6] =
+{
+/* 0 */ { 3, s_2_0, -1, -1, 0},
+/* 1 */ { 2, s_2_1, -1, -1, 0},
+/* 2 */ { 3, s_2_2, -1, -1, 0},
+/* 3 */ { 2, s_2_3, -1, -1, 0},
+/* 4 */ { 3, s_2_4, 3, -1, 0},
+/* 5 */ { 3, s_2_5, 3, -1, 0}
+};
+
+static const symbol s_3_0[3] = { 'l', 'l', 'e' };
+static const symbol s_3_1[3] = { 'i', 'n', 'e' };
+
+static const struct among a_3[2] =
+{
+/* 0 */ { 3, s_3_0, -1, -1, 0},
+/* 1 */ { 3, s_3_1, -1, -1, 0}
+};
+
+static const symbol s_4_0[3] = { 'n', 's', 'a' };
+static const symbol s_4_1[3] = { 'm', 'm', 'e' };
+static const symbol s_4_2[3] = { 'n', 'n', 'e' };
+static const symbol s_4_3[2] = { 'n', 'i' };
+static const symbol s_4_4[2] = { 's', 'i' };
+static const symbol s_4_5[2] = { 'a', 'n' };
+static const symbol s_4_6[2] = { 'e', 'n' };
+static const symbol s_4_7[2] = { 0xE4, 'n' };
+static const symbol s_4_8[3] = { 'n', 's', 0xE4 };
+
+static const struct among a_4[9] =
+{
+/* 0 */ { 3, s_4_0, -1, 3, 0},
+/* 1 */ { 3, s_4_1, -1, 3, 0},
+/* 2 */ { 3, s_4_2, -1, 3, 0},
+/* 3 */ { 2, s_4_3, -1, 2, 0},
+/* 4 */ { 2, s_4_4, -1, 1, 0},
+/* 5 */ { 2, s_4_5, -1, 4, 0},
+/* 6 */ { 2, s_4_6, -1, 6, 0},
+/* 7 */ { 2, s_4_7, -1, 5, 0},
+/* 8 */ { 3, s_4_8, -1, 3, 0}
+};
+
+static const symbol s_5_0[2] = { 'a', 'a' };
+static const symbol s_5_1[2] = { 'e', 'e' };
+static const symbol s_5_2[2] = { 'i', 'i' };
+static const symbol s_5_3[2] = { 'o', 'o' };
+static const symbol s_5_4[2] = { 'u', 'u' };
+static const symbol s_5_5[2] = { 0xE4, 0xE4 };
+static const symbol s_5_6[2] = { 0xF6, 0xF6 };
+
+static const struct among a_5[7] =
+{
+/* 0 */ { 2, s_5_0, -1, -1, 0},
+/* 1 */ { 2, s_5_1, -1, -1, 0},
+/* 2 */ { 2, s_5_2, -1, -1, 0},
+/* 3 */ { 2, s_5_3, -1, -1, 0},
+/* 4 */ { 2, s_5_4, -1, -1, 0},
+/* 5 */ { 2, s_5_5, -1, -1, 0},
+/* 6 */ { 2, s_5_6, -1, -1, 0}
+};
+
+static const symbol s_6_0[1] = { 'a' };
+static const symbol s_6_1[3] = { 'l', 'l', 'a' };
+static const symbol s_6_2[2] = { 'n', 'a' };
+static const symbol s_6_3[3] = { 's', 's', 'a' };
+static const symbol s_6_4[2] = { 't', 'a' };
+static const symbol s_6_5[3] = { 'l', 't', 'a' };
+static const symbol s_6_6[3] = { 's', 't', 'a' };
+static const symbol s_6_7[3] = { 't', 't', 'a' };
+static const symbol s_6_8[3] = { 'l', 'l', 'e' };
+static const symbol s_6_9[3] = { 'i', 'n', 'e' };
+static const symbol s_6_10[3] = { 'k', 's', 'i' };
+static const symbol s_6_11[1] = { 'n' };
+static const symbol s_6_12[3] = { 'h', 'a', 'n' };
+static const symbol s_6_13[3] = { 'd', 'e', 'n' };
+static const symbol s_6_14[4] = { 's', 'e', 'e', 'n' };
+static const symbol s_6_15[3] = { 'h', 'e', 'n' };
+static const symbol s_6_16[4] = { 't', 't', 'e', 'n' };
+static const symbol s_6_17[3] = { 'h', 'i', 'n' };
+static const symbol s_6_18[4] = { 's', 'i', 'i', 'n' };
+static const symbol s_6_19[3] = { 'h', 'o', 'n' };
+static const symbol s_6_20[3] = { 'h', 0xE4, 'n' };
+static const symbol s_6_21[3] = { 'h', 0xF6, 'n' };
+static const symbol s_6_22[1] = { 0xE4 };
+static const symbol s_6_23[3] = { 'l', 'l', 0xE4 };
+static const symbol s_6_24[2] = { 'n', 0xE4 };
+static const symbol s_6_25[3] = { 's', 's', 0xE4 };
+static const symbol s_6_26[2] = { 't', 0xE4 };
+static const symbol s_6_27[3] = { 'l', 't', 0xE4 };
+static const symbol s_6_28[3] = { 's', 't', 0xE4 };
+static const symbol s_6_29[3] = { 't', 't', 0xE4 };
+
+static const struct among a_6[30] =
+{
+/* 0 */ { 1, s_6_0, -1, 8, 0},
+/* 1 */ { 3, s_6_1, 0, -1, 0},
+/* 2 */ { 2, s_6_2, 0, -1, 0},
+/* 3 */ { 3, s_6_3, 0, -1, 0},
+/* 4 */ { 2, s_6_4, 0, -1, 0},
+/* 5 */ { 3, s_6_5, 4, -1, 0},
+/* 6 */ { 3, s_6_6, 4, -1, 0},
+/* 7 */ { 3, s_6_7, 4, 9, 0},
+/* 8 */ { 3, s_6_8, -1, -1, 0},
+/* 9 */ { 3, s_6_9, -1, -1, 0},
+/* 10 */ { 3, s_6_10, -1, -1, 0},
+/* 11 */ { 1, s_6_11, -1, 7, 0},
+/* 12 */ { 3, s_6_12, 11, 1, 0},
+/* 13 */ { 3, s_6_13, 11, -1, r_VI},
+/* 14 */ { 4, s_6_14, 11, -1, r_LONG},
+/* 15 */ { 3, s_6_15, 11, 2, 0},
+/* 16 */ { 4, s_6_16, 11, -1, r_VI},
+/* 17 */ { 3, s_6_17, 11, 3, 0},
+/* 18 */ { 4, s_6_18, 11, -1, r_VI},
+/* 19 */ { 3, s_6_19, 11, 4, 0},
+/* 20 */ { 3, s_6_20, 11, 5, 0},
+/* 21 */ { 3, s_6_21, 11, 6, 0},
+/* 22 */ { 1, s_6_22, -1, 8, 0},
+/* 23 */ { 3, s_6_23, 22, -1, 0},
+/* 24 */ { 2, s_6_24, 22, -1, 0},
+/* 25 */ { 3, s_6_25, 22, -1, 0},
+/* 26 */ { 2, s_6_26, 22, -1, 0},
+/* 27 */ { 3, s_6_27, 26, -1, 0},
+/* 28 */ { 3, s_6_28, 26, -1, 0},
+/* 29 */ { 3, s_6_29, 26, 9, 0}
+};
+
+static const symbol s_7_0[3] = { 'e', 'j', 'a' };
+static const symbol s_7_1[3] = { 'm', 'm', 'a' };
+static const symbol s_7_2[4] = { 'i', 'm', 'm', 'a' };
+static const symbol s_7_3[3] = { 'm', 'p', 'a' };
+static const symbol s_7_4[4] = { 'i', 'm', 'p', 'a' };
+static const symbol s_7_5[3] = { 'm', 'm', 'i' };
+static const symbol s_7_6[4] = { 'i', 'm', 'm', 'i' };
+static const symbol s_7_7[3] = { 'm', 'p', 'i' };
+static const symbol s_7_8[4] = { 'i', 'm', 'p', 'i' };
+static const symbol s_7_9[3] = { 'e', 'j', 0xE4 };
+static const symbol s_7_10[3] = { 'm', 'm', 0xE4 };
+static const symbol s_7_11[4] = { 'i', 'm', 'm', 0xE4 };
+static const symbol s_7_12[3] = { 'm', 'p', 0xE4 };
+static const symbol s_7_13[4] = { 'i', 'm', 'p', 0xE4 };
+
+static const struct among a_7[14] =
+{
+/* 0 */ { 3, s_7_0, -1, -1, 0},
+/* 1 */ { 3, s_7_1, -1, 1, 0},
+/* 2 */ { 4, s_7_2, 1, -1, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0},
+/* 4 */ { 4, s_7_4, 3, -1, 0},
+/* 5 */ { 3, s_7_5, -1, 1, 0},
+/* 6 */ { 4, s_7_6, 5, -1, 0},
+/* 7 */ { 3, s_7_7, -1, 1, 0},
+/* 8 */ { 4, s_7_8, 7, -1, 0},
+/* 9 */ { 3, s_7_9, -1, -1, 0},
+/* 10 */ { 3, s_7_10, -1, 1, 0},
+/* 11 */ { 4, s_7_11, 10, -1, 0},
+/* 12 */ { 3, s_7_12, -1, 1, 0},
+/* 13 */ { 4, s_7_13, 12, -1, 0}
+};
+
+static const symbol s_8_0[1] = { 'i' };
+static const symbol s_8_1[1] = { 'j' };
+
+static const struct among a_8[2] =
+{
+/* 0 */ { 1, s_8_0, -1, -1, 0},
+/* 1 */ { 1, s_8_1, -1, -1, 0}
+};
+
+static const symbol s_9_0[3] = { 'm', 'm', 'a' };
+static const symbol s_9_1[4] = { 'i', 'm', 'm', 'a' };
+
+static const struct among a_9[2] =
+{
+/* 0 */ { 3, s_9_0, -1, 1, 0},
+/* 1 */ { 4, s_9_1, 0, -1, 0}
+};
+
+static const unsigned char g_AEI[] = { 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 };
+
+static const unsigned char g_V1[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 };
+
+static const unsigned char g_V2[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 };
+
+static const unsigned char g_particle_end[] = { 17, 97, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 };
+
+static const symbol s_0[] = { 'k' };
+static const symbol s_1[] = { 'k', 's', 'e' };
+static const symbol s_2[] = { 'k', 's', 'i' };
+static const symbol s_3[] = { 'i' };
+static const symbol s_4[] = { 'a' };
+static const symbol s_5[] = { 'e' };
+static const symbol s_6[] = { 'i' };
+static const symbol s_7[] = { 'o' };
+static const symbol s_8[] = { 0xE4 };
+static const symbol s_9[] = { 0xF6 };
+static const symbol s_10[] = { 'i', 'e' };
+static const symbol s_11[] = { 'e' };
+static const symbol s_12[] = { 'p', 'o' };
+static const symbol s_13[] = { 't' };
+static const symbol s_14[] = { 'p', 'o' };
+static const symbol s_15[] = { 'j' };
+static const symbol s_16[] = { 'o' };
+static const symbol s_17[] = { 'u' };
+static const symbol s_18[] = { 'o' };
+static const symbol s_19[] = { 'j' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 46 */
+ { /* gopast */ /* non V1, line 46 */
+ int ret = in_grouping(z, g_V1, 97, 246, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 46 */
+ if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 47 */
+ { /* gopast */ /* non V1, line 47 */
+ int ret = in_grouping(z, g_V1, 97, 246, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 47 */
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_particle_etc(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 55 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 55 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 55 */
+ among_var = find_among_b(z, a_0, 10); /* substring, line 55 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 55 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ if (in_grouping_b(z, g_particle_end, 97, 246, 0)) return 0;
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 64 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 66 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_possessive(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 69 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 69 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 69 */
+ among_var = find_among_b(z, a_4, 9); /* substring, line 69 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 69 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m2 = z->l - z->c; (void)m2; /* not, line 72 */
+ if (!(eq_s_b(z, 1, s_0))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m2;
+ }
+ { int ret = slice_del(z); /* delete, line 72 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 74 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 74 */
+ if (!(eq_s_b(z, 3, s_1))) return 0;
+ z->bra = z->c; /* ], line 74 */
+ { int ret = slice_from_s(z, 3, s_2); /* <-, line 74 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0;
+ if (!(find_among_b(z, a_1, 6))) return 0; /* among, line 81 */
+ { int ret = slice_del(z); /* delete, line 81 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 228) return 0;
+ if (!(find_among_b(z, a_2, 6))) return 0; /* among, line 83 */
+ { int ret = slice_del(z); /* delete, line 84 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0;
+ if (!(find_among_b(z, a_3, 2))) return 0; /* among, line 86 */
+ { int ret = slice_del(z); /* delete, line 86 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_LONG(struct SN_env * z) {
+ if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 91 */
+ return 1;
+}
+
+static int r_VI(struct SN_env * z) {
+ if (!(eq_s_b(z, 1, s_3))) return 0;
+ if (in_grouping_b(z, g_V2, 97, 246, 0)) return 0;
+ return 1;
+}
+
+static int r_case_ending(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 96 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 96 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 96 */
+ among_var = find_among_b(z, a_6, 30); /* substring, line 96 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 96 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ if (!(eq_s_b(z, 1, s_4))) return 0;
+ break;
+ case 2:
+ if (!(eq_s_b(z, 1, s_5))) return 0;
+ break;
+ case 3:
+ if (!(eq_s_b(z, 1, s_6))) return 0;
+ break;
+ case 4:
+ if (!(eq_s_b(z, 1, s_7))) return 0;
+ break;
+ case 5:
+ if (!(eq_s_b(z, 1, s_8))) return 0;
+ break;
+ case 6:
+ if (!(eq_s_b(z, 1, s_9))) return 0;
+ break;
+ case 7:
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */
+ { int m2 = z->l - z->c; (void)m2; /* and, line 113 */
+ { int m3 = z->l - z->c; (void)m3; /* or, line 112 */
+ { int ret = r_LONG(z);
+ if (ret == 0) goto lab2; /* call LONG, line 111 */
+ if (ret < 0) return ret;
+ }
+ goto lab1;
+ lab2:
+ z->c = z->l - m3;
+ if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m_keep; goto lab0; }
+ }
+ lab1:
+ z->c = z->l - m2;
+ if (z->c <= z->lb) { z->c = z->l - m_keep; goto lab0; }
+ z->c--; /* next, line 113 */
+ }
+ z->bra = z->c; /* ], line 113 */
+ lab0:
+ ;
+ }
+ break;
+ case 8:
+ if (in_grouping_b(z, g_V1, 97, 246, 0)) return 0;
+ if (out_grouping_b(z, g_V1, 97, 246, 0)) return 0;
+ break;
+ case 9:
+ if (!(eq_s_b(z, 1, s_11))) return 0;
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 138 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set ending_removed, line 139 */
+ return 1;
+}
+
+static int r_other_endings(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 142 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[1]) return 0;
+ z->c = z->I[1]; /* tomark, line 142 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 142 */
+ among_var = find_among_b(z, a_7, 14); /* substring, line 142 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 142 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m2 = z->l - z->c; (void)m2; /* not, line 146 */
+ if (!(eq_s_b(z, 2, s_12))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m2;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 151 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_i_plural(struct SN_env * z) {
+ { int mlimit; /* setlimit, line 154 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 154 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 154 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit; return 0; }
+ if (!(find_among_b(z, a_8, 2))) { z->lb = mlimit; return 0; } /* substring, line 154 */
+ z->bra = z->c; /* ], line 154 */
+ z->lb = mlimit;
+ }
+ { int ret = slice_del(z); /* delete, line 158 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_t_plural(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 161 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 161 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 162 */
+ if (!(eq_s_b(z, 1, s_13))) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 162 */
+ { int m_test = z->l - z->c; /* test, line 162 */
+ if (in_grouping_b(z, g_V1, 97, 246, 0)) { z->lb = mlimit; return 0; }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 163 */
+ if (ret < 0) return ret;
+ }
+ z->lb = mlimit;
+ }
+ { int mlimit; /* setlimit, line 165 */
+ int m2 = z->l - z->c; (void)m2;
+ if (z->c < z->I[1]) return 0;
+ z->c = z->I[1]; /* tomark, line 165 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m2;
+ z->ket = z->c; /* [, line 165 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_9, 2); /* substring, line 165 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 165 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m3 = z->l - z->c; (void)m3; /* not, line 167 */
+ if (!(eq_s_b(z, 2, s_14))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m3;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 170 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_tidy(struct SN_env * z) {
+ { int mlimit; /* setlimit, line 173 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 173 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* do, line 174 */
+ { int m3 = z->l - z->c; (void)m3; /* and, line 174 */
+ { int ret = r_LONG(z);
+ if (ret == 0) goto lab0; /* call LONG, line 174 */
+ if (ret < 0) return ret;
+ }
+ z->c = z->l - m3;
+ z->ket = z->c; /* [, line 174 */
+ if (z->c <= z->lb) goto lab0;
+ z->c--; /* next, line 174 */
+ z->bra = z->c; /* ], line 174 */
+ { int ret = slice_del(z); /* delete, line 174 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab0:
+ z->c = z->l - m2;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 175 */
+ z->ket = z->c; /* [, line 175 */
+ if (in_grouping_b(z, g_AEI, 97, 228, 0)) goto lab1;
+ z->bra = z->c; /* ], line 175 */
+ if (out_grouping_b(z, g_V1, 97, 246, 0)) goto lab1;
+ { int ret = slice_del(z); /* delete, line 175 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 176 */
+ z->ket = z->c; /* [, line 176 */
+ if (!(eq_s_b(z, 1, s_15))) goto lab2;
+ z->bra = z->c; /* ], line 176 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 176 */
+ if (!(eq_s_b(z, 1, s_16))) goto lab4;
+ goto lab3;
+ lab4:
+ z->c = z->l - m6;
+ if (!(eq_s_b(z, 1, s_17))) goto lab2;
+ }
+ lab3:
+ { int ret = slice_del(z); /* delete, line 176 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m5;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 177 */
+ z->ket = z->c; /* [, line 177 */
+ if (!(eq_s_b(z, 1, s_18))) goto lab5;
+ z->bra = z->c; /* ], line 177 */
+ if (!(eq_s_b(z, 1, s_19))) goto lab5;
+ { int ret = slice_del(z); /* delete, line 177 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ z->c = z->l - m7;
+ }
+ z->lb = mlimit;
+ }
+ if (in_grouping_b(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* non V1, line 179 */
+ z->ket = z->c; /* [, line 179 */
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 179 */
+ z->bra = z->c; /* ], line 179 */
+ z->S[0] = slice_to(z, z->S[0]); /* -> x, line 179 */
+ if (z->S[0] == 0) return -1; /* -> x, line 179 */
+ if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 179 */
+ { int ret = slice_del(z); /* delete, line 179 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern int finnish_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 185 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 185 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->B[0] = 0; /* unset ending_removed, line 186 */
+ z->lb = z->c; z->c = z->l; /* backwards, line 187 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 188 */
+ { int ret = r_particle_etc(z);
+ if (ret == 0) goto lab1; /* call particle_etc, line 188 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 189 */
+ { int ret = r_possessive(z);
+ if (ret == 0) goto lab2; /* call possessive, line 189 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 190 */
+ { int ret = r_case_ending(z);
+ if (ret == 0) goto lab3; /* call case_ending, line 190 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 191 */
+ { int ret = r_other_endings(z);
+ if (ret == 0) goto lab4; /* call other_endings, line 191 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ z->c = z->l - m5;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* or, line 192 */
+ if (!(z->B[0])) goto lab6; /* Boolean test ending_removed, line 192 */
+ { int m7 = z->l - z->c; (void)m7; /* do, line 192 */
+ { int ret = r_i_plural(z);
+ if (ret == 0) goto lab7; /* call i_plural, line 192 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m7;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int m8 = z->l - z->c; (void)m8; /* do, line 192 */
+ { int ret = r_t_plural(z);
+ if (ret == 0) goto lab8; /* call t_plural, line 192 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = z->l - m8;
+ }
+ }
+lab5:
+ { int m9 = z->l - z->c; (void)m9; /* do, line 193 */
+ { int ret = r_tidy(z);
+ if (ret == 0) goto lab9; /* call tidy, line 193 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m9;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * finnish_ISO_8859_1_create_env(void) { return SN_create_env(1, 2, 1); }
+
+extern void finnish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 1); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c
new file mode 100644
index 00000000000..fc79c0a24dc
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c
@@ -0,0 +1,1246 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int french_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_un_accent(struct SN_env * z);
+static int r_un_double(struct SN_env * z);
+static int r_residual_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_i_verb_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * french_ISO_8859_1_create_env(void);
+extern void french_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[3] = { 'c', 'o', 'l' };
+static const symbol s_0_1[3] = { 'p', 'a', 'r' };
+static const symbol s_0_2[3] = { 't', 'a', 'p' };
+
+static const struct among a_0[3] =
+{
+/* 0 */ { 3, s_0_0, -1, -1, 0},
+/* 1 */ { 3, s_0_1, -1, -1, 0},
+/* 2 */ { 3, s_0_2, -1, -1, 0}
+};
+
+static const symbol s_1_1[1] = { 'I' };
+static const symbol s_1_2[1] = { 'U' };
+static const symbol s_1_3[1] = { 'Y' };
+
+static const struct among a_1[4] =
+{
+/* 0 */ { 0, 0, -1, 4, 0},
+/* 1 */ { 1, s_1_1, 0, 1, 0},
+/* 2 */ { 1, s_1_2, 0, 2, 0},
+/* 3 */ { 1, s_1_3, 0, 3, 0}
+};
+
+static const symbol s_2_0[3] = { 'i', 'q', 'U' };
+static const symbol s_2_1[3] = { 'a', 'b', 'l' };
+static const symbol s_2_2[3] = { 'I', 0xE8, 'r' };
+static const symbol s_2_3[3] = { 'i', 0xE8, 'r' };
+static const symbol s_2_4[3] = { 'e', 'u', 's' };
+static const symbol s_2_5[2] = { 'i', 'v' };
+
+static const struct among a_2[6] =
+{
+/* 0 */ { 3, s_2_0, -1, 3, 0},
+/* 1 */ { 3, s_2_1, -1, 3, 0},
+/* 2 */ { 3, s_2_2, -1, 4, 0},
+/* 3 */ { 3, s_2_3, -1, 4, 0},
+/* 4 */ { 3, s_2_4, -1, 2, 0},
+/* 5 */ { 2, s_2_5, -1, 1, 0}
+};
+
+static const symbol s_3_0[2] = { 'i', 'c' };
+static const symbol s_3_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_3_2[2] = { 'i', 'v' };
+
+static const struct among a_3[3] =
+{
+/* 0 */ { 2, s_3_0, -1, 2, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0},
+/* 2 */ { 2, s_3_2, -1, 3, 0}
+};
+
+static const symbol s_4_0[4] = { 'i', 'q', 'U', 'e' };
+static const symbol s_4_1[6] = { 'a', 't', 'r', 'i', 'c', 'e' };
+static const symbol s_4_2[4] = { 'a', 'n', 'c', 'e' };
+static const symbol s_4_3[4] = { 'e', 'n', 'c', 'e' };
+static const symbol s_4_4[5] = { 'l', 'o', 'g', 'i', 'e' };
+static const symbol s_4_5[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_4_6[4] = { 'i', 's', 'm', 'e' };
+static const symbol s_4_7[4] = { 'e', 'u', 's', 'e' };
+static const symbol s_4_8[4] = { 'i', 's', 't', 'e' };
+static const symbol s_4_9[3] = { 'i', 'v', 'e' };
+static const symbol s_4_10[2] = { 'i', 'f' };
+static const symbol s_4_11[5] = { 'u', 's', 'i', 'o', 'n' };
+static const symbol s_4_12[5] = { 'a', 't', 'i', 'o', 'n' };
+static const symbol s_4_13[5] = { 'u', 't', 'i', 'o', 'n' };
+static const symbol s_4_14[5] = { 'a', 't', 'e', 'u', 'r' };
+static const symbol s_4_15[5] = { 'i', 'q', 'U', 'e', 's' };
+static const symbol s_4_16[7] = { 'a', 't', 'r', 'i', 'c', 'e', 's' };
+static const symbol s_4_17[5] = { 'a', 'n', 'c', 'e', 's' };
+static const symbol s_4_18[5] = { 'e', 'n', 'c', 'e', 's' };
+static const symbol s_4_19[6] = { 'l', 'o', 'g', 'i', 'e', 's' };
+static const symbol s_4_20[5] = { 'a', 'b', 'l', 'e', 's' };
+static const symbol s_4_21[5] = { 'i', 's', 'm', 'e', 's' };
+static const symbol s_4_22[5] = { 'e', 'u', 's', 'e', 's' };
+static const symbol s_4_23[5] = { 'i', 's', 't', 'e', 's' };
+static const symbol s_4_24[4] = { 'i', 'v', 'e', 's' };
+static const symbol s_4_25[3] = { 'i', 'f', 's' };
+static const symbol s_4_26[6] = { 'u', 's', 'i', 'o', 'n', 's' };
+static const symbol s_4_27[6] = { 'a', 't', 'i', 'o', 'n', 's' };
+static const symbol s_4_28[6] = { 'u', 't', 'i', 'o', 'n', 's' };
+static const symbol s_4_29[6] = { 'a', 't', 'e', 'u', 'r', 's' };
+static const symbol s_4_30[5] = { 'm', 'e', 'n', 't', 's' };
+static const symbol s_4_31[6] = { 'e', 'm', 'e', 'n', 't', 's' };
+static const symbol s_4_32[9] = { 'i', 's', 's', 'e', 'm', 'e', 'n', 't', 's' };
+static const symbol s_4_33[4] = { 'i', 't', 0xE9, 's' };
+static const symbol s_4_34[4] = { 'm', 'e', 'n', 't' };
+static const symbol s_4_35[5] = { 'e', 'm', 'e', 'n', 't' };
+static const symbol s_4_36[8] = { 'i', 's', 's', 'e', 'm', 'e', 'n', 't' };
+static const symbol s_4_37[6] = { 'a', 'm', 'm', 'e', 'n', 't' };
+static const symbol s_4_38[6] = { 'e', 'm', 'm', 'e', 'n', 't' };
+static const symbol s_4_39[3] = { 'a', 'u', 'x' };
+static const symbol s_4_40[4] = { 'e', 'a', 'u', 'x' };
+static const symbol s_4_41[3] = { 'e', 'u', 'x' };
+static const symbol s_4_42[3] = { 'i', 't', 0xE9 };
+
+static const struct among a_4[43] =
+{
+/* 0 */ { 4, s_4_0, -1, 1, 0},
+/* 1 */ { 6, s_4_1, -1, 2, 0},
+/* 2 */ { 4, s_4_2, -1, 1, 0},
+/* 3 */ { 4, s_4_3, -1, 5, 0},
+/* 4 */ { 5, s_4_4, -1, 3, 0},
+/* 5 */ { 4, s_4_5, -1, 1, 0},
+/* 6 */ { 4, s_4_6, -1, 1, 0},
+/* 7 */ { 4, s_4_7, -1, 11, 0},
+/* 8 */ { 4, s_4_8, -1, 1, 0},
+/* 9 */ { 3, s_4_9, -1, 8, 0},
+/* 10 */ { 2, s_4_10, -1, 8, 0},
+/* 11 */ { 5, s_4_11, -1, 4, 0},
+/* 12 */ { 5, s_4_12, -1, 2, 0},
+/* 13 */ { 5, s_4_13, -1, 4, 0},
+/* 14 */ { 5, s_4_14, -1, 2, 0},
+/* 15 */ { 5, s_4_15, -1, 1, 0},
+/* 16 */ { 7, s_4_16, -1, 2, 0},
+/* 17 */ { 5, s_4_17, -1, 1, 0},
+/* 18 */ { 5, s_4_18, -1, 5, 0},
+/* 19 */ { 6, s_4_19, -1, 3, 0},
+/* 20 */ { 5, s_4_20, -1, 1, 0},
+/* 21 */ { 5, s_4_21, -1, 1, 0},
+/* 22 */ { 5, s_4_22, -1, 11, 0},
+/* 23 */ { 5, s_4_23, -1, 1, 0},
+/* 24 */ { 4, s_4_24, -1, 8, 0},
+/* 25 */ { 3, s_4_25, -1, 8, 0},
+/* 26 */ { 6, s_4_26, -1, 4, 0},
+/* 27 */ { 6, s_4_27, -1, 2, 0},
+/* 28 */ { 6, s_4_28, -1, 4, 0},
+/* 29 */ { 6, s_4_29, -1, 2, 0},
+/* 30 */ { 5, s_4_30, -1, 15, 0},
+/* 31 */ { 6, s_4_31, 30, 6, 0},
+/* 32 */ { 9, s_4_32, 31, 12, 0},
+/* 33 */ { 4, s_4_33, -1, 7, 0},
+/* 34 */ { 4, s_4_34, -1, 15, 0},
+/* 35 */ { 5, s_4_35, 34, 6, 0},
+/* 36 */ { 8, s_4_36, 35, 12, 0},
+/* 37 */ { 6, s_4_37, 34, 13, 0},
+/* 38 */ { 6, s_4_38, 34, 14, 0},
+/* 39 */ { 3, s_4_39, -1, 10, 0},
+/* 40 */ { 4, s_4_40, 39, 9, 0},
+/* 41 */ { 3, s_4_41, -1, 1, 0},
+/* 42 */ { 3, s_4_42, -1, 7, 0}
+};
+
+static const symbol s_5_0[3] = { 'i', 'r', 'a' };
+static const symbol s_5_1[2] = { 'i', 'e' };
+static const symbol s_5_2[4] = { 'i', 's', 's', 'e' };
+static const symbol s_5_3[7] = { 'i', 's', 's', 'a', 'n', 't', 'e' };
+static const symbol s_5_4[1] = { 'i' };
+static const symbol s_5_5[4] = { 'i', 'r', 'a', 'i' };
+static const symbol s_5_6[2] = { 'i', 'r' };
+static const symbol s_5_7[4] = { 'i', 'r', 'a', 's' };
+static const symbol s_5_8[3] = { 'i', 'e', 's' };
+static const symbol s_5_9[4] = { 0xEE, 'm', 'e', 's' };
+static const symbol s_5_10[5] = { 'i', 's', 's', 'e', 's' };
+static const symbol s_5_11[8] = { 'i', 's', 's', 'a', 'n', 't', 'e', 's' };
+static const symbol s_5_12[4] = { 0xEE, 't', 'e', 's' };
+static const symbol s_5_13[2] = { 'i', 's' };
+static const symbol s_5_14[5] = { 'i', 'r', 'a', 'i', 's' };
+static const symbol s_5_15[6] = { 'i', 's', 's', 'a', 'i', 's' };
+static const symbol s_5_16[6] = { 'i', 'r', 'i', 'o', 'n', 's' };
+static const symbol s_5_17[7] = { 'i', 's', 's', 'i', 'o', 'n', 's' };
+static const symbol s_5_18[5] = { 'i', 'r', 'o', 'n', 's' };
+static const symbol s_5_19[6] = { 'i', 's', 's', 'o', 'n', 's' };
+static const symbol s_5_20[7] = { 'i', 's', 's', 'a', 'n', 't', 's' };
+static const symbol s_5_21[2] = { 'i', 't' };
+static const symbol s_5_22[5] = { 'i', 'r', 'a', 'i', 't' };
+static const symbol s_5_23[6] = { 'i', 's', 's', 'a', 'i', 't' };
+static const symbol s_5_24[6] = { 'i', 's', 's', 'a', 'n', 't' };
+static const symbol s_5_25[7] = { 'i', 'r', 'a', 'I', 'e', 'n', 't' };
+static const symbol s_5_26[8] = { 'i', 's', 's', 'a', 'I', 'e', 'n', 't' };
+static const symbol s_5_27[5] = { 'i', 'r', 'e', 'n', 't' };
+static const symbol s_5_28[6] = { 'i', 's', 's', 'e', 'n', 't' };
+static const symbol s_5_29[5] = { 'i', 'r', 'o', 'n', 't' };
+static const symbol s_5_30[2] = { 0xEE, 't' };
+static const symbol s_5_31[5] = { 'i', 'r', 'i', 'e', 'z' };
+static const symbol s_5_32[6] = { 'i', 's', 's', 'i', 'e', 'z' };
+static const symbol s_5_33[4] = { 'i', 'r', 'e', 'z' };
+static const symbol s_5_34[5] = { 'i', 's', 's', 'e', 'z' };
+
+static const struct among a_5[35] =
+{
+/* 0 */ { 3, s_5_0, -1, 1, 0},
+/* 1 */ { 2, s_5_1, -1, 1, 0},
+/* 2 */ { 4, s_5_2, -1, 1, 0},
+/* 3 */ { 7, s_5_3, -1, 1, 0},
+/* 4 */ { 1, s_5_4, -1, 1, 0},
+/* 5 */ { 4, s_5_5, 4, 1, 0},
+/* 6 */ { 2, s_5_6, -1, 1, 0},
+/* 7 */ { 4, s_5_7, -1, 1, 0},
+/* 8 */ { 3, s_5_8, -1, 1, 0},
+/* 9 */ { 4, s_5_9, -1, 1, 0},
+/* 10 */ { 5, s_5_10, -1, 1, 0},
+/* 11 */ { 8, s_5_11, -1, 1, 0},
+/* 12 */ { 4, s_5_12, -1, 1, 0},
+/* 13 */ { 2, s_5_13, -1, 1, 0},
+/* 14 */ { 5, s_5_14, 13, 1, 0},
+/* 15 */ { 6, s_5_15, 13, 1, 0},
+/* 16 */ { 6, s_5_16, -1, 1, 0},
+/* 17 */ { 7, s_5_17, -1, 1, 0},
+/* 18 */ { 5, s_5_18, -1, 1, 0},
+/* 19 */ { 6, s_5_19, -1, 1, 0},
+/* 20 */ { 7, s_5_20, -1, 1, 0},
+/* 21 */ { 2, s_5_21, -1, 1, 0},
+/* 22 */ { 5, s_5_22, 21, 1, 0},
+/* 23 */ { 6, s_5_23, 21, 1, 0},
+/* 24 */ { 6, s_5_24, -1, 1, 0},
+/* 25 */ { 7, s_5_25, -1, 1, 0},
+/* 26 */ { 8, s_5_26, -1, 1, 0},
+/* 27 */ { 5, s_5_27, -1, 1, 0},
+/* 28 */ { 6, s_5_28, -1, 1, 0},
+/* 29 */ { 5, s_5_29, -1, 1, 0},
+/* 30 */ { 2, s_5_30, -1, 1, 0},
+/* 31 */ { 5, s_5_31, -1, 1, 0},
+/* 32 */ { 6, s_5_32, -1, 1, 0},
+/* 33 */ { 4, s_5_33, -1, 1, 0},
+/* 34 */ { 5, s_5_34, -1, 1, 0}
+};
+
+static const symbol s_6_0[1] = { 'a' };
+static const symbol s_6_1[3] = { 'e', 'r', 'a' };
+static const symbol s_6_2[4] = { 'a', 's', 's', 'e' };
+static const symbol s_6_3[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_6_4[2] = { 0xE9, 'e' };
+static const symbol s_6_5[2] = { 'a', 'i' };
+static const symbol s_6_6[4] = { 'e', 'r', 'a', 'i' };
+static const symbol s_6_7[2] = { 'e', 'r' };
+static const symbol s_6_8[2] = { 'a', 's' };
+static const symbol s_6_9[4] = { 'e', 'r', 'a', 's' };
+static const symbol s_6_10[4] = { 0xE2, 'm', 'e', 's' };
+static const symbol s_6_11[5] = { 'a', 's', 's', 'e', 's' };
+static const symbol s_6_12[5] = { 'a', 'n', 't', 'e', 's' };
+static const symbol s_6_13[4] = { 0xE2, 't', 'e', 's' };
+static const symbol s_6_14[3] = { 0xE9, 'e', 's' };
+static const symbol s_6_15[3] = { 'a', 'i', 's' };
+static const symbol s_6_16[5] = { 'e', 'r', 'a', 'i', 's' };
+static const symbol s_6_17[4] = { 'i', 'o', 'n', 's' };
+static const symbol s_6_18[6] = { 'e', 'r', 'i', 'o', 'n', 's' };
+static const symbol s_6_19[7] = { 'a', 's', 's', 'i', 'o', 'n', 's' };
+static const symbol s_6_20[5] = { 'e', 'r', 'o', 'n', 's' };
+static const symbol s_6_21[4] = { 'a', 'n', 't', 's' };
+static const symbol s_6_22[2] = { 0xE9, 's' };
+static const symbol s_6_23[3] = { 'a', 'i', 't' };
+static const symbol s_6_24[5] = { 'e', 'r', 'a', 'i', 't' };
+static const symbol s_6_25[3] = { 'a', 'n', 't' };
+static const symbol s_6_26[5] = { 'a', 'I', 'e', 'n', 't' };
+static const symbol s_6_27[7] = { 'e', 'r', 'a', 'I', 'e', 'n', 't' };
+static const symbol s_6_28[5] = { 0xE8, 'r', 'e', 'n', 't' };
+static const symbol s_6_29[6] = { 'a', 's', 's', 'e', 'n', 't' };
+static const symbol s_6_30[5] = { 'e', 'r', 'o', 'n', 't' };
+static const symbol s_6_31[2] = { 0xE2, 't' };
+static const symbol s_6_32[2] = { 'e', 'z' };
+static const symbol s_6_33[3] = { 'i', 'e', 'z' };
+static const symbol s_6_34[5] = { 'e', 'r', 'i', 'e', 'z' };
+static const symbol s_6_35[6] = { 'a', 's', 's', 'i', 'e', 'z' };
+static const symbol s_6_36[4] = { 'e', 'r', 'e', 'z' };
+static const symbol s_6_37[1] = { 0xE9 };
+
+static const struct among a_6[38] =
+{
+/* 0 */ { 1, s_6_0, -1, 3, 0},
+/* 1 */ { 3, s_6_1, 0, 2, 0},
+/* 2 */ { 4, s_6_2, -1, 3, 0},
+/* 3 */ { 4, s_6_3, -1, 3, 0},
+/* 4 */ { 2, s_6_4, -1, 2, 0},
+/* 5 */ { 2, s_6_5, -1, 3, 0},
+/* 6 */ { 4, s_6_6, 5, 2, 0},
+/* 7 */ { 2, s_6_7, -1, 2, 0},
+/* 8 */ { 2, s_6_8, -1, 3, 0},
+/* 9 */ { 4, s_6_9, 8, 2, 0},
+/* 10 */ { 4, s_6_10, -1, 3, 0},
+/* 11 */ { 5, s_6_11, -1, 3, 0},
+/* 12 */ { 5, s_6_12, -1, 3, 0},
+/* 13 */ { 4, s_6_13, -1, 3, 0},
+/* 14 */ { 3, s_6_14, -1, 2, 0},
+/* 15 */ { 3, s_6_15, -1, 3, 0},
+/* 16 */ { 5, s_6_16, 15, 2, 0},
+/* 17 */ { 4, s_6_17, -1, 1, 0},
+/* 18 */ { 6, s_6_18, 17, 2, 0},
+/* 19 */ { 7, s_6_19, 17, 3, 0},
+/* 20 */ { 5, s_6_20, -1, 2, 0},
+/* 21 */ { 4, s_6_21, -1, 3, 0},
+/* 22 */ { 2, s_6_22, -1, 2, 0},
+/* 23 */ { 3, s_6_23, -1, 3, 0},
+/* 24 */ { 5, s_6_24, 23, 2, 0},
+/* 25 */ { 3, s_6_25, -1, 3, 0},
+/* 26 */ { 5, s_6_26, -1, 3, 0},
+/* 27 */ { 7, s_6_27, 26, 2, 0},
+/* 28 */ { 5, s_6_28, -1, 2, 0},
+/* 29 */ { 6, s_6_29, -1, 3, 0},
+/* 30 */ { 5, s_6_30, -1, 2, 0},
+/* 31 */ { 2, s_6_31, -1, 3, 0},
+/* 32 */ { 2, s_6_32, -1, 2, 0},
+/* 33 */ { 3, s_6_33, 32, 2, 0},
+/* 34 */ { 5, s_6_34, 33, 2, 0},
+/* 35 */ { 6, s_6_35, 33, 3, 0},
+/* 36 */ { 4, s_6_36, 32, 2, 0},
+/* 37 */ { 1, s_6_37, -1, 2, 0}
+};
+
+static const symbol s_7_0[1] = { 'e' };
+static const symbol s_7_1[4] = { 'I', 0xE8, 'r', 'e' };
+static const symbol s_7_2[4] = { 'i', 0xE8, 'r', 'e' };
+static const symbol s_7_3[3] = { 'i', 'o', 'n' };
+static const symbol s_7_4[3] = { 'I', 'e', 'r' };
+static const symbol s_7_5[3] = { 'i', 'e', 'r' };
+static const symbol s_7_6[1] = { 0xEB };
+
+static const struct among a_7[7] =
+{
+/* 0 */ { 1, s_7_0, -1, 3, 0},
+/* 1 */ { 4, s_7_1, 0, 2, 0},
+/* 2 */ { 4, s_7_2, 0, 2, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0},
+/* 4 */ { 3, s_7_4, -1, 2, 0},
+/* 5 */ { 3, s_7_5, -1, 2, 0},
+/* 6 */ { 1, s_7_6, -1, 4, 0}
+};
+
+static const symbol s_8_0[3] = { 'e', 'l', 'l' };
+static const symbol s_8_1[4] = { 'e', 'i', 'l', 'l' };
+static const symbol s_8_2[3] = { 'e', 'n', 'n' };
+static const symbol s_8_3[3] = { 'o', 'n', 'n' };
+static const symbol s_8_4[3] = { 'e', 't', 't' };
+
+static const struct among a_8[5] =
+{
+/* 0 */ { 3, s_8_0, -1, -1, 0},
+/* 1 */ { 4, s_8_1, -1, -1, 0},
+/* 2 */ { 3, s_8_2, -1, -1, 0},
+/* 3 */ { 3, s_8_3, -1, -1, 0},
+/* 4 */ { 3, s_8_4, -1, -1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 130, 103, 8, 5 };
+
+static const unsigned char g_keep_with_s[] = { 1, 65, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
+
+static const symbol s_0[] = { 'u' };
+static const symbol s_1[] = { 'U' };
+static const symbol s_2[] = { 'i' };
+static const symbol s_3[] = { 'I' };
+static const symbol s_4[] = { 'y' };
+static const symbol s_5[] = { 'Y' };
+static const symbol s_6[] = { 'y' };
+static const symbol s_7[] = { 'Y' };
+static const symbol s_8[] = { 'q' };
+static const symbol s_9[] = { 'u' };
+static const symbol s_10[] = { 'U' };
+static const symbol s_11[] = { 'i' };
+static const symbol s_12[] = { 'u' };
+static const symbol s_13[] = { 'y' };
+static const symbol s_14[] = { 'i', 'c' };
+static const symbol s_15[] = { 'i', 'q', 'U' };
+static const symbol s_16[] = { 'l', 'o', 'g' };
+static const symbol s_17[] = { 'u' };
+static const symbol s_18[] = { 'e', 'n', 't' };
+static const symbol s_19[] = { 'a', 't' };
+static const symbol s_20[] = { 'e', 'u', 'x' };
+static const symbol s_21[] = { 'i' };
+static const symbol s_22[] = { 'a', 'b', 'l' };
+static const symbol s_23[] = { 'i', 'q', 'U' };
+static const symbol s_24[] = { 'a', 't' };
+static const symbol s_25[] = { 'i', 'c' };
+static const symbol s_26[] = { 'i', 'q', 'U' };
+static const symbol s_27[] = { 'e', 'a', 'u' };
+static const symbol s_28[] = { 'a', 'l' };
+static const symbol s_29[] = { 'e', 'u', 'x' };
+static const symbol s_30[] = { 'a', 'n', 't' };
+static const symbol s_31[] = { 'e', 'n', 't' };
+static const symbol s_32[] = { 'e' };
+static const symbol s_33[] = { 's' };
+static const symbol s_34[] = { 's' };
+static const symbol s_35[] = { 't' };
+static const symbol s_36[] = { 'i' };
+static const symbol s_37[] = { 'g', 'u' };
+static const symbol s_38[] = { 0xE9 };
+static const symbol s_39[] = { 0xE8 };
+static const symbol s_40[] = { 'e' };
+static const symbol s_41[] = { 'Y' };
+static const symbol s_42[] = { 'i' };
+static const symbol s_43[] = { 0xE7 };
+static const symbol s_44[] = { 'c' };
+
+static int r_prelude(struct SN_env * z) {
+ while(1) { /* repeat, line 38 */
+ int c1 = z->c;
+ while(1) { /* goto, line 38 */
+ int c2 = z->c;
+ { int c3 = z->c; /* or, line 44 */
+ if (in_grouping(z, g_v, 97, 251, 0)) goto lab3;
+ z->bra = z->c; /* [, line 40 */
+ { int c4 = z->c; /* or, line 40 */
+ if (!(eq_s(z, 1, s_0))) goto lab5;
+ z->ket = z->c; /* ], line 40 */
+ if (in_grouping(z, g_v, 97, 251, 0)) goto lab5;
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 40 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab5:
+ z->c = c4;
+ if (!(eq_s(z, 1, s_2))) goto lab6;
+ z->ket = z->c; /* ], line 41 */
+ if (in_grouping(z, g_v, 97, 251, 0)) goto lab6;
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 41 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab6:
+ z->c = c4;
+ if (!(eq_s(z, 1, s_4))) goto lab3;
+ z->ket = z->c; /* ], line 42 */
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 42 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab4:
+ goto lab2;
+ lab3:
+ z->c = c3;
+ z->bra = z->c; /* [, line 45 */
+ if (!(eq_s(z, 1, s_6))) goto lab7;
+ z->ket = z->c; /* ], line 45 */
+ if (in_grouping(z, g_v, 97, 251, 0)) goto lab7;
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 45 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab7:
+ z->c = c3;
+ if (!(eq_s(z, 1, s_8))) goto lab1;
+ z->bra = z->c; /* [, line 47 */
+ if (!(eq_s(z, 1, s_9))) goto lab1;
+ z->ket = z->c; /* ], line 47 */
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 47 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab2:
+ z->c = c2;
+ break;
+ lab1:
+ z->c = c2;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* goto, line 38 */
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 56 */
+ { int c2 = z->c; /* or, line 58 */
+ if (in_grouping(z, g_v, 97, 251, 0)) goto lab2;
+ if (in_grouping(z, g_v, 97, 251, 0)) goto lab2;
+ if (z->c >= z->l) goto lab2;
+ z->c++; /* next, line 57 */
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3;
+ if (!(find_among(z, a_0, 3))) goto lab3; /* among, line 59 */
+ goto lab1;
+ lab3:
+ z->c = c2;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 66 */
+ { /* gopast */ /* grouping v, line 66 */
+ int ret = out_grouping(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 67 */
+ lab0:
+ z->c = c1;
+ }
+ { int c3 = z->c; /* do, line 69 */
+ { /* gopast */ /* grouping v, line 70 */
+ int ret = out_grouping(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 70 */
+ int ret = in_grouping(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 70 */
+ { /* gopast */ /* grouping v, line 71 */
+ int ret = out_grouping(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 71 */
+ int ret = in_grouping(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 71 */
+ lab4:
+ z->c = c3;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 75 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 77 */
+ if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652096 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 4; else
+ among_var = find_among(z, a_1, 4); /* substring, line 77 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 77 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_11); /* <-, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_12); /* <-, line 79 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 80 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 81 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 92 */
+ among_var = find_among_b(z, a_4, 43); /* substring, line 92 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 92 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 96 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 96 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 99 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 99 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 100 */
+ z->ket = z->c; /* [, line 100 */
+ if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 100 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 100 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab2; /* call R2, line 100 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 100 */
+ if (ret < 0) return ret;
+ }
+ goto lab1;
+ lab2:
+ z->c = z->l - m1;
+ { int ret = slice_from_s(z, 3, s_15); /* <-, line 100 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab1:
+ lab0:
+ ;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 104 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_16); /* <-, line 104 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 107 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_17); /* <-, line 107 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_18); /* <-, line 110 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 114 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 114 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 115 */
+ z->ket = z->c; /* [, line 116 */
+ among_var = find_among_b(z, a_2, 6); /* substring, line 116 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 116 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab3; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 117 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 117 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 117 */
+ if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 117 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 117 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 117 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m2 = z->l - z->c; (void)m2; /* or, line 118 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab5; /* call R2, line 118 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 118 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab5:
+ z->c = z->l - m2;
+ { int ret = r_R1(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R1, line 118 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_20); /* <-, line 118 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab4:
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 120 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 120 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call RV, line 122 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_21); /* <-, line 122 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab3:
+ ;
+ }
+ break;
+ case 7:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 129 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 129 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 130 */
+ z->ket = z->c; /* [, line 131 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab6; }
+ among_var = find_among_b(z, a_3, 3); /* substring, line 131 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab6; }
+ z->bra = z->c; /* ], line 131 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab6; }
+ case 1:
+ { int m3 = z->l - z->c; (void)m3; /* or, line 132 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab8; /* call R2, line 132 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 132 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab8:
+ z->c = z->l - m3;
+ { int ret = slice_from_s(z, 3, s_22); /* <-, line 132 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab7:
+ break;
+ case 2:
+ { int m4 = z->l - z->c; (void)m4; /* or, line 133 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab10; /* call R2, line 133 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 133 */
+ if (ret < 0) return ret;
+ }
+ goto lab9;
+ lab10:
+ z->c = z->l - m4;
+ { int ret = slice_from_s(z, 3, s_23); /* <-, line 133 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab9:
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call R2, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab6:
+ ;
+ }
+ break;
+ case 8:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 141 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 141 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 142 */
+ z->ket = z->c; /* [, line 142 */
+ if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m_keep; goto lab11; }
+ z->bra = z->c; /* ], line 142 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab11; } /* call R2, line 142 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 142 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 142 */
+ if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m_keep; goto lab11; }
+ z->bra = z->c; /* ], line 142 */
+ { int m5 = z->l - z->c; (void)m5; /* or, line 142 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab13; /* call R2, line 142 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 142 */
+ if (ret < 0) return ret;
+ }
+ goto lab12;
+ lab13:
+ z->c = z->l - m5;
+ { int ret = slice_from_s(z, 3, s_26); /* <-, line 142 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab12:
+ lab11:
+ ;
+ }
+ break;
+ case 9:
+ { int ret = slice_from_s(z, 3, s_27); /* <-, line 144 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 145 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 2, s_28); /* <-, line 145 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int m6 = z->l - z->c; (void)m6; /* or, line 147 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab15; /* call R2, line 147 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 147 */
+ if (ret < 0) return ret;
+ }
+ goto lab14;
+ lab15:
+ z->c = z->l - m6;
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 147 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_29); /* <-, line 147 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab14:
+ break;
+ case 12:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 150 */
+ if (ret < 0) return ret;
+ }
+ if (out_grouping_b(z, g_v, 97, 251, 0)) return 0;
+ { int ret = slice_del(z); /* delete, line 150 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 155 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_30); /* <-, line 155 */
+ if (ret < 0) return ret;
+ }
+ return 0; /* fail, line 155 */
+ break;
+ case 14:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 156 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_31); /* <-, line 156 */
+ if (ret < 0) return ret;
+ }
+ return 0; /* fail, line 156 */
+ break;
+ case 15:
+ { int m_test = z->l - z->c; /* test, line 158 */
+ if (in_grouping_b(z, g_v, 97, 251, 0)) return 0;
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 158 */
+ if (ret < 0) return ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 158 */
+ if (ret < 0) return ret;
+ }
+ return 0; /* fail, line 158 */
+ break;
+ }
+ return 1;
+}
+
+static int r_i_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 163 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 163 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 164 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_5, 35); /* substring, line 164 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 164 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ if (out_grouping_b(z, g_v, 97, 251, 0)) { z->lb = mlimit; return 0; }
+ { int ret = slice_del(z); /* delete, line 170 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 174 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 174 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 175 */
+ among_var = find_among_b(z, a_6, 38); /* substring, line 175 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 175 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->lb = mlimit; return 0; } /* call R2, line 177 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 177 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 185 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 190 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 191 */
+ z->ket = z->c; /* [, line 191 */
+ if (!(eq_s_b(z, 1, s_32))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 191 */
+ { int ret = slice_del(z); /* delete, line 191 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_residual_suffix(struct SN_env * z) {
+ int among_var;
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 199 */
+ z->ket = z->c; /* [, line 199 */
+ if (!(eq_s_b(z, 1, s_33))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 199 */
+ { int m_test = z->l - z->c; /* test, line 199 */
+ if (out_grouping_b(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m_keep; goto lab0; }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 199 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ { int mlimit; /* setlimit, line 200 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 200 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 201 */
+ among_var = find_among_b(z, a_7, 7); /* substring, line 201 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 201 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->lb = mlimit; return 0; } /* call R2, line 202 */
+ if (ret < 0) return ret;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* or, line 202 */
+ if (!(eq_s_b(z, 1, s_34))) goto lab2;
+ goto lab1;
+ lab2:
+ z->c = z->l - m2;
+ if (!(eq_s_b(z, 1, s_35))) { z->lb = mlimit; return 0; }
+ }
+ lab1:
+ { int ret = slice_del(z); /* delete, line 202 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_36); /* <-, line 204 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 205 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ if (!(eq_s_b(z, 2, s_37))) { z->lb = mlimit; return 0; }
+ { int ret = slice_del(z); /* delete, line 206 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_un_double(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 212 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_8, 5))) return 0; /* among, line 212 */
+ z->c = z->l - m_test;
+ }
+ z->ket = z->c; /* [, line 212 */
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 212 */
+ z->bra = z->c; /* ], line 212 */
+ { int ret = slice_del(z); /* delete, line 212 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_un_accent(struct SN_env * z) {
+ { int i = 1;
+ while(1) { /* atleast, line 216 */
+ if (out_grouping_b(z, g_v, 97, 251, 0)) goto lab0;
+ i--;
+ continue;
+ lab0:
+ break;
+ }
+ if (i > 0) return 0;
+ }
+ z->ket = z->c; /* [, line 217 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 217 */
+ if (!(eq_s_b(z, 1, s_38))) goto lab2;
+ goto lab1;
+ lab2:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_39))) return 0;
+ }
+lab1:
+ z->bra = z->c; /* ], line 217 */
+ { int ret = slice_from_s(z, 1, s_40); /* <-, line 217 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern int french_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 223 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 223 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 224 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 224 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 225 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 227 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 237 */
+ { int m5 = z->l - z->c; (void)m5; /* and, line 233 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 229 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab6; /* call standard_suffix, line 229 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int ret = r_i_verb_suffix(z);
+ if (ret == 0) goto lab7; /* call i_verb_suffix, line 230 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab7:
+ z->c = z->l - m6;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab4; /* call verb_suffix, line 231 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ z->c = z->l - m5;
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 234 */
+ z->ket = z->c; /* [, line 234 */
+ { int m7 = z->l - z->c; (void)m7; /* or, line 234 */
+ if (!(eq_s_b(z, 1, s_41))) goto lab10;
+ z->bra = z->c; /* ], line 234 */
+ { int ret = slice_from_s(z, 1, s_42); /* <-, line 234 */
+ if (ret < 0) return ret;
+ }
+ goto lab9;
+ lab10:
+ z->c = z->l - m7;
+ if (!(eq_s_b(z, 1, s_43))) { z->c = z->l - m_keep; goto lab8; }
+ z->bra = z->c; /* ], line 235 */
+ { int ret = slice_from_s(z, 1, s_44); /* <-, line 235 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab9:
+ lab8:
+ ;
+ }
+ }
+ goto lab3;
+ lab4:
+ z->c = z->l - m4;
+ { int ret = r_residual_suffix(z);
+ if (ret == 0) goto lab2; /* call residual_suffix, line 238 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab3:
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 243 */
+ { int ret = r_un_double(z);
+ if (ret == 0) goto lab11; /* call un_double, line 243 */
+ if (ret < 0) return ret;
+ }
+ lab11:
+ z->c = z->l - m8;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 244 */
+ { int ret = r_un_accent(z);
+ if (ret == 0) goto lab12; /* call un_accent, line 244 */
+ if (ret < 0) return ret;
+ }
+ lab12:
+ z->c = z->l - m9;
+ }
+ z->c = z->lb;
+ { int c10 = z->c; /* do, line 246 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab13; /* call postlude, line 246 */
+ if (ret < 0) return ret;
+ }
+ lab13:
+ z->c = c10;
+ }
+ return 1;
+}
+
+extern struct SN_env * french_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void french_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c
new file mode 100644
index 00000000000..13c24230923
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c
@@ -0,0 +1,503 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int german_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_standard_suffix(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * german_ISO_8859_1_create_env(void);
+extern void german_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[1] = { 'U' };
+static const symbol s_0_2[1] = { 'Y' };
+static const symbol s_0_3[1] = { 0xE4 };
+static const symbol s_0_4[1] = { 0xF6 };
+static const symbol s_0_5[1] = { 0xFC };
+
+static const struct among a_0[6] =
+{
+/* 0 */ { 0, 0, -1, 6, 0},
+/* 1 */ { 1, s_0_1, 0, 2, 0},
+/* 2 */ { 1, s_0_2, 0, 1, 0},
+/* 3 */ { 1, s_0_3, 0, 3, 0},
+/* 4 */ { 1, s_0_4, 0, 4, 0},
+/* 5 */ { 1, s_0_5, 0, 5, 0}
+};
+
+static const symbol s_1_0[1] = { 'e' };
+static const symbol s_1_1[2] = { 'e', 'm' };
+static const symbol s_1_2[2] = { 'e', 'n' };
+static const symbol s_1_3[3] = { 'e', 'r', 'n' };
+static const symbol s_1_4[2] = { 'e', 'r' };
+static const symbol s_1_5[1] = { 's' };
+static const symbol s_1_6[2] = { 'e', 's' };
+
+static const struct among a_1[7] =
+{
+/* 0 */ { 1, s_1_0, -1, 1, 0},
+/* 1 */ { 2, s_1_1, -1, 1, 0},
+/* 2 */ { 2, s_1_2, -1, 1, 0},
+/* 3 */ { 3, s_1_3, -1, 1, 0},
+/* 4 */ { 2, s_1_4, -1, 1, 0},
+/* 5 */ { 1, s_1_5, -1, 2, 0},
+/* 6 */ { 2, s_1_6, 5, 1, 0}
+};
+
+static const symbol s_2_0[2] = { 'e', 'n' };
+static const symbol s_2_1[2] = { 'e', 'r' };
+static const symbol s_2_2[2] = { 's', 't' };
+static const symbol s_2_3[3] = { 'e', 's', 't' };
+
+static const struct among a_2[4] =
+{
+/* 0 */ { 2, s_2_0, -1, 1, 0},
+/* 1 */ { 2, s_2_1, -1, 1, 0},
+/* 2 */ { 2, s_2_2, -1, 2, 0},
+/* 3 */ { 3, s_2_3, 2, 1, 0}
+};
+
+static const symbol s_3_0[2] = { 'i', 'g' };
+static const symbol s_3_1[4] = { 'l', 'i', 'c', 'h' };
+
+static const struct among a_3[2] =
+{
+/* 0 */ { 2, s_3_0, -1, 1, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0}
+};
+
+static const symbol s_4_0[3] = { 'e', 'n', 'd' };
+static const symbol s_4_1[2] = { 'i', 'g' };
+static const symbol s_4_2[3] = { 'u', 'n', 'g' };
+static const symbol s_4_3[4] = { 'l', 'i', 'c', 'h' };
+static const symbol s_4_4[4] = { 'i', 's', 'c', 'h' };
+static const symbol s_4_5[2] = { 'i', 'k' };
+static const symbol s_4_6[4] = { 'h', 'e', 'i', 't' };
+static const symbol s_4_7[4] = { 'k', 'e', 'i', 't' };
+
+static const struct among a_4[8] =
+{
+/* 0 */ { 3, s_4_0, -1, 1, 0},
+/* 1 */ { 2, s_4_1, -1, 2, 0},
+/* 2 */ { 3, s_4_2, -1, 1, 0},
+/* 3 */ { 4, s_4_3, -1, 3, 0},
+/* 4 */ { 4, s_4_4, -1, 2, 0},
+/* 5 */ { 2, s_4_5, -1, 2, 0},
+/* 6 */ { 4, s_4_6, -1, 3, 0},
+/* 7 */ { 4, s_4_7, -1, 4, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8 };
+
+static const unsigned char g_s_ending[] = { 117, 30, 5 };
+
+static const unsigned char g_st_ending[] = { 117, 30, 4 };
+
+static const symbol s_0[] = { 0xDF };
+static const symbol s_1[] = { 's', 's' };
+static const symbol s_2[] = { 'u' };
+static const symbol s_3[] = { 'U' };
+static const symbol s_4[] = { 'y' };
+static const symbol s_5[] = { 'Y' };
+static const symbol s_6[] = { 'y' };
+static const symbol s_7[] = { 'u' };
+static const symbol s_8[] = { 'a' };
+static const symbol s_9[] = { 'o' };
+static const symbol s_10[] = { 'u' };
+static const symbol s_11[] = { 'i', 'g' };
+static const symbol s_12[] = { 'e' };
+static const symbol s_13[] = { 'e' };
+static const symbol s_14[] = { 'e', 'r' };
+static const symbol s_15[] = { 'e', 'n' };
+
+static int r_prelude(struct SN_env * z) {
+ { int c_test = z->c; /* test, line 30 */
+ while(1) { /* repeat, line 30 */
+ int c1 = z->c;
+ { int c2 = z->c; /* or, line 33 */
+ z->bra = z->c; /* [, line 32 */
+ if (!(eq_s(z, 1, s_0))) goto lab2;
+ z->ket = z->c; /* ], line 32 */
+ { int ret = slice_from_s(z, 2, s_1); /* <-, line 32 */
+ if (ret < 0) return ret;
+ }
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 33 */
+ }
+ lab1:
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ z->c = c_test;
+ }
+ while(1) { /* repeat, line 36 */
+ int c3 = z->c;
+ while(1) { /* goto, line 36 */
+ int c4 = z->c;
+ if (in_grouping(z, g_v, 97, 252, 0)) goto lab4;
+ z->bra = z->c; /* [, line 37 */
+ { int c5 = z->c; /* or, line 37 */
+ if (!(eq_s(z, 1, s_2))) goto lab6;
+ z->ket = z->c; /* ], line 37 */
+ if (in_grouping(z, g_v, 97, 252, 0)) goto lab6;
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 37 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c5;
+ if (!(eq_s(z, 1, s_4))) goto lab4;
+ z->ket = z->c; /* ], line 38 */
+ if (in_grouping(z, g_v, 97, 252, 0)) goto lab4;
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 38 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ z->c = c4;
+ break;
+ lab4:
+ z->c = c4;
+ if (z->c >= z->l) goto lab3;
+ z->c++; /* goto, line 36 */
+ }
+ continue;
+ lab3:
+ z->c = c3;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { int c_test = z->c; /* test, line 47 */
+ { int ret = z->c + 3;
+ if (0 > ret || ret > z->l) return 0;
+ z->c = ret; /* hop, line 47 */
+ }
+ z->I[2] = z->c; /* setmark x, line 47 */
+ z->c = c_test;
+ }
+ { /* gopast */ /* grouping v, line 49 */
+ int ret = out_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 49 */
+ int ret = in_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 49 */
+ /* try, line 50 */
+ if (!(z->I[0] < z->I[2])) goto lab0;
+ z->I[0] = z->I[2];
+lab0:
+ { /* gopast */ /* grouping v, line 51 */
+ int ret = out_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 51 */
+ int ret = in_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 51 */
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 55 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 57 */
+ among_var = find_among(z, a_0, 6); /* substring, line 57 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 57 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 58 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_8); /* <-, line 60 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_9); /* <-, line 61 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 62 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 63 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ { int m1 = z->l - z->c; (void)m1; /* do, line 74 */
+ z->ket = z->c; /* [, line 75 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0;
+ among_var = find_among_b(z, a_1, 7); /* substring, line 75 */
+ if (!(among_var)) goto lab0;
+ z->bra = z->c; /* ], line 75 */
+ { int ret = r_R1(z);
+ if (ret == 0) goto lab0; /* call R1, line 75 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (in_grouping_b(z, g_s_ending, 98, 116, 0)) goto lab0;
+ { int ret = slice_del(z); /* delete, line 80 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ z->c = z->l - m1;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* do, line 84 */
+ z->ket = z->c; /* [, line 85 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab1;
+ among_var = find_among_b(z, a_2, 4); /* substring, line 85 */
+ if (!(among_var)) goto lab1;
+ z->bra = z->c; /* ], line 85 */
+ { int ret = r_R1(z);
+ if (ret == 0) goto lab1; /* call R1, line 85 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: goto lab1;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 87 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (in_grouping_b(z, g_st_ending, 98, 116, 0)) goto lab1;
+ { int ret = z->c - 3;
+ if (z->lb > ret || ret > z->l) goto lab1;
+ z->c = ret; /* hop, line 90 */
+ }
+ { int ret = slice_del(z); /* delete, line 90 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 94 */
+ z->ket = z->c; /* [, line 95 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2;
+ among_var = find_among_b(z, a_4, 8); /* substring, line 95 */
+ if (!(among_var)) goto lab2;
+ z->bra = z->c; /* ], line 95 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab2; /* call R2, line 95 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: goto lab2;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 97 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 98 */
+ z->ket = z->c; /* [, line 98 */
+ if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 98 */
+ { int m4 = z->l - z->c; (void)m4; /* not, line 98 */
+ if (!(eq_s_b(z, 1, s_12))) goto lab4;
+ { z->c = z->l - m_keep; goto lab3; }
+ lab4:
+ z->c = z->l - m4;
+ }
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 98 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 98 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ ;
+ }
+ break;
+ case 2:
+ { int m5 = z->l - z->c; (void)m5; /* not, line 101 */
+ if (!(eq_s_b(z, 1, s_13))) goto lab5;
+ goto lab2;
+ lab5:
+ z->c = z->l - m5;
+ }
+ { int ret = slice_del(z); /* delete, line 101 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 104 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 105 */
+ z->ket = z->c; /* [, line 106 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 106 */
+ if (!(eq_s_b(z, 2, s_14))) goto lab8;
+ goto lab7;
+ lab8:
+ z->c = z->l - m6;
+ if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m_keep; goto lab6; }
+ }
+ lab7:
+ z->bra = z->c; /* ], line 106 */
+ { int ret = r_R1(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call R1, line 106 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 106 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ ;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */
+ z->ket = z->c; /* [, line 112 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m_keep; goto lab9; }
+ among_var = find_among_b(z, a_3, 2); /* substring, line 112 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab9; }
+ z->bra = z->c; /* ], line 112 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab9; } /* call R2, line 112 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab9; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 114 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab9:
+ ;
+ }
+ break;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ return 1;
+}
+
+extern int german_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 125 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 125 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 126 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 126 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 127 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 128 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab2; /* call standard_suffix, line 128 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ z->c = z->lb;
+ { int c4 = z->c; /* do, line 129 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab3; /* call postlude, line 129 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = c4;
+ }
+ return 1;
+}
+
+extern struct SN_env * german_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void german_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_hungarian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_hungarian.c
new file mode 100644
index 00000000000..ff4b23e0605
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_hungarian.c
@@ -0,0 +1,1230 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int hungarian_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_double(struct SN_env * z);
+static int r_undouble(struct SN_env * z);
+static int r_factive(struct SN_env * z);
+static int r_instrum(struct SN_env * z);
+static int r_plur_owner(struct SN_env * z);
+static int r_sing_owner(struct SN_env * z);
+static int r_owned(struct SN_env * z);
+static int r_plural(struct SN_env * z);
+static int r_case_other(struct SN_env * z);
+static int r_case_special(struct SN_env * z);
+static int r_case(struct SN_env * z);
+static int r_v_ending(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * hungarian_ISO_8859_1_create_env(void);
+extern void hungarian_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[2] = { 'c', 's' };
+static const symbol s_0_1[3] = { 'd', 'z', 's' };
+static const symbol s_0_2[2] = { 'g', 'y' };
+static const symbol s_0_3[2] = { 'l', 'y' };
+static const symbol s_0_4[2] = { 'n', 'y' };
+static const symbol s_0_5[2] = { 's', 'z' };
+static const symbol s_0_6[2] = { 't', 'y' };
+static const symbol s_0_7[2] = { 'z', 's' };
+
+static const struct among a_0[8] =
+{
+/* 0 */ { 2, s_0_0, -1, -1, 0},
+/* 1 */ { 3, s_0_1, -1, -1, 0},
+/* 2 */ { 2, s_0_2, -1, -1, 0},
+/* 3 */ { 2, s_0_3, -1, -1, 0},
+/* 4 */ { 2, s_0_4, -1, -1, 0},
+/* 5 */ { 2, s_0_5, -1, -1, 0},
+/* 6 */ { 2, s_0_6, -1, -1, 0},
+/* 7 */ { 2, s_0_7, -1, -1, 0}
+};
+
+static const symbol s_1_0[1] = { 0xE1 };
+static const symbol s_1_1[1] = { 0xE9 };
+
+static const struct among a_1[2] =
+{
+/* 0 */ { 1, s_1_0, -1, 1, 0},
+/* 1 */ { 1, s_1_1, -1, 2, 0}
+};
+
+static const symbol s_2_0[2] = { 'b', 'b' };
+static const symbol s_2_1[2] = { 'c', 'c' };
+static const symbol s_2_2[2] = { 'd', 'd' };
+static const symbol s_2_3[2] = { 'f', 'f' };
+static const symbol s_2_4[2] = { 'g', 'g' };
+static const symbol s_2_5[2] = { 'j', 'j' };
+static const symbol s_2_6[2] = { 'k', 'k' };
+static const symbol s_2_7[2] = { 'l', 'l' };
+static const symbol s_2_8[2] = { 'm', 'm' };
+static const symbol s_2_9[2] = { 'n', 'n' };
+static const symbol s_2_10[2] = { 'p', 'p' };
+static const symbol s_2_11[2] = { 'r', 'r' };
+static const symbol s_2_12[3] = { 'c', 'c', 's' };
+static const symbol s_2_13[2] = { 's', 's' };
+static const symbol s_2_14[3] = { 'z', 'z', 's' };
+static const symbol s_2_15[2] = { 't', 't' };
+static const symbol s_2_16[2] = { 'v', 'v' };
+static const symbol s_2_17[3] = { 'g', 'g', 'y' };
+static const symbol s_2_18[3] = { 'l', 'l', 'y' };
+static const symbol s_2_19[3] = { 'n', 'n', 'y' };
+static const symbol s_2_20[3] = { 't', 't', 'y' };
+static const symbol s_2_21[3] = { 's', 's', 'z' };
+static const symbol s_2_22[2] = { 'z', 'z' };
+
+static const struct among a_2[23] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 2, s_2_1, -1, -1, 0},
+/* 2 */ { 2, s_2_2, -1, -1, 0},
+/* 3 */ { 2, s_2_3, -1, -1, 0},
+/* 4 */ { 2, s_2_4, -1, -1, 0},
+/* 5 */ { 2, s_2_5, -1, -1, 0},
+/* 6 */ { 2, s_2_6, -1, -1, 0},
+/* 7 */ { 2, s_2_7, -1, -1, 0},
+/* 8 */ { 2, s_2_8, -1, -1, 0},
+/* 9 */ { 2, s_2_9, -1, -1, 0},
+/* 10 */ { 2, s_2_10, -1, -1, 0},
+/* 11 */ { 2, s_2_11, -1, -1, 0},
+/* 12 */ { 3, s_2_12, -1, -1, 0},
+/* 13 */ { 2, s_2_13, -1, -1, 0},
+/* 14 */ { 3, s_2_14, -1, -1, 0},
+/* 15 */ { 2, s_2_15, -1, -1, 0},
+/* 16 */ { 2, s_2_16, -1, -1, 0},
+/* 17 */ { 3, s_2_17, -1, -1, 0},
+/* 18 */ { 3, s_2_18, -1, -1, 0},
+/* 19 */ { 3, s_2_19, -1, -1, 0},
+/* 20 */ { 3, s_2_20, -1, -1, 0},
+/* 21 */ { 3, s_2_21, -1, -1, 0},
+/* 22 */ { 2, s_2_22, -1, -1, 0}
+};
+
+static const symbol s_3_0[2] = { 'a', 'l' };
+static const symbol s_3_1[2] = { 'e', 'l' };
+
+static const struct among a_3[2] =
+{
+/* 0 */ { 2, s_3_0, -1, 1, 0},
+/* 1 */ { 2, s_3_1, -1, 2, 0}
+};
+
+static const symbol s_4_0[2] = { 'b', 'a' };
+static const symbol s_4_1[2] = { 'r', 'a' };
+static const symbol s_4_2[2] = { 'b', 'e' };
+static const symbol s_4_3[2] = { 'r', 'e' };
+static const symbol s_4_4[2] = { 'i', 'g' };
+static const symbol s_4_5[3] = { 'n', 'a', 'k' };
+static const symbol s_4_6[3] = { 'n', 'e', 'k' };
+static const symbol s_4_7[3] = { 'v', 'a', 'l' };
+static const symbol s_4_8[3] = { 'v', 'e', 'l' };
+static const symbol s_4_9[2] = { 'u', 'l' };
+static const symbol s_4_10[3] = { 'n', 0xE1, 'l' };
+static const symbol s_4_11[3] = { 'n', 0xE9, 'l' };
+static const symbol s_4_12[3] = { 'b', 0xF3, 'l' };
+static const symbol s_4_13[3] = { 'r', 0xF3, 'l' };
+static const symbol s_4_14[3] = { 't', 0xF3, 'l' };
+static const symbol s_4_15[3] = { 'b', 0xF5, 'l' };
+static const symbol s_4_16[3] = { 'r', 0xF5, 'l' };
+static const symbol s_4_17[3] = { 't', 0xF5, 'l' };
+static const symbol s_4_18[2] = { 0xFC, 'l' };
+static const symbol s_4_19[1] = { 'n' };
+static const symbol s_4_20[2] = { 'a', 'n' };
+static const symbol s_4_21[3] = { 'b', 'a', 'n' };
+static const symbol s_4_22[2] = { 'e', 'n' };
+static const symbol s_4_23[3] = { 'b', 'e', 'n' };
+static const symbol s_4_24[6] = { 'k', 0xE9, 'p', 'p', 'e', 'n' };
+static const symbol s_4_25[2] = { 'o', 'n' };
+static const symbol s_4_26[2] = { 0xF6, 'n' };
+static const symbol s_4_27[4] = { 'k', 0xE9, 'p', 'p' };
+static const symbol s_4_28[3] = { 'k', 'o', 'r' };
+static const symbol s_4_29[1] = { 't' };
+static const symbol s_4_30[2] = { 'a', 't' };
+static const symbol s_4_31[2] = { 'e', 't' };
+static const symbol s_4_32[4] = { 'k', 0xE9, 'n', 't' };
+static const symbol s_4_33[6] = { 'a', 'n', 'k', 0xE9, 'n', 't' };
+static const symbol s_4_34[6] = { 'e', 'n', 'k', 0xE9, 'n', 't' };
+static const symbol s_4_35[6] = { 'o', 'n', 'k', 0xE9, 'n', 't' };
+static const symbol s_4_36[2] = { 'o', 't' };
+static const symbol s_4_37[3] = { 0xE9, 'r', 't' };
+static const symbol s_4_38[2] = { 0xF6, 't' };
+static const symbol s_4_39[3] = { 'h', 'e', 'z' };
+static const symbol s_4_40[3] = { 'h', 'o', 'z' };
+static const symbol s_4_41[3] = { 'h', 0xF6, 'z' };
+static const symbol s_4_42[2] = { 'v', 0xE1 };
+static const symbol s_4_43[2] = { 'v', 0xE9 };
+
+static const struct among a_4[44] =
+{
+/* 0 */ { 2, s_4_0, -1, -1, 0},
+/* 1 */ { 2, s_4_1, -1, -1, 0},
+/* 2 */ { 2, s_4_2, -1, -1, 0},
+/* 3 */ { 2, s_4_3, -1, -1, 0},
+/* 4 */ { 2, s_4_4, -1, -1, 0},
+/* 5 */ { 3, s_4_5, -1, -1, 0},
+/* 6 */ { 3, s_4_6, -1, -1, 0},
+/* 7 */ { 3, s_4_7, -1, -1, 0},
+/* 8 */ { 3, s_4_8, -1, -1, 0},
+/* 9 */ { 2, s_4_9, -1, -1, 0},
+/* 10 */ { 3, s_4_10, -1, -1, 0},
+/* 11 */ { 3, s_4_11, -1, -1, 0},
+/* 12 */ { 3, s_4_12, -1, -1, 0},
+/* 13 */ { 3, s_4_13, -1, -1, 0},
+/* 14 */ { 3, s_4_14, -1, -1, 0},
+/* 15 */ { 3, s_4_15, -1, -1, 0},
+/* 16 */ { 3, s_4_16, -1, -1, 0},
+/* 17 */ { 3, s_4_17, -1, -1, 0},
+/* 18 */ { 2, s_4_18, -1, -1, 0},
+/* 19 */ { 1, s_4_19, -1, -1, 0},
+/* 20 */ { 2, s_4_20, 19, -1, 0},
+/* 21 */ { 3, s_4_21, 20, -1, 0},
+/* 22 */ { 2, s_4_22, 19, -1, 0},
+/* 23 */ { 3, s_4_23, 22, -1, 0},
+/* 24 */ { 6, s_4_24, 22, -1, 0},
+/* 25 */ { 2, s_4_25, 19, -1, 0},
+/* 26 */ { 2, s_4_26, 19, -1, 0},
+/* 27 */ { 4, s_4_27, -1, -1, 0},
+/* 28 */ { 3, s_4_28, -1, -1, 0},
+/* 29 */ { 1, s_4_29, -1, -1, 0},
+/* 30 */ { 2, s_4_30, 29, -1, 0},
+/* 31 */ { 2, s_4_31, 29, -1, 0},
+/* 32 */ { 4, s_4_32, 29, -1, 0},
+/* 33 */ { 6, s_4_33, 32, -1, 0},
+/* 34 */ { 6, s_4_34, 32, -1, 0},
+/* 35 */ { 6, s_4_35, 32, -1, 0},
+/* 36 */ { 2, s_4_36, 29, -1, 0},
+/* 37 */ { 3, s_4_37, 29, -1, 0},
+/* 38 */ { 2, s_4_38, 29, -1, 0},
+/* 39 */ { 3, s_4_39, -1, -1, 0},
+/* 40 */ { 3, s_4_40, -1, -1, 0},
+/* 41 */ { 3, s_4_41, -1, -1, 0},
+/* 42 */ { 2, s_4_42, -1, -1, 0},
+/* 43 */ { 2, s_4_43, -1, -1, 0}
+};
+
+static const symbol s_5_0[2] = { 0xE1, 'n' };
+static const symbol s_5_1[2] = { 0xE9, 'n' };
+static const symbol s_5_2[6] = { 0xE1, 'n', 'k', 0xE9, 'n', 't' };
+
+static const struct among a_5[3] =
+{
+/* 0 */ { 2, s_5_0, -1, 2, 0},
+/* 1 */ { 2, s_5_1, -1, 1, 0},
+/* 2 */ { 6, s_5_2, -1, 3, 0}
+};
+
+static const symbol s_6_0[4] = { 's', 't', 'u', 'l' };
+static const symbol s_6_1[5] = { 'a', 's', 't', 'u', 'l' };
+static const symbol s_6_2[5] = { 0xE1, 's', 't', 'u', 'l' };
+static const symbol s_6_3[4] = { 's', 't', 0xFC, 'l' };
+static const symbol s_6_4[5] = { 'e', 's', 't', 0xFC, 'l' };
+static const symbol s_6_5[5] = { 0xE9, 's', 't', 0xFC, 'l' };
+
+static const struct among a_6[6] =
+{
+/* 0 */ { 4, s_6_0, -1, 2, 0},
+/* 1 */ { 5, s_6_1, 0, 1, 0},
+/* 2 */ { 5, s_6_2, 0, 3, 0},
+/* 3 */ { 4, s_6_3, -1, 2, 0},
+/* 4 */ { 5, s_6_4, 3, 1, 0},
+/* 5 */ { 5, s_6_5, 3, 4, 0}
+};
+
+static const symbol s_7_0[1] = { 0xE1 };
+static const symbol s_7_1[1] = { 0xE9 };
+
+static const struct among a_7[2] =
+{
+/* 0 */ { 1, s_7_0, -1, 1, 0},
+/* 1 */ { 1, s_7_1, -1, 2, 0}
+};
+
+static const symbol s_8_0[1] = { 'k' };
+static const symbol s_8_1[2] = { 'a', 'k' };
+static const symbol s_8_2[2] = { 'e', 'k' };
+static const symbol s_8_3[2] = { 'o', 'k' };
+static const symbol s_8_4[2] = { 0xE1, 'k' };
+static const symbol s_8_5[2] = { 0xE9, 'k' };
+static const symbol s_8_6[2] = { 0xF6, 'k' };
+
+static const struct among a_8[7] =
+{
+/* 0 */ { 1, s_8_0, -1, 7, 0},
+/* 1 */ { 2, s_8_1, 0, 4, 0},
+/* 2 */ { 2, s_8_2, 0, 6, 0},
+/* 3 */ { 2, s_8_3, 0, 5, 0},
+/* 4 */ { 2, s_8_4, 0, 1, 0},
+/* 5 */ { 2, s_8_5, 0, 2, 0},
+/* 6 */ { 2, s_8_6, 0, 3, 0}
+};
+
+static const symbol s_9_0[2] = { 0xE9, 'i' };
+static const symbol s_9_1[3] = { 0xE1, 0xE9, 'i' };
+static const symbol s_9_2[3] = { 0xE9, 0xE9, 'i' };
+static const symbol s_9_3[1] = { 0xE9 };
+static const symbol s_9_4[2] = { 'k', 0xE9 };
+static const symbol s_9_5[3] = { 'a', 'k', 0xE9 };
+static const symbol s_9_6[3] = { 'e', 'k', 0xE9 };
+static const symbol s_9_7[3] = { 'o', 'k', 0xE9 };
+static const symbol s_9_8[3] = { 0xE1, 'k', 0xE9 };
+static const symbol s_9_9[3] = { 0xE9, 'k', 0xE9 };
+static const symbol s_9_10[3] = { 0xF6, 'k', 0xE9 };
+static const symbol s_9_11[2] = { 0xE9, 0xE9 };
+
+static const struct among a_9[12] =
+{
+/* 0 */ { 2, s_9_0, -1, 7, 0},
+/* 1 */ { 3, s_9_1, 0, 6, 0},
+/* 2 */ { 3, s_9_2, 0, 5, 0},
+/* 3 */ { 1, s_9_3, -1, 9, 0},
+/* 4 */ { 2, s_9_4, 3, 4, 0},
+/* 5 */ { 3, s_9_5, 4, 1, 0},
+/* 6 */ { 3, s_9_6, 4, 1, 0},
+/* 7 */ { 3, s_9_7, 4, 1, 0},
+/* 8 */ { 3, s_9_8, 4, 3, 0},
+/* 9 */ { 3, s_9_9, 4, 2, 0},
+/* 10 */ { 3, s_9_10, 4, 1, 0},
+/* 11 */ { 2, s_9_11, 3, 8, 0}
+};
+
+static const symbol s_10_0[1] = { 'a' };
+static const symbol s_10_1[2] = { 'j', 'a' };
+static const symbol s_10_2[1] = { 'd' };
+static const symbol s_10_3[2] = { 'a', 'd' };
+static const symbol s_10_4[2] = { 'e', 'd' };
+static const symbol s_10_5[2] = { 'o', 'd' };
+static const symbol s_10_6[2] = { 0xE1, 'd' };
+static const symbol s_10_7[2] = { 0xE9, 'd' };
+static const symbol s_10_8[2] = { 0xF6, 'd' };
+static const symbol s_10_9[1] = { 'e' };
+static const symbol s_10_10[2] = { 'j', 'e' };
+static const symbol s_10_11[2] = { 'n', 'k' };
+static const symbol s_10_12[3] = { 'u', 'n', 'k' };
+static const symbol s_10_13[3] = { 0xE1, 'n', 'k' };
+static const symbol s_10_14[3] = { 0xE9, 'n', 'k' };
+static const symbol s_10_15[3] = { 0xFC, 'n', 'k' };
+static const symbol s_10_16[2] = { 'u', 'k' };
+static const symbol s_10_17[3] = { 'j', 'u', 'k' };
+static const symbol s_10_18[4] = { 0xE1, 'j', 'u', 'k' };
+static const symbol s_10_19[2] = { 0xFC, 'k' };
+static const symbol s_10_20[3] = { 'j', 0xFC, 'k' };
+static const symbol s_10_21[4] = { 0xE9, 'j', 0xFC, 'k' };
+static const symbol s_10_22[1] = { 'm' };
+static const symbol s_10_23[2] = { 'a', 'm' };
+static const symbol s_10_24[2] = { 'e', 'm' };
+static const symbol s_10_25[2] = { 'o', 'm' };
+static const symbol s_10_26[2] = { 0xE1, 'm' };
+static const symbol s_10_27[2] = { 0xE9, 'm' };
+static const symbol s_10_28[1] = { 'o' };
+static const symbol s_10_29[1] = { 0xE1 };
+static const symbol s_10_30[1] = { 0xE9 };
+
+static const struct among a_10[31] =
+{
+/* 0 */ { 1, s_10_0, -1, 18, 0},
+/* 1 */ { 2, s_10_1, 0, 17, 0},
+/* 2 */ { 1, s_10_2, -1, 16, 0},
+/* 3 */ { 2, s_10_3, 2, 13, 0},
+/* 4 */ { 2, s_10_4, 2, 13, 0},
+/* 5 */ { 2, s_10_5, 2, 13, 0},
+/* 6 */ { 2, s_10_6, 2, 14, 0},
+/* 7 */ { 2, s_10_7, 2, 15, 0},
+/* 8 */ { 2, s_10_8, 2, 13, 0},
+/* 9 */ { 1, s_10_9, -1, 18, 0},
+/* 10 */ { 2, s_10_10, 9, 17, 0},
+/* 11 */ { 2, s_10_11, -1, 4, 0},
+/* 12 */ { 3, s_10_12, 11, 1, 0},
+/* 13 */ { 3, s_10_13, 11, 2, 0},
+/* 14 */ { 3, s_10_14, 11, 3, 0},
+/* 15 */ { 3, s_10_15, 11, 1, 0},
+/* 16 */ { 2, s_10_16, -1, 8, 0},
+/* 17 */ { 3, s_10_17, 16, 7, 0},
+/* 18 */ { 4, s_10_18, 17, 5, 0},
+/* 19 */ { 2, s_10_19, -1, 8, 0},
+/* 20 */ { 3, s_10_20, 19, 7, 0},
+/* 21 */ { 4, s_10_21, 20, 6, 0},
+/* 22 */ { 1, s_10_22, -1, 12, 0},
+/* 23 */ { 2, s_10_23, 22, 9, 0},
+/* 24 */ { 2, s_10_24, 22, 9, 0},
+/* 25 */ { 2, s_10_25, 22, 9, 0},
+/* 26 */ { 2, s_10_26, 22, 10, 0},
+/* 27 */ { 2, s_10_27, 22, 11, 0},
+/* 28 */ { 1, s_10_28, -1, 18, 0},
+/* 29 */ { 1, s_10_29, -1, 19, 0},
+/* 30 */ { 1, s_10_30, -1, 20, 0}
+};
+
+static const symbol s_11_0[2] = { 'i', 'd' };
+static const symbol s_11_1[3] = { 'a', 'i', 'd' };
+static const symbol s_11_2[4] = { 'j', 'a', 'i', 'd' };
+static const symbol s_11_3[3] = { 'e', 'i', 'd' };
+static const symbol s_11_4[4] = { 'j', 'e', 'i', 'd' };
+static const symbol s_11_5[3] = { 0xE1, 'i', 'd' };
+static const symbol s_11_6[3] = { 0xE9, 'i', 'd' };
+static const symbol s_11_7[1] = { 'i' };
+static const symbol s_11_8[2] = { 'a', 'i' };
+static const symbol s_11_9[3] = { 'j', 'a', 'i' };
+static const symbol s_11_10[2] = { 'e', 'i' };
+static const symbol s_11_11[3] = { 'j', 'e', 'i' };
+static const symbol s_11_12[2] = { 0xE1, 'i' };
+static const symbol s_11_13[2] = { 0xE9, 'i' };
+static const symbol s_11_14[4] = { 'i', 't', 'e', 'k' };
+static const symbol s_11_15[5] = { 'e', 'i', 't', 'e', 'k' };
+static const symbol s_11_16[6] = { 'j', 'e', 'i', 't', 'e', 'k' };
+static const symbol s_11_17[5] = { 0xE9, 'i', 't', 'e', 'k' };
+static const symbol s_11_18[2] = { 'i', 'k' };
+static const symbol s_11_19[3] = { 'a', 'i', 'k' };
+static const symbol s_11_20[4] = { 'j', 'a', 'i', 'k' };
+static const symbol s_11_21[3] = { 'e', 'i', 'k' };
+static const symbol s_11_22[4] = { 'j', 'e', 'i', 'k' };
+static const symbol s_11_23[3] = { 0xE1, 'i', 'k' };
+static const symbol s_11_24[3] = { 0xE9, 'i', 'k' };
+static const symbol s_11_25[3] = { 'i', 'n', 'k' };
+static const symbol s_11_26[4] = { 'a', 'i', 'n', 'k' };
+static const symbol s_11_27[5] = { 'j', 'a', 'i', 'n', 'k' };
+static const symbol s_11_28[4] = { 'e', 'i', 'n', 'k' };
+static const symbol s_11_29[5] = { 'j', 'e', 'i', 'n', 'k' };
+static const symbol s_11_30[4] = { 0xE1, 'i', 'n', 'k' };
+static const symbol s_11_31[4] = { 0xE9, 'i', 'n', 'k' };
+static const symbol s_11_32[5] = { 'a', 'i', 't', 'o', 'k' };
+static const symbol s_11_33[6] = { 'j', 'a', 'i', 't', 'o', 'k' };
+static const symbol s_11_34[5] = { 0xE1, 'i', 't', 'o', 'k' };
+static const symbol s_11_35[2] = { 'i', 'm' };
+static const symbol s_11_36[3] = { 'a', 'i', 'm' };
+static const symbol s_11_37[4] = { 'j', 'a', 'i', 'm' };
+static const symbol s_11_38[3] = { 'e', 'i', 'm' };
+static const symbol s_11_39[4] = { 'j', 'e', 'i', 'm' };
+static const symbol s_11_40[3] = { 0xE1, 'i', 'm' };
+static const symbol s_11_41[3] = { 0xE9, 'i', 'm' };
+
+static const struct among a_11[42] =
+{
+/* 0 */ { 2, s_11_0, -1, 10, 0},
+/* 1 */ { 3, s_11_1, 0, 9, 0},
+/* 2 */ { 4, s_11_2, 1, 6, 0},
+/* 3 */ { 3, s_11_3, 0, 9, 0},
+/* 4 */ { 4, s_11_4, 3, 6, 0},
+/* 5 */ { 3, s_11_5, 0, 7, 0},
+/* 6 */ { 3, s_11_6, 0, 8, 0},
+/* 7 */ { 1, s_11_7, -1, 15, 0},
+/* 8 */ { 2, s_11_8, 7, 14, 0},
+/* 9 */ { 3, s_11_9, 8, 11, 0},
+/* 10 */ { 2, s_11_10, 7, 14, 0},
+/* 11 */ { 3, s_11_11, 10, 11, 0},
+/* 12 */ { 2, s_11_12, 7, 12, 0},
+/* 13 */ { 2, s_11_13, 7, 13, 0},
+/* 14 */ { 4, s_11_14, -1, 24, 0},
+/* 15 */ { 5, s_11_15, 14, 21, 0},
+/* 16 */ { 6, s_11_16, 15, 20, 0},
+/* 17 */ { 5, s_11_17, 14, 23, 0},
+/* 18 */ { 2, s_11_18, -1, 29, 0},
+/* 19 */ { 3, s_11_19, 18, 26, 0},
+/* 20 */ { 4, s_11_20, 19, 25, 0},
+/* 21 */ { 3, s_11_21, 18, 26, 0},
+/* 22 */ { 4, s_11_22, 21, 25, 0},
+/* 23 */ { 3, s_11_23, 18, 27, 0},
+/* 24 */ { 3, s_11_24, 18, 28, 0},
+/* 25 */ { 3, s_11_25, -1, 20, 0},
+/* 26 */ { 4, s_11_26, 25, 17, 0},
+/* 27 */ { 5, s_11_27, 26, 16, 0},
+/* 28 */ { 4, s_11_28, 25, 17, 0},
+/* 29 */ { 5, s_11_29, 28, 16, 0},
+/* 30 */ { 4, s_11_30, 25, 18, 0},
+/* 31 */ { 4, s_11_31, 25, 19, 0},
+/* 32 */ { 5, s_11_32, -1, 21, 0},
+/* 33 */ { 6, s_11_33, 32, 20, 0},
+/* 34 */ { 5, s_11_34, -1, 22, 0},
+/* 35 */ { 2, s_11_35, -1, 5, 0},
+/* 36 */ { 3, s_11_36, 35, 4, 0},
+/* 37 */ { 4, s_11_37, 36, 1, 0},
+/* 38 */ { 3, s_11_38, 35, 4, 0},
+/* 39 */ { 4, s_11_39, 38, 1, 0},
+/* 40 */ { 3, s_11_40, 35, 2, 0},
+/* 41 */ { 3, s_11_41, 35, 3, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 52, 14 };
+
+static const symbol s_0[] = { 'a' };
+static const symbol s_1[] = { 'e' };
+static const symbol s_2[] = { 'e' };
+static const symbol s_3[] = { 'a' };
+static const symbol s_4[] = { 'a' };
+static const symbol s_5[] = { 'a' };
+static const symbol s_6[] = { 'e' };
+static const symbol s_7[] = { 'a' };
+static const symbol s_8[] = { 'e' };
+static const symbol s_9[] = { 'e' };
+static const symbol s_10[] = { 'a' };
+static const symbol s_11[] = { 'e' };
+static const symbol s_12[] = { 'a' };
+static const symbol s_13[] = { 'e' };
+static const symbol s_14[] = { 'a' };
+static const symbol s_15[] = { 'e' };
+static const symbol s_16[] = { 'a' };
+static const symbol s_17[] = { 'e' };
+static const symbol s_18[] = { 'a' };
+static const symbol s_19[] = { 'e' };
+static const symbol s_20[] = { 'a' };
+static const symbol s_21[] = { 'e' };
+static const symbol s_22[] = { 'a' };
+static const symbol s_23[] = { 'e' };
+static const symbol s_24[] = { 'a' };
+static const symbol s_25[] = { 'e' };
+static const symbol s_26[] = { 'a' };
+static const symbol s_27[] = { 'e' };
+static const symbol s_28[] = { 'a' };
+static const symbol s_29[] = { 'e' };
+static const symbol s_30[] = { 'a' };
+static const symbol s_31[] = { 'e' };
+static const symbol s_32[] = { 'a' };
+static const symbol s_33[] = { 'e' };
+static const symbol s_34[] = { 'a' };
+static const symbol s_35[] = { 'e' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ { int c1 = z->c; /* or, line 51 */
+ if (in_grouping(z, g_v, 97, 252, 0)) goto lab1;
+ if (in_grouping(z, g_v, 97, 252, 1) < 0) goto lab1; /* goto */ /* non v, line 48 */
+ { int c2 = z->c; /* or, line 49 */
+ if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3;
+ if (!(find_among(z, a_0, 8))) goto lab3; /* among, line 49 */
+ goto lab2;
+ lab3:
+ z->c = c2;
+ if (z->c >= z->l) goto lab1;
+ z->c++; /* next, line 49 */
+ }
+ lab2:
+ z->I[0] = z->c; /* setmark p1, line 50 */
+ goto lab0;
+ lab1:
+ z->c = c1;
+ if (out_grouping(z, g_v, 97, 252, 0)) return 0;
+ { /* gopast */ /* grouping v, line 53 */
+ int ret = out_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 53 */
+ }
+lab0:
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_v_ending(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 61 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0;
+ among_var = find_among_b(z, a_1, 2); /* substring, line 61 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 61 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 61 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_0); /* <-, line 62 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 63 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_double(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 68 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_2, 23))) return 0; /* among, line 68 */
+ z->c = z->l - m_test;
+ }
+ return 1;
+}
+
+static int r_undouble(struct SN_env * z) {
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 73 */
+ z->ket = z->c; /* [, line 73 */
+ { int ret = z->c - 1;
+ if (z->lb > ret || ret > z->l) return 0;
+ z->c = ret; /* hop, line 73 */
+ }
+ z->bra = z->c; /* ], line 73 */
+ { int ret = slice_del(z); /* delete, line 73 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_instrum(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 77 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0;
+ among_var = find_among_b(z, a_3, 2); /* substring, line 77 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 77 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 77 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_double(z);
+ if (ret == 0) return 0; /* call double, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_double(z);
+ if (ret == 0) return 0; /* call double, line 79 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 81 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_undouble(z);
+ if (ret == 0) return 0; /* call undouble, line 82 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_case(struct SN_env * z) {
+ z->ket = z->c; /* [, line 87 */
+ if (!(find_among_b(z, a_4, 44))) return 0; /* substring, line 87 */
+ z->bra = z->c; /* ], line 87 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 87 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 111 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_v_ending(z);
+ if (ret == 0) return 0; /* call v_ending, line 112 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_case_special(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 116 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0;
+ among_var = find_among_b(z, a_5, 3); /* substring, line 116 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 116 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 116 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 117 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 118 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 119 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_case_other(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 124 */
+ if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0;
+ among_var = find_among_b(z, a_6, 6); /* substring, line 124 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 124 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 124 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 125 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 126 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 127 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 128 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_factive(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 133 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0;
+ among_var = find_among_b(z, a_7, 2); /* substring, line 133 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 133 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 133 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_double(z);
+ if (ret == 0) return 0; /* call double, line 134 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_double(z);
+ if (ret == 0) return 0; /* call double, line 135 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 137 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_undouble(z);
+ if (ret == 0) return 0; /* call undouble, line 138 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_plural(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 142 */
+ if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0;
+ among_var = find_among_b(z, a_8, 7); /* substring, line 142 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 142 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 142 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 143 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_8); /* <-, line 144 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 145 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 146 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_del(z); /* delete, line 147 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_del(z); /* delete, line 148 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_del(z); /* delete, line 149 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_owned(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 154 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 233)) return 0;
+ among_var = find_among_b(z, a_9, 12); /* substring, line 154 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 154 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 154 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 155 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_9); /* <-, line 156 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 157 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 158 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_11); /* <-, line 159 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 1, s_12); /* <-, line 160 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_del(z); /* delete, line 161 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 162 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_del(z); /* delete, line 163 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_sing_owner(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 168 */
+ among_var = find_among_b(z, a_10, 31); /* substring, line 168 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 168 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 168 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 169 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_14); /* <-, line 170 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_15); /* <-, line 171 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 172 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_16); /* <-, line 173 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 1, s_17); /* <-, line 174 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_del(z); /* delete, line 175 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_del(z); /* delete, line 176 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_del(z); /* delete, line 177 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_from_s(z, 1, s_18); /* <-, line 178 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_from_s(z, 1, s_19); /* <-, line 179 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 12:
+ { int ret = slice_del(z); /* delete, line 180 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ { int ret = slice_del(z); /* delete, line 181 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 14:
+ { int ret = slice_from_s(z, 1, s_20); /* <-, line 182 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 15:
+ { int ret = slice_from_s(z, 1, s_21); /* <-, line 183 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 16:
+ { int ret = slice_del(z); /* delete, line 184 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 17:
+ { int ret = slice_del(z); /* delete, line 185 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 18:
+ { int ret = slice_del(z); /* delete, line 186 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 19:
+ { int ret = slice_from_s(z, 1, s_22); /* <-, line 187 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 20:
+ { int ret = slice_from_s(z, 1, s_23); /* <-, line 188 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_plur_owner(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 193 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_11, 42); /* substring, line 193 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 193 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 193 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 194 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_24); /* <-, line 195 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_25); /* <-, line 196 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 197 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_del(z); /* delete, line 198 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_del(z); /* delete, line 199 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 1, s_26); /* <-, line 200 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 1, s_27); /* <-, line 201 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_del(z); /* delete, line 202 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_del(z); /* delete, line 203 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_del(z); /* delete, line 204 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 12:
+ { int ret = slice_from_s(z, 1, s_28); /* <-, line 205 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ { int ret = slice_from_s(z, 1, s_29); /* <-, line 206 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 14:
+ { int ret = slice_del(z); /* delete, line 207 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 15:
+ { int ret = slice_del(z); /* delete, line 208 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 16:
+ { int ret = slice_del(z); /* delete, line 209 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 17:
+ { int ret = slice_del(z); /* delete, line 210 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 18:
+ { int ret = slice_from_s(z, 1, s_30); /* <-, line 211 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 19:
+ { int ret = slice_from_s(z, 1, s_31); /* <-, line 212 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 20:
+ { int ret = slice_del(z); /* delete, line 214 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 21:
+ { int ret = slice_del(z); /* delete, line 215 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 22:
+ { int ret = slice_from_s(z, 1, s_32); /* <-, line 216 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 23:
+ { int ret = slice_from_s(z, 1, s_33); /* <-, line 217 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 24:
+ { int ret = slice_del(z); /* delete, line 218 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 25:
+ { int ret = slice_del(z); /* delete, line 219 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 26:
+ { int ret = slice_del(z); /* delete, line 220 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 27:
+ { int ret = slice_from_s(z, 1, s_34); /* <-, line 221 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 28:
+ { int ret = slice_from_s(z, 1, s_35); /* <-, line 222 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 29:
+ { int ret = slice_del(z); /* delete, line 223 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int hungarian_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 229 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 229 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 230 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 231 */
+ { int ret = r_instrum(z);
+ if (ret == 0) goto lab1; /* call instrum, line 231 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 232 */
+ { int ret = r_case(z);
+ if (ret == 0) goto lab2; /* call case, line 232 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 233 */
+ { int ret = r_case_special(z);
+ if (ret == 0) goto lab3; /* call case_special, line 233 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 234 */
+ { int ret = r_case_other(z);
+ if (ret == 0) goto lab4; /* call case_other, line 234 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ z->c = z->l - m5;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* do, line 235 */
+ { int ret = r_factive(z);
+ if (ret == 0) goto lab5; /* call factive, line 235 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ z->c = z->l - m6;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 236 */
+ { int ret = r_owned(z);
+ if (ret == 0) goto lab6; /* call owned, line 236 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m7;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 237 */
+ { int ret = r_sing_owner(z);
+ if (ret == 0) goto lab7; /* call sing_owner, line 237 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m8;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 238 */
+ { int ret = r_plur_owner(z);
+ if (ret == 0) goto lab8; /* call plur_owner, line 238 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = z->l - m9;
+ }
+ { int m10 = z->l - z->c; (void)m10; /* do, line 239 */
+ { int ret = r_plural(z);
+ if (ret == 0) goto lab9; /* call plural, line 239 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m10;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * hungarian_ISO_8859_1_create_env(void) { return SN_create_env(0, 1, 0); }
+
+extern void hungarian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c
new file mode 100644
index 00000000000..d941b0f0363
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c
@@ -0,0 +1,1065 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int italian_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_vowel_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_attached_pronoun(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * italian_ISO_8859_1_create_env(void);
+extern void italian_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[2] = { 'q', 'u' };
+static const symbol s_0_2[1] = { 0xE1 };
+static const symbol s_0_3[1] = { 0xE9 };
+static const symbol s_0_4[1] = { 0xED };
+static const symbol s_0_5[1] = { 0xF3 };
+static const symbol s_0_6[1] = { 0xFA };
+
+static const struct among a_0[7] =
+{
+/* 0 */ { 0, 0, -1, 7, 0},
+/* 1 */ { 2, s_0_1, 0, 6, 0},
+/* 2 */ { 1, s_0_2, 0, 1, 0},
+/* 3 */ { 1, s_0_3, 0, 2, 0},
+/* 4 */ { 1, s_0_4, 0, 3, 0},
+/* 5 */ { 1, s_0_5, 0, 4, 0},
+/* 6 */ { 1, s_0_6, 0, 5, 0}
+};
+
+static const symbol s_1_1[1] = { 'I' };
+static const symbol s_1_2[1] = { 'U' };
+
+static const struct among a_1[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 1, s_1_1, 0, 1, 0},
+/* 2 */ { 1, s_1_2, 0, 2, 0}
+};
+
+static const symbol s_2_0[2] = { 'l', 'a' };
+static const symbol s_2_1[4] = { 'c', 'e', 'l', 'a' };
+static const symbol s_2_2[6] = { 'g', 'l', 'i', 'e', 'l', 'a' };
+static const symbol s_2_3[4] = { 'm', 'e', 'l', 'a' };
+static const symbol s_2_4[4] = { 't', 'e', 'l', 'a' };
+static const symbol s_2_5[4] = { 'v', 'e', 'l', 'a' };
+static const symbol s_2_6[2] = { 'l', 'e' };
+static const symbol s_2_7[4] = { 'c', 'e', 'l', 'e' };
+static const symbol s_2_8[6] = { 'g', 'l', 'i', 'e', 'l', 'e' };
+static const symbol s_2_9[4] = { 'm', 'e', 'l', 'e' };
+static const symbol s_2_10[4] = { 't', 'e', 'l', 'e' };
+static const symbol s_2_11[4] = { 'v', 'e', 'l', 'e' };
+static const symbol s_2_12[2] = { 'n', 'e' };
+static const symbol s_2_13[4] = { 'c', 'e', 'n', 'e' };
+static const symbol s_2_14[6] = { 'g', 'l', 'i', 'e', 'n', 'e' };
+static const symbol s_2_15[4] = { 'm', 'e', 'n', 'e' };
+static const symbol s_2_16[4] = { 's', 'e', 'n', 'e' };
+static const symbol s_2_17[4] = { 't', 'e', 'n', 'e' };
+static const symbol s_2_18[4] = { 'v', 'e', 'n', 'e' };
+static const symbol s_2_19[2] = { 'c', 'i' };
+static const symbol s_2_20[2] = { 'l', 'i' };
+static const symbol s_2_21[4] = { 'c', 'e', 'l', 'i' };
+static const symbol s_2_22[6] = { 'g', 'l', 'i', 'e', 'l', 'i' };
+static const symbol s_2_23[4] = { 'm', 'e', 'l', 'i' };
+static const symbol s_2_24[4] = { 't', 'e', 'l', 'i' };
+static const symbol s_2_25[4] = { 'v', 'e', 'l', 'i' };
+static const symbol s_2_26[3] = { 'g', 'l', 'i' };
+static const symbol s_2_27[2] = { 'm', 'i' };
+static const symbol s_2_28[2] = { 's', 'i' };
+static const symbol s_2_29[2] = { 't', 'i' };
+static const symbol s_2_30[2] = { 'v', 'i' };
+static const symbol s_2_31[2] = { 'l', 'o' };
+static const symbol s_2_32[4] = { 'c', 'e', 'l', 'o' };
+static const symbol s_2_33[6] = { 'g', 'l', 'i', 'e', 'l', 'o' };
+static const symbol s_2_34[4] = { 'm', 'e', 'l', 'o' };
+static const symbol s_2_35[4] = { 't', 'e', 'l', 'o' };
+static const symbol s_2_36[4] = { 'v', 'e', 'l', 'o' };
+
+static const struct among a_2[37] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 4, s_2_1, 0, -1, 0},
+/* 2 */ { 6, s_2_2, 0, -1, 0},
+/* 3 */ { 4, s_2_3, 0, -1, 0},
+/* 4 */ { 4, s_2_4, 0, -1, 0},
+/* 5 */ { 4, s_2_5, 0, -1, 0},
+/* 6 */ { 2, s_2_6, -1, -1, 0},
+/* 7 */ { 4, s_2_7, 6, -1, 0},
+/* 8 */ { 6, s_2_8, 6, -1, 0},
+/* 9 */ { 4, s_2_9, 6, -1, 0},
+/* 10 */ { 4, s_2_10, 6, -1, 0},
+/* 11 */ { 4, s_2_11, 6, -1, 0},
+/* 12 */ { 2, s_2_12, -1, -1, 0},
+/* 13 */ { 4, s_2_13, 12, -1, 0},
+/* 14 */ { 6, s_2_14, 12, -1, 0},
+/* 15 */ { 4, s_2_15, 12, -1, 0},
+/* 16 */ { 4, s_2_16, 12, -1, 0},
+/* 17 */ { 4, s_2_17, 12, -1, 0},
+/* 18 */ { 4, s_2_18, 12, -1, 0},
+/* 19 */ { 2, s_2_19, -1, -1, 0},
+/* 20 */ { 2, s_2_20, -1, -1, 0},
+/* 21 */ { 4, s_2_21, 20, -1, 0},
+/* 22 */ { 6, s_2_22, 20, -1, 0},
+/* 23 */ { 4, s_2_23, 20, -1, 0},
+/* 24 */ { 4, s_2_24, 20, -1, 0},
+/* 25 */ { 4, s_2_25, 20, -1, 0},
+/* 26 */ { 3, s_2_26, 20, -1, 0},
+/* 27 */ { 2, s_2_27, -1, -1, 0},
+/* 28 */ { 2, s_2_28, -1, -1, 0},
+/* 29 */ { 2, s_2_29, -1, -1, 0},
+/* 30 */ { 2, s_2_30, -1, -1, 0},
+/* 31 */ { 2, s_2_31, -1, -1, 0},
+/* 32 */ { 4, s_2_32, 31, -1, 0},
+/* 33 */ { 6, s_2_33, 31, -1, 0},
+/* 34 */ { 4, s_2_34, 31, -1, 0},
+/* 35 */ { 4, s_2_35, 31, -1, 0},
+/* 36 */ { 4, s_2_36, 31, -1, 0}
+};
+
+static const symbol s_3_0[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_3_1[4] = { 'e', 'n', 'd', 'o' };
+static const symbol s_3_2[2] = { 'a', 'r' };
+static const symbol s_3_3[2] = { 'e', 'r' };
+static const symbol s_3_4[2] = { 'i', 'r' };
+
+static const struct among a_3[5] =
+{
+/* 0 */ { 4, s_3_0, -1, 1, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0},
+/* 2 */ { 2, s_3_2, -1, 2, 0},
+/* 3 */ { 2, s_3_3, -1, 2, 0},
+/* 4 */ { 2, s_3_4, -1, 2, 0}
+};
+
+static const symbol s_4_0[2] = { 'i', 'c' };
+static const symbol s_4_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_4_2[2] = { 'o', 's' };
+static const symbol s_4_3[2] = { 'i', 'v' };
+
+static const struct among a_4[4] =
+{
+/* 0 */ { 2, s_4_0, -1, -1, 0},
+/* 1 */ { 4, s_4_1, -1, -1, 0},
+/* 2 */ { 2, s_4_2, -1, -1, 0},
+/* 3 */ { 2, s_4_3, -1, 1, 0}
+};
+
+static const symbol s_5_0[2] = { 'i', 'c' };
+static const symbol s_5_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_5_2[2] = { 'i', 'v' };
+
+static const struct among a_5[3] =
+{
+/* 0 */ { 2, s_5_0, -1, 1, 0},
+/* 1 */ { 4, s_5_1, -1, 1, 0},
+/* 2 */ { 2, s_5_2, -1, 1, 0}
+};
+
+static const symbol s_6_0[3] = { 'i', 'c', 'a' };
+static const symbol s_6_1[5] = { 'l', 'o', 'g', 'i', 'a' };
+static const symbol s_6_2[3] = { 'o', 's', 'a' };
+static const symbol s_6_3[4] = { 'i', 's', 't', 'a' };
+static const symbol s_6_4[3] = { 'i', 'v', 'a' };
+static const symbol s_6_5[4] = { 'a', 'n', 'z', 'a' };
+static const symbol s_6_6[4] = { 'e', 'n', 'z', 'a' };
+static const symbol s_6_7[3] = { 'i', 'c', 'e' };
+static const symbol s_6_8[6] = { 'a', 't', 'r', 'i', 'c', 'e' };
+static const symbol s_6_9[4] = { 'i', 'c', 'h', 'e' };
+static const symbol s_6_10[5] = { 'l', 'o', 'g', 'i', 'e' };
+static const symbol s_6_11[5] = { 'a', 'b', 'i', 'l', 'e' };
+static const symbol s_6_12[5] = { 'i', 'b', 'i', 'l', 'e' };
+static const symbol s_6_13[6] = { 'u', 's', 'i', 'o', 'n', 'e' };
+static const symbol s_6_14[6] = { 'a', 'z', 'i', 'o', 'n', 'e' };
+static const symbol s_6_15[6] = { 'u', 'z', 'i', 'o', 'n', 'e' };
+static const symbol s_6_16[5] = { 'a', 't', 'o', 'r', 'e' };
+static const symbol s_6_17[3] = { 'o', 's', 'e' };
+static const symbol s_6_18[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_6_19[5] = { 'm', 'e', 'n', 't', 'e' };
+static const symbol s_6_20[6] = { 'a', 'm', 'e', 'n', 't', 'e' };
+static const symbol s_6_21[4] = { 'i', 's', 't', 'e' };
+static const symbol s_6_22[3] = { 'i', 'v', 'e' };
+static const symbol s_6_23[4] = { 'a', 'n', 'z', 'e' };
+static const symbol s_6_24[4] = { 'e', 'n', 'z', 'e' };
+static const symbol s_6_25[3] = { 'i', 'c', 'i' };
+static const symbol s_6_26[6] = { 'a', 't', 'r', 'i', 'c', 'i' };
+static const symbol s_6_27[4] = { 'i', 'c', 'h', 'i' };
+static const symbol s_6_28[5] = { 'a', 'b', 'i', 'l', 'i' };
+static const symbol s_6_29[5] = { 'i', 'b', 'i', 'l', 'i' };
+static const symbol s_6_30[4] = { 'i', 's', 'm', 'i' };
+static const symbol s_6_31[6] = { 'u', 's', 'i', 'o', 'n', 'i' };
+static const symbol s_6_32[6] = { 'a', 'z', 'i', 'o', 'n', 'i' };
+static const symbol s_6_33[6] = { 'u', 'z', 'i', 'o', 'n', 'i' };
+static const symbol s_6_34[5] = { 'a', 't', 'o', 'r', 'i' };
+static const symbol s_6_35[3] = { 'o', 's', 'i' };
+static const symbol s_6_36[4] = { 'a', 'n', 't', 'i' };
+static const symbol s_6_37[6] = { 'a', 'm', 'e', 'n', 't', 'i' };
+static const symbol s_6_38[6] = { 'i', 'm', 'e', 'n', 't', 'i' };
+static const symbol s_6_39[4] = { 'i', 's', 't', 'i' };
+static const symbol s_6_40[3] = { 'i', 'v', 'i' };
+static const symbol s_6_41[3] = { 'i', 'c', 'o' };
+static const symbol s_6_42[4] = { 'i', 's', 'm', 'o' };
+static const symbol s_6_43[3] = { 'o', 's', 'o' };
+static const symbol s_6_44[6] = { 'a', 'm', 'e', 'n', 't', 'o' };
+static const symbol s_6_45[6] = { 'i', 'm', 'e', 'n', 't', 'o' };
+static const symbol s_6_46[3] = { 'i', 'v', 'o' };
+static const symbol s_6_47[3] = { 'i', 't', 0xE0 };
+static const symbol s_6_48[4] = { 'i', 's', 't', 0xE0 };
+static const symbol s_6_49[4] = { 'i', 's', 't', 0xE8 };
+static const symbol s_6_50[4] = { 'i', 's', 't', 0xEC };
+
+static const struct among a_6[51] =
+{
+/* 0 */ { 3, s_6_0, -1, 1, 0},
+/* 1 */ { 5, s_6_1, -1, 3, 0},
+/* 2 */ { 3, s_6_2, -1, 1, 0},
+/* 3 */ { 4, s_6_3, -1, 1, 0},
+/* 4 */ { 3, s_6_4, -1, 9, 0},
+/* 5 */ { 4, s_6_5, -1, 1, 0},
+/* 6 */ { 4, s_6_6, -1, 5, 0},
+/* 7 */ { 3, s_6_7, -1, 1, 0},
+/* 8 */ { 6, s_6_8, 7, 1, 0},
+/* 9 */ { 4, s_6_9, -1, 1, 0},
+/* 10 */ { 5, s_6_10, -1, 3, 0},
+/* 11 */ { 5, s_6_11, -1, 1, 0},
+/* 12 */ { 5, s_6_12, -1, 1, 0},
+/* 13 */ { 6, s_6_13, -1, 4, 0},
+/* 14 */ { 6, s_6_14, -1, 2, 0},
+/* 15 */ { 6, s_6_15, -1, 4, 0},
+/* 16 */ { 5, s_6_16, -1, 2, 0},
+/* 17 */ { 3, s_6_17, -1, 1, 0},
+/* 18 */ { 4, s_6_18, -1, 1, 0},
+/* 19 */ { 5, s_6_19, -1, 1, 0},
+/* 20 */ { 6, s_6_20, 19, 7, 0},
+/* 21 */ { 4, s_6_21, -1, 1, 0},
+/* 22 */ { 3, s_6_22, -1, 9, 0},
+/* 23 */ { 4, s_6_23, -1, 1, 0},
+/* 24 */ { 4, s_6_24, -1, 5, 0},
+/* 25 */ { 3, s_6_25, -1, 1, 0},
+/* 26 */ { 6, s_6_26, 25, 1, 0},
+/* 27 */ { 4, s_6_27, -1, 1, 0},
+/* 28 */ { 5, s_6_28, -1, 1, 0},
+/* 29 */ { 5, s_6_29, -1, 1, 0},
+/* 30 */ { 4, s_6_30, -1, 1, 0},
+/* 31 */ { 6, s_6_31, -1, 4, 0},
+/* 32 */ { 6, s_6_32, -1, 2, 0},
+/* 33 */ { 6, s_6_33, -1, 4, 0},
+/* 34 */ { 5, s_6_34, -1, 2, 0},
+/* 35 */ { 3, s_6_35, -1, 1, 0},
+/* 36 */ { 4, s_6_36, -1, 1, 0},
+/* 37 */ { 6, s_6_37, -1, 6, 0},
+/* 38 */ { 6, s_6_38, -1, 6, 0},
+/* 39 */ { 4, s_6_39, -1, 1, 0},
+/* 40 */ { 3, s_6_40, -1, 9, 0},
+/* 41 */ { 3, s_6_41, -1, 1, 0},
+/* 42 */ { 4, s_6_42, -1, 1, 0},
+/* 43 */ { 3, s_6_43, -1, 1, 0},
+/* 44 */ { 6, s_6_44, -1, 6, 0},
+/* 45 */ { 6, s_6_45, -1, 6, 0},
+/* 46 */ { 3, s_6_46, -1, 9, 0},
+/* 47 */ { 3, s_6_47, -1, 8, 0},
+/* 48 */ { 4, s_6_48, -1, 1, 0},
+/* 49 */ { 4, s_6_49, -1, 1, 0},
+/* 50 */ { 4, s_6_50, -1, 1, 0}
+};
+
+static const symbol s_7_0[4] = { 'i', 's', 'c', 'a' };
+static const symbol s_7_1[4] = { 'e', 'n', 'd', 'a' };
+static const symbol s_7_2[3] = { 'a', 't', 'a' };
+static const symbol s_7_3[3] = { 'i', 't', 'a' };
+static const symbol s_7_4[3] = { 'u', 't', 'a' };
+static const symbol s_7_5[3] = { 'a', 'v', 'a' };
+static const symbol s_7_6[3] = { 'e', 'v', 'a' };
+static const symbol s_7_7[3] = { 'i', 'v', 'a' };
+static const symbol s_7_8[6] = { 'e', 'r', 'e', 'b', 'b', 'e' };
+static const symbol s_7_9[6] = { 'i', 'r', 'e', 'b', 'b', 'e' };
+static const symbol s_7_10[4] = { 'i', 's', 'c', 'e' };
+static const symbol s_7_11[4] = { 'e', 'n', 'd', 'e' };
+static const symbol s_7_12[3] = { 'a', 'r', 'e' };
+static const symbol s_7_13[3] = { 'e', 'r', 'e' };
+static const symbol s_7_14[3] = { 'i', 'r', 'e' };
+static const symbol s_7_15[4] = { 'a', 's', 's', 'e' };
+static const symbol s_7_16[3] = { 'a', 't', 'e' };
+static const symbol s_7_17[5] = { 'a', 'v', 'a', 't', 'e' };
+static const symbol s_7_18[5] = { 'e', 'v', 'a', 't', 'e' };
+static const symbol s_7_19[5] = { 'i', 'v', 'a', 't', 'e' };
+static const symbol s_7_20[3] = { 'e', 't', 'e' };
+static const symbol s_7_21[5] = { 'e', 'r', 'e', 't', 'e' };
+static const symbol s_7_22[5] = { 'i', 'r', 'e', 't', 'e' };
+static const symbol s_7_23[3] = { 'i', 't', 'e' };
+static const symbol s_7_24[6] = { 'e', 'r', 'e', 's', 't', 'e' };
+static const symbol s_7_25[6] = { 'i', 'r', 'e', 's', 't', 'e' };
+static const symbol s_7_26[3] = { 'u', 't', 'e' };
+static const symbol s_7_27[4] = { 'e', 'r', 'a', 'i' };
+static const symbol s_7_28[4] = { 'i', 'r', 'a', 'i' };
+static const symbol s_7_29[4] = { 'i', 's', 'c', 'i' };
+static const symbol s_7_30[4] = { 'e', 'n', 'd', 'i' };
+static const symbol s_7_31[4] = { 'e', 'r', 'e', 'i' };
+static const symbol s_7_32[4] = { 'i', 'r', 'e', 'i' };
+static const symbol s_7_33[4] = { 'a', 's', 's', 'i' };
+static const symbol s_7_34[3] = { 'a', 't', 'i' };
+static const symbol s_7_35[3] = { 'i', 't', 'i' };
+static const symbol s_7_36[6] = { 'e', 'r', 'e', 's', 't', 'i' };
+static const symbol s_7_37[6] = { 'i', 'r', 'e', 's', 't', 'i' };
+static const symbol s_7_38[3] = { 'u', 't', 'i' };
+static const symbol s_7_39[3] = { 'a', 'v', 'i' };
+static const symbol s_7_40[3] = { 'e', 'v', 'i' };
+static const symbol s_7_41[3] = { 'i', 'v', 'i' };
+static const symbol s_7_42[4] = { 'i', 's', 'c', 'o' };
+static const symbol s_7_43[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_7_44[4] = { 'e', 'n', 'd', 'o' };
+static const symbol s_7_45[4] = { 'Y', 'a', 'm', 'o' };
+static const symbol s_7_46[4] = { 'i', 'a', 'm', 'o' };
+static const symbol s_7_47[5] = { 'a', 'v', 'a', 'm', 'o' };
+static const symbol s_7_48[5] = { 'e', 'v', 'a', 'm', 'o' };
+static const symbol s_7_49[5] = { 'i', 'v', 'a', 'm', 'o' };
+static const symbol s_7_50[5] = { 'e', 'r', 'e', 'm', 'o' };
+static const symbol s_7_51[5] = { 'i', 'r', 'e', 'm', 'o' };
+static const symbol s_7_52[6] = { 'a', 's', 's', 'i', 'm', 'o' };
+static const symbol s_7_53[4] = { 'a', 'm', 'm', 'o' };
+static const symbol s_7_54[4] = { 'e', 'm', 'm', 'o' };
+static const symbol s_7_55[6] = { 'e', 'r', 'e', 'm', 'm', 'o' };
+static const symbol s_7_56[6] = { 'i', 'r', 'e', 'm', 'm', 'o' };
+static const symbol s_7_57[4] = { 'i', 'm', 'm', 'o' };
+static const symbol s_7_58[3] = { 'a', 'n', 'o' };
+static const symbol s_7_59[6] = { 'i', 's', 'c', 'a', 'n', 'o' };
+static const symbol s_7_60[5] = { 'a', 'v', 'a', 'n', 'o' };
+static const symbol s_7_61[5] = { 'e', 'v', 'a', 'n', 'o' };
+static const symbol s_7_62[5] = { 'i', 'v', 'a', 'n', 'o' };
+static const symbol s_7_63[6] = { 'e', 'r', 'a', 'n', 'n', 'o' };
+static const symbol s_7_64[6] = { 'i', 'r', 'a', 'n', 'n', 'o' };
+static const symbol s_7_65[3] = { 'o', 'n', 'o' };
+static const symbol s_7_66[6] = { 'i', 's', 'c', 'o', 'n', 'o' };
+static const symbol s_7_67[5] = { 'a', 'r', 'o', 'n', 'o' };
+static const symbol s_7_68[5] = { 'e', 'r', 'o', 'n', 'o' };
+static const symbol s_7_69[5] = { 'i', 'r', 'o', 'n', 'o' };
+static const symbol s_7_70[8] = { 'e', 'r', 'e', 'b', 'b', 'e', 'r', 'o' };
+static const symbol s_7_71[8] = { 'i', 'r', 'e', 'b', 'b', 'e', 'r', 'o' };
+static const symbol s_7_72[6] = { 'a', 's', 's', 'e', 'r', 'o' };
+static const symbol s_7_73[6] = { 'e', 's', 's', 'e', 'r', 'o' };
+static const symbol s_7_74[6] = { 'i', 's', 's', 'e', 'r', 'o' };
+static const symbol s_7_75[3] = { 'a', 't', 'o' };
+static const symbol s_7_76[3] = { 'i', 't', 'o' };
+static const symbol s_7_77[3] = { 'u', 't', 'o' };
+static const symbol s_7_78[3] = { 'a', 'v', 'o' };
+static const symbol s_7_79[3] = { 'e', 'v', 'o' };
+static const symbol s_7_80[3] = { 'i', 'v', 'o' };
+static const symbol s_7_81[2] = { 'a', 'r' };
+static const symbol s_7_82[2] = { 'i', 'r' };
+static const symbol s_7_83[3] = { 'e', 'r', 0xE0 };
+static const symbol s_7_84[3] = { 'i', 'r', 0xE0 };
+static const symbol s_7_85[3] = { 'e', 'r', 0xF2 };
+static const symbol s_7_86[3] = { 'i', 'r', 0xF2 };
+
+static const struct among a_7[87] =
+{
+/* 0 */ { 4, s_7_0, -1, 1, 0},
+/* 1 */ { 4, s_7_1, -1, 1, 0},
+/* 2 */ { 3, s_7_2, -1, 1, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0},
+/* 4 */ { 3, s_7_4, -1, 1, 0},
+/* 5 */ { 3, s_7_5, -1, 1, 0},
+/* 6 */ { 3, s_7_6, -1, 1, 0},
+/* 7 */ { 3, s_7_7, -1, 1, 0},
+/* 8 */ { 6, s_7_8, -1, 1, 0},
+/* 9 */ { 6, s_7_9, -1, 1, 0},
+/* 10 */ { 4, s_7_10, -1, 1, 0},
+/* 11 */ { 4, s_7_11, -1, 1, 0},
+/* 12 */ { 3, s_7_12, -1, 1, 0},
+/* 13 */ { 3, s_7_13, -1, 1, 0},
+/* 14 */ { 3, s_7_14, -1, 1, 0},
+/* 15 */ { 4, s_7_15, -1, 1, 0},
+/* 16 */ { 3, s_7_16, -1, 1, 0},
+/* 17 */ { 5, s_7_17, 16, 1, 0},
+/* 18 */ { 5, s_7_18, 16, 1, 0},
+/* 19 */ { 5, s_7_19, 16, 1, 0},
+/* 20 */ { 3, s_7_20, -1, 1, 0},
+/* 21 */ { 5, s_7_21, 20, 1, 0},
+/* 22 */ { 5, s_7_22, 20, 1, 0},
+/* 23 */ { 3, s_7_23, -1, 1, 0},
+/* 24 */ { 6, s_7_24, -1, 1, 0},
+/* 25 */ { 6, s_7_25, -1, 1, 0},
+/* 26 */ { 3, s_7_26, -1, 1, 0},
+/* 27 */ { 4, s_7_27, -1, 1, 0},
+/* 28 */ { 4, s_7_28, -1, 1, 0},
+/* 29 */ { 4, s_7_29, -1, 1, 0},
+/* 30 */ { 4, s_7_30, -1, 1, 0},
+/* 31 */ { 4, s_7_31, -1, 1, 0},
+/* 32 */ { 4, s_7_32, -1, 1, 0},
+/* 33 */ { 4, s_7_33, -1, 1, 0},
+/* 34 */ { 3, s_7_34, -1, 1, 0},
+/* 35 */ { 3, s_7_35, -1, 1, 0},
+/* 36 */ { 6, s_7_36, -1, 1, 0},
+/* 37 */ { 6, s_7_37, -1, 1, 0},
+/* 38 */ { 3, s_7_38, -1, 1, 0},
+/* 39 */ { 3, s_7_39, -1, 1, 0},
+/* 40 */ { 3, s_7_40, -1, 1, 0},
+/* 41 */ { 3, s_7_41, -1, 1, 0},
+/* 42 */ { 4, s_7_42, -1, 1, 0},
+/* 43 */ { 4, s_7_43, -1, 1, 0},
+/* 44 */ { 4, s_7_44, -1, 1, 0},
+/* 45 */ { 4, s_7_45, -1, 1, 0},
+/* 46 */ { 4, s_7_46, -1, 1, 0},
+/* 47 */ { 5, s_7_47, -1, 1, 0},
+/* 48 */ { 5, s_7_48, -1, 1, 0},
+/* 49 */ { 5, s_7_49, -1, 1, 0},
+/* 50 */ { 5, s_7_50, -1, 1, 0},
+/* 51 */ { 5, s_7_51, -1, 1, 0},
+/* 52 */ { 6, s_7_52, -1, 1, 0},
+/* 53 */ { 4, s_7_53, -1, 1, 0},
+/* 54 */ { 4, s_7_54, -1, 1, 0},
+/* 55 */ { 6, s_7_55, 54, 1, 0},
+/* 56 */ { 6, s_7_56, 54, 1, 0},
+/* 57 */ { 4, s_7_57, -1, 1, 0},
+/* 58 */ { 3, s_7_58, -1, 1, 0},
+/* 59 */ { 6, s_7_59, 58, 1, 0},
+/* 60 */ { 5, s_7_60, 58, 1, 0},
+/* 61 */ { 5, s_7_61, 58, 1, 0},
+/* 62 */ { 5, s_7_62, 58, 1, 0},
+/* 63 */ { 6, s_7_63, -1, 1, 0},
+/* 64 */ { 6, s_7_64, -1, 1, 0},
+/* 65 */ { 3, s_7_65, -1, 1, 0},
+/* 66 */ { 6, s_7_66, 65, 1, 0},
+/* 67 */ { 5, s_7_67, 65, 1, 0},
+/* 68 */ { 5, s_7_68, 65, 1, 0},
+/* 69 */ { 5, s_7_69, 65, 1, 0},
+/* 70 */ { 8, s_7_70, -1, 1, 0},
+/* 71 */ { 8, s_7_71, -1, 1, 0},
+/* 72 */ { 6, s_7_72, -1, 1, 0},
+/* 73 */ { 6, s_7_73, -1, 1, 0},
+/* 74 */ { 6, s_7_74, -1, 1, 0},
+/* 75 */ { 3, s_7_75, -1, 1, 0},
+/* 76 */ { 3, s_7_76, -1, 1, 0},
+/* 77 */ { 3, s_7_77, -1, 1, 0},
+/* 78 */ { 3, s_7_78, -1, 1, 0},
+/* 79 */ { 3, s_7_79, -1, 1, 0},
+/* 80 */ { 3, s_7_80, -1, 1, 0},
+/* 81 */ { 2, s_7_81, -1, 1, 0},
+/* 82 */ { 2, s_7_82, -1, 1, 0},
+/* 83 */ { 3, s_7_83, -1, 1, 0},
+/* 84 */ { 3, s_7_84, -1, 1, 0},
+/* 85 */ { 3, s_7_85, -1, 1, 0},
+/* 86 */ { 3, s_7_86, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1 };
+
+static const unsigned char g_AEIO[] = { 17, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2 };
+
+static const unsigned char g_CG[] = { 17 };
+
+static const symbol s_0[] = { 0xE0 };
+static const symbol s_1[] = { 0xE8 };
+static const symbol s_2[] = { 0xEC };
+static const symbol s_3[] = { 0xF2 };
+static const symbol s_4[] = { 0xF9 };
+static const symbol s_5[] = { 'q', 'U' };
+static const symbol s_6[] = { 'u' };
+static const symbol s_7[] = { 'U' };
+static const symbol s_8[] = { 'i' };
+static const symbol s_9[] = { 'I' };
+static const symbol s_10[] = { 'i' };
+static const symbol s_11[] = { 'u' };
+static const symbol s_12[] = { 'e' };
+static const symbol s_13[] = { 'i', 'c' };
+static const symbol s_14[] = { 'l', 'o', 'g' };
+static const symbol s_15[] = { 'u' };
+static const symbol s_16[] = { 'e', 'n', 't', 'e' };
+static const symbol s_17[] = { 'a', 't' };
+static const symbol s_18[] = { 'a', 't' };
+static const symbol s_19[] = { 'i', 'c' };
+static const symbol s_20[] = { 'i' };
+static const symbol s_21[] = { 'h' };
+
+static int r_prelude(struct SN_env * z) {
+ int among_var;
+ { int c_test = z->c; /* test, line 35 */
+ while(1) { /* repeat, line 35 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 36 */
+ among_var = find_among(z, a_0, 7); /* substring, line 36 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 36 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_0); /* <-, line 37 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 38 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 39 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 40 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 41 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 2, s_5); /* <-, line 42 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 43 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ z->c = c_test;
+ }
+ while(1) { /* repeat, line 46 */
+ int c2 = z->c;
+ while(1) { /* goto, line 46 */
+ int c3 = z->c;
+ if (in_grouping(z, g_v, 97, 249, 0)) goto lab2;
+ z->bra = z->c; /* [, line 47 */
+ { int c4 = z->c; /* or, line 47 */
+ if (!(eq_s(z, 1, s_6))) goto lab4;
+ z->ket = z->c; /* ], line 47 */
+ if (in_grouping(z, g_v, 97, 249, 0)) goto lab4;
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 47 */
+ if (ret < 0) return ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c4;
+ if (!(eq_s(z, 1, s_8))) goto lab2;
+ z->ket = z->c; /* ], line 48 */
+ if (in_grouping(z, g_v, 97, 249, 0)) goto lab2;
+ { int ret = slice_from_s(z, 1, s_9); /* <-, line 48 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab3:
+ z->c = c3;
+ break;
+ lab2:
+ z->c = c3;
+ if (z->c >= z->l) goto lab1;
+ z->c++; /* goto, line 46 */
+ }
+ continue;
+ lab1:
+ z->c = c2;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 58 */
+ { int c2 = z->c; /* or, line 60 */
+ if (in_grouping(z, g_v, 97, 249, 0)) goto lab2;
+ { int c3 = z->c; /* or, line 59 */
+ if (out_grouping(z, g_v, 97, 249, 0)) goto lab4;
+ { /* gopast */ /* grouping v, line 59 */
+ int ret = out_grouping(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c3;
+ if (in_grouping(z, g_v, 97, 249, 0)) goto lab2;
+ { /* gopast */ /* non v, line 59 */
+ int ret = in_grouping(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab2;
+ z->c += ret;
+ }
+ }
+ lab3:
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (out_grouping(z, g_v, 97, 249, 0)) goto lab0;
+ { int c4 = z->c; /* or, line 61 */
+ if (out_grouping(z, g_v, 97, 249, 0)) goto lab6;
+ { /* gopast */ /* grouping v, line 61 */
+ int ret = out_grouping(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab6;
+ z->c += ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c4;
+ if (in_grouping(z, g_v, 97, 249, 0)) goto lab0;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 61 */
+ }
+ lab5:
+ ;
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 62 */
+ lab0:
+ z->c = c1;
+ }
+ { int c5 = z->c; /* do, line 64 */
+ { /* gopast */ /* grouping v, line 65 */
+ int ret = out_grouping(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 65 */
+ int ret = in_grouping(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 65 */
+ { /* gopast */ /* grouping v, line 66 */
+ int ret = out_grouping(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 66 */
+ int ret = in_grouping(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 66 */
+ lab7:
+ z->c = c5;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 70 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 72 */
+ if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else
+ among_var = find_among(z, a_1, 3); /* substring, line 72 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 72 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 73 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_11); /* <-, line 74 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 75 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_attached_pronoun(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 87 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_2, 37))) return 0; /* substring, line 87 */
+ z->bra = z->c; /* ], line 87 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0;
+ among_var = find_among_b(z, a_3, 5); /* among, line 97 */
+ if (!(among_var)) return 0;
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 97 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 98 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_12); /* <-, line 99 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 104 */
+ among_var = find_among_b(z, a_6, 51); /* substring, line 104 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 104 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 111 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 111 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 113 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 113 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 114 */
+ z->ket = z->c; /* [, line 114 */
+ if (!(eq_s_b(z, 2, s_13))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 114 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 114 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 114 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 117 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_14); /* <-, line 117 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 119 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_15); /* <-, line 119 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 121 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 4, s_16); /* <-, line 121 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 123 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 123 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 125 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 125 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 126 */
+ z->ket = z->c; /* [, line 127 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab1; }
+ among_var = find_among_b(z, a_4, 4); /* substring, line 127 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 127 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 127 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 127 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab1; }
+ case 1:
+ z->ket = z->c; /* [, line 128 */
+ if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 128 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 128 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 128 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab1:
+ ;
+ }
+ break;
+ case 8:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 135 */
+ z->ket = z->c; /* [, line 136 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab2; }
+ among_var = find_among_b(z, a_5, 3); /* substring, line 136 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab2; }
+ z->bra = z->c; /* ], line 136 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab2; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 137 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 137 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab2:
+ ;
+ }
+ break;
+ case 9:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 142 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 142 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 143 */
+ z->ket = z->c; /* [, line 143 */
+ if (!(eq_s_b(z, 2, s_18))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 143 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 143 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 143 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 143 */
+ if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 143 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 143 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 143 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ ;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 148 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 148 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 149 */
+ among_var = find_among_b(z, a_7, 87); /* substring, line 149 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 149 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 163 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_vowel_suffix(struct SN_env * z) {
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 171 */
+ z->ket = z->c; /* [, line 172 */
+ if (in_grouping_b(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 172 */
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 172 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 172 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 173 */
+ if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 173 */
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 173 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 173 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 175 */
+ z->ket = z->c; /* [, line 176 */
+ if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 176 */
+ if (in_grouping_b(z, g_CG, 99, 103, 0)) { z->c = z->l - m_keep; goto lab1; }
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call RV, line 176 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 176 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ ;
+ }
+ return 1;
+}
+
+extern int italian_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 182 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 182 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 183 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 183 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 184 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 185 */
+ { int ret = r_attached_pronoun(z);
+ if (ret == 0) goto lab2; /* call attached_pronoun, line 185 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 186 */
+ { int m5 = z->l - z->c; (void)m5; /* or, line 186 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab5; /* call standard_suffix, line 186 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab5:
+ z->c = z->l - m5;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab3; /* call verb_suffix, line 186 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab4:
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* do, line 187 */
+ { int ret = r_vowel_suffix(z);
+ if (ret == 0) goto lab6; /* call vowel_suffix, line 187 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m6;
+ }
+ z->c = z->lb;
+ { int c7 = z->c; /* do, line 189 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab7; /* call postlude, line 189 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = c7;
+ }
+ return 1;
+}
+
+extern struct SN_env * italian_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void italian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c
new file mode 100644
index 00000000000..2debf1082d8
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c
@@ -0,0 +1,297 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int norwegian_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_other_suffix(struct SN_env * z);
+static int r_consonant_pair(struct SN_env * z);
+static int r_main_suffix(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * norwegian_ISO_8859_1_create_env(void);
+extern void norwegian_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[1] = { 'a' };
+static const symbol s_0_1[1] = { 'e' };
+static const symbol s_0_2[3] = { 'e', 'd', 'e' };
+static const symbol s_0_3[4] = { 'a', 'n', 'd', 'e' };
+static const symbol s_0_4[4] = { 'e', 'n', 'd', 'e' };
+static const symbol s_0_5[3] = { 'a', 'n', 'e' };
+static const symbol s_0_6[3] = { 'e', 'n', 'e' };
+static const symbol s_0_7[6] = { 'h', 'e', 't', 'e', 'n', 'e' };
+static const symbol s_0_8[4] = { 'e', 'r', 't', 'e' };
+static const symbol s_0_9[2] = { 'e', 'n' };
+static const symbol s_0_10[5] = { 'h', 'e', 't', 'e', 'n' };
+static const symbol s_0_11[2] = { 'a', 'r' };
+static const symbol s_0_12[2] = { 'e', 'r' };
+static const symbol s_0_13[5] = { 'h', 'e', 't', 'e', 'r' };
+static const symbol s_0_14[1] = { 's' };
+static const symbol s_0_15[2] = { 'a', 's' };
+static const symbol s_0_16[2] = { 'e', 's' };
+static const symbol s_0_17[4] = { 'e', 'd', 'e', 's' };
+static const symbol s_0_18[5] = { 'e', 'n', 'd', 'e', 's' };
+static const symbol s_0_19[4] = { 'e', 'n', 'e', 's' };
+static const symbol s_0_20[7] = { 'h', 'e', 't', 'e', 'n', 'e', 's' };
+static const symbol s_0_21[3] = { 'e', 'n', 's' };
+static const symbol s_0_22[6] = { 'h', 'e', 't', 'e', 'n', 's' };
+static const symbol s_0_23[3] = { 'e', 'r', 's' };
+static const symbol s_0_24[3] = { 'e', 't', 's' };
+static const symbol s_0_25[2] = { 'e', 't' };
+static const symbol s_0_26[3] = { 'h', 'e', 't' };
+static const symbol s_0_27[3] = { 'e', 'r', 't' };
+static const symbol s_0_28[3] = { 'a', 's', 't' };
+
+static const struct among a_0[29] =
+{
+/* 0 */ { 1, s_0_0, -1, 1, 0},
+/* 1 */ { 1, s_0_1, -1, 1, 0},
+/* 2 */ { 3, s_0_2, 1, 1, 0},
+/* 3 */ { 4, s_0_3, 1, 1, 0},
+/* 4 */ { 4, s_0_4, 1, 1, 0},
+/* 5 */ { 3, s_0_5, 1, 1, 0},
+/* 6 */ { 3, s_0_6, 1, 1, 0},
+/* 7 */ { 6, s_0_7, 6, 1, 0},
+/* 8 */ { 4, s_0_8, 1, 3, 0},
+/* 9 */ { 2, s_0_9, -1, 1, 0},
+/* 10 */ { 5, s_0_10, 9, 1, 0},
+/* 11 */ { 2, s_0_11, -1, 1, 0},
+/* 12 */ { 2, s_0_12, -1, 1, 0},
+/* 13 */ { 5, s_0_13, 12, 1, 0},
+/* 14 */ { 1, s_0_14, -1, 2, 0},
+/* 15 */ { 2, s_0_15, 14, 1, 0},
+/* 16 */ { 2, s_0_16, 14, 1, 0},
+/* 17 */ { 4, s_0_17, 16, 1, 0},
+/* 18 */ { 5, s_0_18, 16, 1, 0},
+/* 19 */ { 4, s_0_19, 16, 1, 0},
+/* 20 */ { 7, s_0_20, 19, 1, 0},
+/* 21 */ { 3, s_0_21, 14, 1, 0},
+/* 22 */ { 6, s_0_22, 21, 1, 0},
+/* 23 */ { 3, s_0_23, 14, 1, 0},
+/* 24 */ { 3, s_0_24, 14, 1, 0},
+/* 25 */ { 2, s_0_25, -1, 1, 0},
+/* 26 */ { 3, s_0_26, 25, 1, 0},
+/* 27 */ { 3, s_0_27, -1, 3, 0},
+/* 28 */ { 3, s_0_28, -1, 1, 0}
+};
+
+static const symbol s_1_0[2] = { 'd', 't' };
+static const symbol s_1_1[2] = { 'v', 't' };
+
+static const struct among a_1[2] =
+{
+/* 0 */ { 2, s_1_0, -1, -1, 0},
+/* 1 */ { 2, s_1_1, -1, -1, 0}
+};
+
+static const symbol s_2_0[3] = { 'l', 'e', 'g' };
+static const symbol s_2_1[4] = { 'e', 'l', 'e', 'g' };
+static const symbol s_2_2[2] = { 'i', 'g' };
+static const symbol s_2_3[3] = { 'e', 'i', 'g' };
+static const symbol s_2_4[3] = { 'l', 'i', 'g' };
+static const symbol s_2_5[4] = { 'e', 'l', 'i', 'g' };
+static const symbol s_2_6[3] = { 'e', 'l', 's' };
+static const symbol s_2_7[3] = { 'l', 'o', 'v' };
+static const symbol s_2_8[4] = { 'e', 'l', 'o', 'v' };
+static const symbol s_2_9[4] = { 's', 'l', 'o', 'v' };
+static const symbol s_2_10[7] = { 'h', 'e', 't', 's', 'l', 'o', 'v' };
+
+static const struct among a_2[11] =
+{
+/* 0 */ { 3, s_2_0, -1, 1, 0},
+/* 1 */ { 4, s_2_1, 0, 1, 0},
+/* 2 */ { 2, s_2_2, -1, 1, 0},
+/* 3 */ { 3, s_2_3, 2, 1, 0},
+/* 4 */ { 3, s_2_4, 2, 1, 0},
+/* 5 */ { 4, s_2_5, 4, 1, 0},
+/* 6 */ { 3, s_2_6, -1, 1, 0},
+/* 7 */ { 3, s_2_7, -1, 1, 0},
+/* 8 */ { 4, s_2_8, 7, 1, 0},
+/* 9 */ { 4, s_2_9, 7, 1, 0},
+/* 10 */ { 7, s_2_10, 9, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 };
+
+static const unsigned char g_s_ending[] = { 119, 125, 149, 1 };
+
+static const symbol s_0[] = { 'k' };
+static const symbol s_1[] = { 'e', 'r' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ { int c_test = z->c; /* test, line 30 */
+ { int ret = z->c + 3;
+ if (0 > ret || ret > z->l) return 0;
+ z->c = ret; /* hop, line 30 */
+ }
+ z->I[1] = z->c; /* setmark x, line 30 */
+ z->c = c_test;
+ }
+ if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 31 */
+ { /* gopast */ /* non v, line 31 */
+ int ret = in_grouping(z, g_v, 97, 248, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 31 */
+ /* try, line 32 */
+ if (!(z->I[0] < z->I[1])) goto lab0;
+ z->I[0] = z->I[1];
+lab0:
+ return 1;
+}
+
+static int r_main_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 38 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 38 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 38 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_0, 29); /* substring, line 38 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 38 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 44 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m2 = z->l - z->c; (void)m2; /* or, line 46 */
+ if (in_grouping_b(z, g_s_ending, 98, 122, 0)) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m2;
+ if (!(eq_s_b(z, 1, s_0))) return 0;
+ if (out_grouping_b(z, g_v, 97, 248, 0)) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 46 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 2, s_1); /* <-, line 48 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_consonant_pair(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 53 */
+ { int mlimit; /* setlimit, line 54 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 54 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 54 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit; return 0; }
+ if (!(find_among_b(z, a_1, 2))) { z->lb = mlimit; return 0; } /* substring, line 54 */
+ z->bra = z->c; /* ], line 54 */
+ z->lb = mlimit;
+ }
+ z->c = z->l - m_test;
+ }
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 59 */
+ z->bra = z->c; /* ], line 59 */
+ { int ret = slice_del(z); /* delete, line 59 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_other_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 63 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 63 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 63 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_2, 11); /* substring, line 63 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 63 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 67 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int norwegian_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 74 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 74 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 75 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 76 */
+ { int ret = r_main_suffix(z);
+ if (ret == 0) goto lab1; /* call main_suffix, line 76 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 77 */
+ { int ret = r_consonant_pair(z);
+ if (ret == 0) goto lab2; /* call consonant_pair, line 77 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 78 */
+ { int ret = r_other_suffix(z);
+ if (ret == 0) goto lab3; /* call other_suffix, line 78 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * norwegian_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); }
+
+extern void norwegian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c
new file mode 100644
index 00000000000..69e4fc4c1f2
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c
@@ -0,0 +1,749 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int porter_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_Step_5b(struct SN_env * z);
+static int r_Step_5a(struct SN_env * z);
+static int r_Step_4(struct SN_env * z);
+static int r_Step_3(struct SN_env * z);
+static int r_Step_2(struct SN_env * z);
+static int r_Step_1c(struct SN_env * z);
+static int r_Step_1b(struct SN_env * z);
+static int r_Step_1a(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_shortv(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * porter_ISO_8859_1_create_env(void);
+extern void porter_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[1] = { 's' };
+static const symbol s_0_1[3] = { 'i', 'e', 's' };
+static const symbol s_0_2[4] = { 's', 's', 'e', 's' };
+static const symbol s_0_3[2] = { 's', 's' };
+
+static const struct among a_0[4] =
+{
+/* 0 */ { 1, s_0_0, -1, 3, 0},
+/* 1 */ { 3, s_0_1, 0, 2, 0},
+/* 2 */ { 4, s_0_2, 0, 1, 0},
+/* 3 */ { 2, s_0_3, 0, -1, 0}
+};
+
+static const symbol s_1_1[2] = { 'b', 'b' };
+static const symbol s_1_2[2] = { 'd', 'd' };
+static const symbol s_1_3[2] = { 'f', 'f' };
+static const symbol s_1_4[2] = { 'g', 'g' };
+static const symbol s_1_5[2] = { 'b', 'l' };
+static const symbol s_1_6[2] = { 'm', 'm' };
+static const symbol s_1_7[2] = { 'n', 'n' };
+static const symbol s_1_8[2] = { 'p', 'p' };
+static const symbol s_1_9[2] = { 'r', 'r' };
+static const symbol s_1_10[2] = { 'a', 't' };
+static const symbol s_1_11[2] = { 't', 't' };
+static const symbol s_1_12[2] = { 'i', 'z' };
+
+static const struct among a_1[13] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 2, s_1_1, 0, 2, 0},
+/* 2 */ { 2, s_1_2, 0, 2, 0},
+/* 3 */ { 2, s_1_3, 0, 2, 0},
+/* 4 */ { 2, s_1_4, 0, 2, 0},
+/* 5 */ { 2, s_1_5, 0, 1, 0},
+/* 6 */ { 2, s_1_6, 0, 2, 0},
+/* 7 */ { 2, s_1_7, 0, 2, 0},
+/* 8 */ { 2, s_1_8, 0, 2, 0},
+/* 9 */ { 2, s_1_9, 0, 2, 0},
+/* 10 */ { 2, s_1_10, 0, 1, 0},
+/* 11 */ { 2, s_1_11, 0, 2, 0},
+/* 12 */ { 2, s_1_12, 0, 1, 0}
+};
+
+static const symbol s_2_0[2] = { 'e', 'd' };
+static const symbol s_2_1[3] = { 'e', 'e', 'd' };
+static const symbol s_2_2[3] = { 'i', 'n', 'g' };
+
+static const struct among a_2[3] =
+{
+/* 0 */ { 2, s_2_0, -1, 2, 0},
+/* 1 */ { 3, s_2_1, 0, 1, 0},
+/* 2 */ { 3, s_2_2, -1, 2, 0}
+};
+
+static const symbol s_3_0[4] = { 'a', 'n', 'c', 'i' };
+static const symbol s_3_1[4] = { 'e', 'n', 'c', 'i' };
+static const symbol s_3_2[4] = { 'a', 'b', 'l', 'i' };
+static const symbol s_3_3[3] = { 'e', 'l', 'i' };
+static const symbol s_3_4[4] = { 'a', 'l', 'l', 'i' };
+static const symbol s_3_5[5] = { 'o', 'u', 's', 'l', 'i' };
+static const symbol s_3_6[5] = { 'e', 'n', 't', 'l', 'i' };
+static const symbol s_3_7[5] = { 'a', 'l', 'i', 't', 'i' };
+static const symbol s_3_8[6] = { 'b', 'i', 'l', 'i', 't', 'i' };
+static const symbol s_3_9[5] = { 'i', 'v', 'i', 't', 'i' };
+static const symbol s_3_10[6] = { 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_3_11[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_3_12[5] = { 'a', 'l', 'i', 's', 'm' };
+static const symbol s_3_13[5] = { 'a', 't', 'i', 'o', 'n' };
+static const symbol s_3_14[7] = { 'i', 'z', 'a', 't', 'i', 'o', 'n' };
+static const symbol s_3_15[4] = { 'i', 'z', 'e', 'r' };
+static const symbol s_3_16[4] = { 'a', 't', 'o', 'r' };
+static const symbol s_3_17[7] = { 'i', 'v', 'e', 'n', 'e', 's', 's' };
+static const symbol s_3_18[7] = { 'f', 'u', 'l', 'n', 'e', 's', 's' };
+static const symbol s_3_19[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' };
+
+static const struct among a_3[20] =
+{
+/* 0 */ { 4, s_3_0, -1, 3, 0},
+/* 1 */ { 4, s_3_1, -1, 2, 0},
+/* 2 */ { 4, s_3_2, -1, 4, 0},
+/* 3 */ { 3, s_3_3, -1, 6, 0},
+/* 4 */ { 4, s_3_4, -1, 9, 0},
+/* 5 */ { 5, s_3_5, -1, 12, 0},
+/* 6 */ { 5, s_3_6, -1, 5, 0},
+/* 7 */ { 5, s_3_7, -1, 10, 0},
+/* 8 */ { 6, s_3_8, -1, 14, 0},
+/* 9 */ { 5, s_3_9, -1, 13, 0},
+/* 10 */ { 6, s_3_10, -1, 1, 0},
+/* 11 */ { 7, s_3_11, 10, 8, 0},
+/* 12 */ { 5, s_3_12, -1, 10, 0},
+/* 13 */ { 5, s_3_13, -1, 8, 0},
+/* 14 */ { 7, s_3_14, 13, 7, 0},
+/* 15 */ { 4, s_3_15, -1, 7, 0},
+/* 16 */ { 4, s_3_16, -1, 8, 0},
+/* 17 */ { 7, s_3_17, -1, 13, 0},
+/* 18 */ { 7, s_3_18, -1, 11, 0},
+/* 19 */ { 7, s_3_19, -1, 12, 0}
+};
+
+static const symbol s_4_0[5] = { 'i', 'c', 'a', 't', 'e' };
+static const symbol s_4_1[5] = { 'a', 't', 'i', 'v', 'e' };
+static const symbol s_4_2[5] = { 'a', 'l', 'i', 'z', 'e' };
+static const symbol s_4_3[5] = { 'i', 'c', 'i', 't', 'i' };
+static const symbol s_4_4[4] = { 'i', 'c', 'a', 'l' };
+static const symbol s_4_5[3] = { 'f', 'u', 'l' };
+static const symbol s_4_6[4] = { 'n', 'e', 's', 's' };
+
+static const struct among a_4[7] =
+{
+/* 0 */ { 5, s_4_0, -1, 2, 0},
+/* 1 */ { 5, s_4_1, -1, 3, 0},
+/* 2 */ { 5, s_4_2, -1, 1, 0},
+/* 3 */ { 5, s_4_3, -1, 2, 0},
+/* 4 */ { 4, s_4_4, -1, 2, 0},
+/* 5 */ { 3, s_4_5, -1, 3, 0},
+/* 6 */ { 4, s_4_6, -1, 3, 0}
+};
+
+static const symbol s_5_0[2] = { 'i', 'c' };
+static const symbol s_5_1[4] = { 'a', 'n', 'c', 'e' };
+static const symbol s_5_2[4] = { 'e', 'n', 'c', 'e' };
+static const symbol s_5_3[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_5_4[4] = { 'i', 'b', 'l', 'e' };
+static const symbol s_5_5[3] = { 'a', 't', 'e' };
+static const symbol s_5_6[3] = { 'i', 'v', 'e' };
+static const symbol s_5_7[3] = { 'i', 'z', 'e' };
+static const symbol s_5_8[3] = { 'i', 't', 'i' };
+static const symbol s_5_9[2] = { 'a', 'l' };
+static const symbol s_5_10[3] = { 'i', 's', 'm' };
+static const symbol s_5_11[3] = { 'i', 'o', 'n' };
+static const symbol s_5_12[2] = { 'e', 'r' };
+static const symbol s_5_13[3] = { 'o', 'u', 's' };
+static const symbol s_5_14[3] = { 'a', 'n', 't' };
+static const symbol s_5_15[3] = { 'e', 'n', 't' };
+static const symbol s_5_16[4] = { 'm', 'e', 'n', 't' };
+static const symbol s_5_17[5] = { 'e', 'm', 'e', 'n', 't' };
+static const symbol s_5_18[2] = { 'o', 'u' };
+
+static const struct among a_5[19] =
+{
+/* 0 */ { 2, s_5_0, -1, 1, 0},
+/* 1 */ { 4, s_5_1, -1, 1, 0},
+/* 2 */ { 4, s_5_2, -1, 1, 0},
+/* 3 */ { 4, s_5_3, -1, 1, 0},
+/* 4 */ { 4, s_5_4, -1, 1, 0},
+/* 5 */ { 3, s_5_5, -1, 1, 0},
+/* 6 */ { 3, s_5_6, -1, 1, 0},
+/* 7 */ { 3, s_5_7, -1, 1, 0},
+/* 8 */ { 3, s_5_8, -1, 1, 0},
+/* 9 */ { 2, s_5_9, -1, 1, 0},
+/* 10 */ { 3, s_5_10, -1, 1, 0},
+/* 11 */ { 3, s_5_11, -1, 2, 0},
+/* 12 */ { 2, s_5_12, -1, 1, 0},
+/* 13 */ { 3, s_5_13, -1, 1, 0},
+/* 14 */ { 3, s_5_14, -1, 1, 0},
+/* 15 */ { 3, s_5_15, -1, 1, 0},
+/* 16 */ { 4, s_5_16, 15, 1, 0},
+/* 17 */ { 5, s_5_17, 16, 1, 0},
+/* 18 */ { 2, s_5_18, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1 };
+
+static const unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 };
+
+static const symbol s_0[] = { 's', 's' };
+static const symbol s_1[] = { 'i' };
+static const symbol s_2[] = { 'e', 'e' };
+static const symbol s_3[] = { 'e' };
+static const symbol s_4[] = { 'e' };
+static const symbol s_5[] = { 'y' };
+static const symbol s_6[] = { 'Y' };
+static const symbol s_7[] = { 'i' };
+static const symbol s_8[] = { 't', 'i', 'o', 'n' };
+static const symbol s_9[] = { 'e', 'n', 'c', 'e' };
+static const symbol s_10[] = { 'a', 'n', 'c', 'e' };
+static const symbol s_11[] = { 'a', 'b', 'l', 'e' };
+static const symbol s_12[] = { 'e', 'n', 't' };
+static const symbol s_13[] = { 'e' };
+static const symbol s_14[] = { 'i', 'z', 'e' };
+static const symbol s_15[] = { 'a', 't', 'e' };
+static const symbol s_16[] = { 'a', 'l' };
+static const symbol s_17[] = { 'a', 'l' };
+static const symbol s_18[] = { 'f', 'u', 'l' };
+static const symbol s_19[] = { 'o', 'u', 's' };
+static const symbol s_20[] = { 'i', 'v', 'e' };
+static const symbol s_21[] = { 'b', 'l', 'e' };
+static const symbol s_22[] = { 'a', 'l' };
+static const symbol s_23[] = { 'i', 'c' };
+static const symbol s_24[] = { 's' };
+static const symbol s_25[] = { 't' };
+static const symbol s_26[] = { 'e' };
+static const symbol s_27[] = { 'l' };
+static const symbol s_28[] = { 'l' };
+static const symbol s_29[] = { 'y' };
+static const symbol s_30[] = { 'Y' };
+static const symbol s_31[] = { 'y' };
+static const symbol s_32[] = { 'Y' };
+static const symbol s_33[] = { 'Y' };
+static const symbol s_34[] = { 'y' };
+
+static int r_shortv(struct SN_env * z) {
+ if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) return 0;
+ if (in_grouping_b(z, g_v, 97, 121, 0)) return 0;
+ if (out_grouping_b(z, g_v, 97, 121, 0)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_Step_1a(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 25 */
+ if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0;
+ among_var = find_among_b(z, a_0, 4); /* substring, line 25 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 25 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_0); /* <-, line 26 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 27 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 29 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_1b(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 34 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0;
+ among_var = find_among_b(z, a_2, 3); /* substring, line 34 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 34 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 35 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 2, s_2); /* <-, line 35 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m_test = z->l - z->c; /* test, line 38 */
+ { /* gopast */ /* grouping v, line 38 */
+ int ret = out_grouping_b(z, g_v, 97, 121, 1);
+ if (ret < 0) return 0;
+ z->c -= ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 38 */
+ if (ret < 0) return ret;
+ }
+ { int m_test = z->l - z->c; /* test, line 39 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else
+ among_var = find_among_b(z, a_1, 13); /* substring, line 39 */
+ if (!(among_var)) return 0;
+ z->c = z->l - m_test;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ z->ket = z->c; /* [, line 44 */
+ if (z->c <= z->lb) return 0;
+ z->c--; /* next, line 44 */
+ z->bra = z->c; /* ], line 44 */
+ { int ret = slice_del(z); /* delete, line 44 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c != z->I[0]) return 0; /* atmark, line 45 */
+ { int m_test = z->l - z->c; /* test, line 45 */
+ { int ret = r_shortv(z);
+ if (ret == 0) return 0; /* call shortv, line 45 */
+ if (ret < 0) return ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_1c(struct SN_env * z) {
+ z->ket = z->c; /* [, line 52 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 52 */
+ if (!(eq_s_b(z, 1, s_5))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_6))) return 0;
+ }
+lab0:
+ z->bra = z->c; /* ], line 52 */
+ { /* gopast */ /* grouping v, line 53 */
+ int ret = out_grouping_b(z, g_v, 97, 121, 1);
+ if (ret < 0) return 0;
+ z->c -= ret;
+ }
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 54 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_Step_2(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 58 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_3, 20); /* substring, line 58 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 58 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 58 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 4, s_8); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 4, s_9); /* <-, line 60 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 4, s_10); /* <-, line 61 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 4, s_11); /* <-, line 62 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 3, s_12); /* <-, line 63 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 64 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 3, s_14); /* <-, line 66 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 3, s_15); /* <-, line 68 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_from_s(z, 2, s_16); /* <-, line 69 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_from_s(z, 2, s_17); /* <-, line 71 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_from_s(z, 3, s_18); /* <-, line 72 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 12:
+ { int ret = slice_from_s(z, 3, s_19); /* <-, line 74 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ { int ret = slice_from_s(z, 3, s_20); /* <-, line 76 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 14:
+ { int ret = slice_from_s(z, 3, s_21); /* <-, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_3(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 82 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_4, 7); /* substring, line 82 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 82 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 82 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_22); /* <-, line 83 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 2, s_23); /* <-, line 85 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 87 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_4(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 92 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_5, 19); /* substring, line 92 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 92 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 92 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 95 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 96 */
+ if (!(eq_s_b(z, 1, s_24))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_25))) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 96 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_5a(struct SN_env * z) {
+ z->ket = z->c; /* [, line 101 */
+ if (!(eq_s_b(z, 1, s_26))) return 0;
+ z->bra = z->c; /* ], line 101 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 102 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab1; /* call R2, line 102 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* not, line 102 */
+ { int ret = r_shortv(z);
+ if (ret == 0) goto lab2; /* call shortv, line 102 */
+ if (ret < 0) return ret;
+ }
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ }
+lab0:
+ { int ret = slice_del(z); /* delete, line 103 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_Step_5b(struct SN_env * z) {
+ z->ket = z->c; /* [, line 107 */
+ if (!(eq_s_b(z, 1, s_27))) return 0;
+ z->bra = z->c; /* ], line 107 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 108 */
+ if (ret < 0) return ret;
+ }
+ if (!(eq_s_b(z, 1, s_28))) return 0;
+ { int ret = slice_del(z); /* delete, line 109 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern int porter_ISO_8859_1_stem(struct SN_env * z) {
+ z->B[0] = 0; /* unset Y_found, line 115 */
+ { int c1 = z->c; /* do, line 116 */
+ z->bra = z->c; /* [, line 116 */
+ if (!(eq_s(z, 1, s_29))) goto lab0;
+ z->ket = z->c; /* ], line 116 */
+ { int ret = slice_from_s(z, 1, s_30); /* <-, line 116 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set Y_found, line 116 */
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 117 */
+ while(1) { /* repeat, line 117 */
+ int c3 = z->c;
+ while(1) { /* goto, line 117 */
+ int c4 = z->c;
+ if (in_grouping(z, g_v, 97, 121, 0)) goto lab3;
+ z->bra = z->c; /* [, line 117 */
+ if (!(eq_s(z, 1, s_31))) goto lab3;
+ z->ket = z->c; /* ], line 117 */
+ z->c = c4;
+ break;
+ lab3:
+ z->c = c4;
+ if (z->c >= z->l) goto lab2;
+ z->c++; /* goto, line 117 */
+ }
+ { int ret = slice_from_s(z, 1, s_32); /* <-, line 117 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set Y_found, line 117 */
+ continue;
+ lab2:
+ z->c = c3;
+ break;
+ }
+ z->c = c2;
+ }
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { int c5 = z->c; /* do, line 121 */
+ { /* gopast */ /* grouping v, line 122 */
+ int ret = out_grouping(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 122 */
+ int ret = in_grouping(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 122 */
+ { /* gopast */ /* grouping v, line 123 */
+ int ret = out_grouping(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 123 */
+ int ret = in_grouping(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 123 */
+ lab4:
+ z->c = c5;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 126 */
+
+ { int m6 = z->l - z->c; (void)m6; /* do, line 127 */
+ { int ret = r_Step_1a(z);
+ if (ret == 0) goto lab5; /* call Step_1a, line 127 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ z->c = z->l - m6;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 128 */
+ { int ret = r_Step_1b(z);
+ if (ret == 0) goto lab6; /* call Step_1b, line 128 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m7;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 129 */
+ { int ret = r_Step_1c(z);
+ if (ret == 0) goto lab7; /* call Step_1c, line 129 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m8;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 130 */
+ { int ret = r_Step_2(z);
+ if (ret == 0) goto lab8; /* call Step_2, line 130 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = z->l - m9;
+ }
+ { int m10 = z->l - z->c; (void)m10; /* do, line 131 */
+ { int ret = r_Step_3(z);
+ if (ret == 0) goto lab9; /* call Step_3, line 131 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m10;
+ }
+ { int m11 = z->l - z->c; (void)m11; /* do, line 132 */
+ { int ret = r_Step_4(z);
+ if (ret == 0) goto lab10; /* call Step_4, line 132 */
+ if (ret < 0) return ret;
+ }
+ lab10:
+ z->c = z->l - m11;
+ }
+ { int m12 = z->l - z->c; (void)m12; /* do, line 133 */
+ { int ret = r_Step_5a(z);
+ if (ret == 0) goto lab11; /* call Step_5a, line 133 */
+ if (ret < 0) return ret;
+ }
+ lab11:
+ z->c = z->l - m12;
+ }
+ { int m13 = z->l - z->c; (void)m13; /* do, line 134 */
+ { int ret = r_Step_5b(z);
+ if (ret == 0) goto lab12; /* call Step_5b, line 134 */
+ if (ret < 0) return ret;
+ }
+ lab12:
+ z->c = z->l - m13;
+ }
+ z->c = z->lb;
+ { int c14 = z->c; /* do, line 137 */
+ if (!(z->B[0])) goto lab13; /* Boolean test Y_found, line 137 */
+ while(1) { /* repeat, line 137 */
+ int c15 = z->c;
+ while(1) { /* goto, line 137 */
+ int c16 = z->c;
+ z->bra = z->c; /* [, line 137 */
+ if (!(eq_s(z, 1, s_33))) goto lab15;
+ z->ket = z->c; /* ], line 137 */
+ z->c = c16;
+ break;
+ lab15:
+ z->c = c16;
+ if (z->c >= z->l) goto lab14;
+ z->c++; /* goto, line 137 */
+ }
+ { int ret = slice_from_s(z, 1, s_34); /* <-, line 137 */
+ if (ret < 0) return ret;
+ }
+ continue;
+ lab14:
+ z->c = c15;
+ break;
+ }
+ lab13:
+ z->c = c14;
+ }
+ return 1;
+}
+
+extern struct SN_env * porter_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); }
+
+extern void porter_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c
new file mode 100644
index 00000000000..06d425d008f
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c
@@ -0,0 +1,1017 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int portuguese_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_residual_form(struct SN_env * z);
+static int r_residual_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * portuguese_ISO_8859_1_create_env(void);
+extern void portuguese_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[1] = { 0xE3 };
+static const symbol s_0_2[1] = { 0xF5 };
+
+static const struct among a_0[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 1, s_0_1, 0, 1, 0},
+/* 2 */ { 1, s_0_2, 0, 2, 0}
+};
+
+static const symbol s_1_1[2] = { 'a', '~' };
+static const symbol s_1_2[2] = { 'o', '~' };
+
+static const struct among a_1[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 2, s_1_1, 0, 1, 0},
+/* 2 */ { 2, s_1_2, 0, 2, 0}
+};
+
+static const symbol s_2_0[2] = { 'i', 'c' };
+static const symbol s_2_1[2] = { 'a', 'd' };
+static const symbol s_2_2[2] = { 'o', 's' };
+static const symbol s_2_3[2] = { 'i', 'v' };
+
+static const struct among a_2[4] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 2, s_2_1, -1, -1, 0},
+/* 2 */ { 2, s_2_2, -1, -1, 0},
+/* 3 */ { 2, s_2_3, -1, 1, 0}
+};
+
+static const symbol s_3_0[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_3_1[4] = { 'a', 'v', 'e', 'l' };
+static const symbol s_3_2[4] = { 0xED, 'v', 'e', 'l' };
+
+static const struct among a_3[3] =
+{
+/* 0 */ { 4, s_3_0, -1, 1, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0},
+/* 2 */ { 4, s_3_2, -1, 1, 0}
+};
+
+static const symbol s_4_0[2] = { 'i', 'c' };
+static const symbol s_4_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_4_2[2] = { 'i', 'v' };
+
+static const struct among a_4[3] =
+{
+/* 0 */ { 2, s_4_0, -1, 1, 0},
+/* 1 */ { 4, s_4_1, -1, 1, 0},
+/* 2 */ { 2, s_4_2, -1, 1, 0}
+};
+
+static const symbol s_5_0[3] = { 'i', 'c', 'a' };
+static const symbol s_5_1[5] = { 0xE2, 'n', 'c', 'i', 'a' };
+static const symbol s_5_2[5] = { 0xEA, 'n', 'c', 'i', 'a' };
+static const symbol s_5_3[3] = { 'i', 'r', 'a' };
+static const symbol s_5_4[5] = { 'a', 'd', 'o', 'r', 'a' };
+static const symbol s_5_5[3] = { 'o', 's', 'a' };
+static const symbol s_5_6[4] = { 'i', 's', 't', 'a' };
+static const symbol s_5_7[3] = { 'i', 'v', 'a' };
+static const symbol s_5_8[3] = { 'e', 'z', 'a' };
+static const symbol s_5_9[5] = { 'l', 'o', 'g', 0xED, 'a' };
+static const symbol s_5_10[5] = { 'i', 'd', 'a', 'd', 'e' };
+static const symbol s_5_11[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_5_12[5] = { 'm', 'e', 'n', 't', 'e' };
+static const symbol s_5_13[6] = { 'a', 'm', 'e', 'n', 't', 'e' };
+static const symbol s_5_14[4] = { 0xE1, 'v', 'e', 'l' };
+static const symbol s_5_15[4] = { 0xED, 'v', 'e', 'l' };
+static const symbol s_5_16[5] = { 'u', 'c', 'i', 0xF3, 'n' };
+static const symbol s_5_17[3] = { 'i', 'c', 'o' };
+static const symbol s_5_18[4] = { 'i', 's', 'm', 'o' };
+static const symbol s_5_19[3] = { 'o', 's', 'o' };
+static const symbol s_5_20[6] = { 'a', 'm', 'e', 'n', 't', 'o' };
+static const symbol s_5_21[6] = { 'i', 'm', 'e', 'n', 't', 'o' };
+static const symbol s_5_22[3] = { 'i', 'v', 'o' };
+static const symbol s_5_23[5] = { 'a', 0xE7, 'a', '~', 'o' };
+static const symbol s_5_24[4] = { 'a', 'd', 'o', 'r' };
+static const symbol s_5_25[4] = { 'i', 'c', 'a', 's' };
+static const symbol s_5_26[6] = { 0xEA, 'n', 'c', 'i', 'a', 's' };
+static const symbol s_5_27[4] = { 'i', 'r', 'a', 's' };
+static const symbol s_5_28[6] = { 'a', 'd', 'o', 'r', 'a', 's' };
+static const symbol s_5_29[4] = { 'o', 's', 'a', 's' };
+static const symbol s_5_30[5] = { 'i', 's', 't', 'a', 's' };
+static const symbol s_5_31[4] = { 'i', 'v', 'a', 's' };
+static const symbol s_5_32[4] = { 'e', 'z', 'a', 's' };
+static const symbol s_5_33[6] = { 'l', 'o', 'g', 0xED, 'a', 's' };
+static const symbol s_5_34[6] = { 'i', 'd', 'a', 'd', 'e', 's' };
+static const symbol s_5_35[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' };
+static const symbol s_5_36[6] = { 'a', 'd', 'o', 'r', 'e', 's' };
+static const symbol s_5_37[5] = { 'a', 'n', 't', 'e', 's' };
+static const symbol s_5_38[6] = { 'a', 0xE7, 'o', '~', 'e', 's' };
+static const symbol s_5_39[4] = { 'i', 'c', 'o', 's' };
+static const symbol s_5_40[5] = { 'i', 's', 'm', 'o', 's' };
+static const symbol s_5_41[4] = { 'o', 's', 'o', 's' };
+static const symbol s_5_42[7] = { 'a', 'm', 'e', 'n', 't', 'o', 's' };
+static const symbol s_5_43[7] = { 'i', 'm', 'e', 'n', 't', 'o', 's' };
+static const symbol s_5_44[4] = { 'i', 'v', 'o', 's' };
+
+static const struct among a_5[45] =
+{
+/* 0 */ { 3, s_5_0, -1, 1, 0},
+/* 1 */ { 5, s_5_1, -1, 1, 0},
+/* 2 */ { 5, s_5_2, -1, 4, 0},
+/* 3 */ { 3, s_5_3, -1, 9, 0},
+/* 4 */ { 5, s_5_4, -1, 1, 0},
+/* 5 */ { 3, s_5_5, -1, 1, 0},
+/* 6 */ { 4, s_5_6, -1, 1, 0},
+/* 7 */ { 3, s_5_7, -1, 8, 0},
+/* 8 */ { 3, s_5_8, -1, 1, 0},
+/* 9 */ { 5, s_5_9, -1, 2, 0},
+/* 10 */ { 5, s_5_10, -1, 7, 0},
+/* 11 */ { 4, s_5_11, -1, 1, 0},
+/* 12 */ { 5, s_5_12, -1, 6, 0},
+/* 13 */ { 6, s_5_13, 12, 5, 0},
+/* 14 */ { 4, s_5_14, -1, 1, 0},
+/* 15 */ { 4, s_5_15, -1, 1, 0},
+/* 16 */ { 5, s_5_16, -1, 3, 0},
+/* 17 */ { 3, s_5_17, -1, 1, 0},
+/* 18 */ { 4, s_5_18, -1, 1, 0},
+/* 19 */ { 3, s_5_19, -1, 1, 0},
+/* 20 */ { 6, s_5_20, -1, 1, 0},
+/* 21 */ { 6, s_5_21, -1, 1, 0},
+/* 22 */ { 3, s_5_22, -1, 8, 0},
+/* 23 */ { 5, s_5_23, -1, 1, 0},
+/* 24 */ { 4, s_5_24, -1, 1, 0},
+/* 25 */ { 4, s_5_25, -1, 1, 0},
+/* 26 */ { 6, s_5_26, -1, 4, 0},
+/* 27 */ { 4, s_5_27, -1, 9, 0},
+/* 28 */ { 6, s_5_28, -1, 1, 0},
+/* 29 */ { 4, s_5_29, -1, 1, 0},
+/* 30 */ { 5, s_5_30, -1, 1, 0},
+/* 31 */ { 4, s_5_31, -1, 8, 0},
+/* 32 */ { 4, s_5_32, -1, 1, 0},
+/* 33 */ { 6, s_5_33, -1, 2, 0},
+/* 34 */ { 6, s_5_34, -1, 7, 0},
+/* 35 */ { 7, s_5_35, -1, 3, 0},
+/* 36 */ { 6, s_5_36, -1, 1, 0},
+/* 37 */ { 5, s_5_37, -1, 1, 0},
+/* 38 */ { 6, s_5_38, -1, 1, 0},
+/* 39 */ { 4, s_5_39, -1, 1, 0},
+/* 40 */ { 5, s_5_40, -1, 1, 0},
+/* 41 */ { 4, s_5_41, -1, 1, 0},
+/* 42 */ { 7, s_5_42, -1, 1, 0},
+/* 43 */ { 7, s_5_43, -1, 1, 0},
+/* 44 */ { 4, s_5_44, -1, 8, 0}
+};
+
+static const symbol s_6_0[3] = { 'a', 'd', 'a' };
+static const symbol s_6_1[3] = { 'i', 'd', 'a' };
+static const symbol s_6_2[2] = { 'i', 'a' };
+static const symbol s_6_3[4] = { 'a', 'r', 'i', 'a' };
+static const symbol s_6_4[4] = { 'e', 'r', 'i', 'a' };
+static const symbol s_6_5[4] = { 'i', 'r', 'i', 'a' };
+static const symbol s_6_6[3] = { 'a', 'r', 'a' };
+static const symbol s_6_7[3] = { 'e', 'r', 'a' };
+static const symbol s_6_8[3] = { 'i', 'r', 'a' };
+static const symbol s_6_9[3] = { 'a', 'v', 'a' };
+static const symbol s_6_10[4] = { 'a', 's', 's', 'e' };
+static const symbol s_6_11[4] = { 'e', 's', 's', 'e' };
+static const symbol s_6_12[4] = { 'i', 's', 's', 'e' };
+static const symbol s_6_13[4] = { 'a', 's', 't', 'e' };
+static const symbol s_6_14[4] = { 'e', 's', 't', 'e' };
+static const symbol s_6_15[4] = { 'i', 's', 't', 'e' };
+static const symbol s_6_16[2] = { 'e', 'i' };
+static const symbol s_6_17[4] = { 'a', 'r', 'e', 'i' };
+static const symbol s_6_18[4] = { 'e', 'r', 'e', 'i' };
+static const symbol s_6_19[4] = { 'i', 'r', 'e', 'i' };
+static const symbol s_6_20[2] = { 'a', 'm' };
+static const symbol s_6_21[3] = { 'i', 'a', 'm' };
+static const symbol s_6_22[5] = { 'a', 'r', 'i', 'a', 'm' };
+static const symbol s_6_23[5] = { 'e', 'r', 'i', 'a', 'm' };
+static const symbol s_6_24[5] = { 'i', 'r', 'i', 'a', 'm' };
+static const symbol s_6_25[4] = { 'a', 'r', 'a', 'm' };
+static const symbol s_6_26[4] = { 'e', 'r', 'a', 'm' };
+static const symbol s_6_27[4] = { 'i', 'r', 'a', 'm' };
+static const symbol s_6_28[4] = { 'a', 'v', 'a', 'm' };
+static const symbol s_6_29[2] = { 'e', 'm' };
+static const symbol s_6_30[4] = { 'a', 'r', 'e', 'm' };
+static const symbol s_6_31[4] = { 'e', 'r', 'e', 'm' };
+static const symbol s_6_32[4] = { 'i', 'r', 'e', 'm' };
+static const symbol s_6_33[5] = { 'a', 's', 's', 'e', 'm' };
+static const symbol s_6_34[5] = { 'e', 's', 's', 'e', 'm' };
+static const symbol s_6_35[5] = { 'i', 's', 's', 'e', 'm' };
+static const symbol s_6_36[3] = { 'a', 'd', 'o' };
+static const symbol s_6_37[3] = { 'i', 'd', 'o' };
+static const symbol s_6_38[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_6_39[4] = { 'e', 'n', 'd', 'o' };
+static const symbol s_6_40[4] = { 'i', 'n', 'd', 'o' };
+static const symbol s_6_41[5] = { 'a', 'r', 'a', '~', 'o' };
+static const symbol s_6_42[5] = { 'e', 'r', 'a', '~', 'o' };
+static const symbol s_6_43[5] = { 'i', 'r', 'a', '~', 'o' };
+static const symbol s_6_44[2] = { 'a', 'r' };
+static const symbol s_6_45[2] = { 'e', 'r' };
+static const symbol s_6_46[2] = { 'i', 'r' };
+static const symbol s_6_47[2] = { 'a', 's' };
+static const symbol s_6_48[4] = { 'a', 'd', 'a', 's' };
+static const symbol s_6_49[4] = { 'i', 'd', 'a', 's' };
+static const symbol s_6_50[3] = { 'i', 'a', 's' };
+static const symbol s_6_51[5] = { 'a', 'r', 'i', 'a', 's' };
+static const symbol s_6_52[5] = { 'e', 'r', 'i', 'a', 's' };
+static const symbol s_6_53[5] = { 'i', 'r', 'i', 'a', 's' };
+static const symbol s_6_54[4] = { 'a', 'r', 'a', 's' };
+static const symbol s_6_55[4] = { 'e', 'r', 'a', 's' };
+static const symbol s_6_56[4] = { 'i', 'r', 'a', 's' };
+static const symbol s_6_57[4] = { 'a', 'v', 'a', 's' };
+static const symbol s_6_58[2] = { 'e', 's' };
+static const symbol s_6_59[5] = { 'a', 'r', 'd', 'e', 's' };
+static const symbol s_6_60[5] = { 'e', 'r', 'd', 'e', 's' };
+static const symbol s_6_61[5] = { 'i', 'r', 'd', 'e', 's' };
+static const symbol s_6_62[4] = { 'a', 'r', 'e', 's' };
+static const symbol s_6_63[4] = { 'e', 'r', 'e', 's' };
+static const symbol s_6_64[4] = { 'i', 'r', 'e', 's' };
+static const symbol s_6_65[5] = { 'a', 's', 's', 'e', 's' };
+static const symbol s_6_66[5] = { 'e', 's', 's', 'e', 's' };
+static const symbol s_6_67[5] = { 'i', 's', 's', 'e', 's' };
+static const symbol s_6_68[5] = { 'a', 's', 't', 'e', 's' };
+static const symbol s_6_69[5] = { 'e', 's', 't', 'e', 's' };
+static const symbol s_6_70[5] = { 'i', 's', 't', 'e', 's' };
+static const symbol s_6_71[2] = { 'i', 's' };
+static const symbol s_6_72[3] = { 'a', 'i', 's' };
+static const symbol s_6_73[3] = { 'e', 'i', 's' };
+static const symbol s_6_74[5] = { 'a', 'r', 'e', 'i', 's' };
+static const symbol s_6_75[5] = { 'e', 'r', 'e', 'i', 's' };
+static const symbol s_6_76[5] = { 'i', 'r', 'e', 'i', 's' };
+static const symbol s_6_77[5] = { 0xE1, 'r', 'e', 'i', 's' };
+static const symbol s_6_78[5] = { 0xE9, 'r', 'e', 'i', 's' };
+static const symbol s_6_79[5] = { 0xED, 'r', 'e', 'i', 's' };
+static const symbol s_6_80[6] = { 0xE1, 's', 's', 'e', 'i', 's' };
+static const symbol s_6_81[6] = { 0xE9, 's', 's', 'e', 'i', 's' };
+static const symbol s_6_82[6] = { 0xED, 's', 's', 'e', 'i', 's' };
+static const symbol s_6_83[5] = { 0xE1, 'v', 'e', 'i', 's' };
+static const symbol s_6_84[4] = { 0xED, 'e', 'i', 's' };
+static const symbol s_6_85[6] = { 'a', 'r', 0xED, 'e', 'i', 's' };
+static const symbol s_6_86[6] = { 'e', 'r', 0xED, 'e', 'i', 's' };
+static const symbol s_6_87[6] = { 'i', 'r', 0xED, 'e', 'i', 's' };
+static const symbol s_6_88[4] = { 'a', 'd', 'o', 's' };
+static const symbol s_6_89[4] = { 'i', 'd', 'o', 's' };
+static const symbol s_6_90[4] = { 'a', 'm', 'o', 's' };
+static const symbol s_6_91[6] = { 0xE1, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_6_92[6] = { 0xE9, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_6_93[6] = { 0xED, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_6_94[6] = { 0xE1, 'v', 'a', 'm', 'o', 's' };
+static const symbol s_6_95[5] = { 0xED, 'a', 'm', 'o', 's' };
+static const symbol s_6_96[7] = { 'a', 'r', 0xED, 'a', 'm', 'o', 's' };
+static const symbol s_6_97[7] = { 'e', 'r', 0xED, 'a', 'm', 'o', 's' };
+static const symbol s_6_98[7] = { 'i', 'r', 0xED, 'a', 'm', 'o', 's' };
+static const symbol s_6_99[4] = { 'e', 'm', 'o', 's' };
+static const symbol s_6_100[6] = { 'a', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_6_101[6] = { 'e', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_6_102[6] = { 'i', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_6_103[7] = { 0xE1, 's', 's', 'e', 'm', 'o', 's' };
+static const symbol s_6_104[7] = { 0xEA, 's', 's', 'e', 'm', 'o', 's' };
+static const symbol s_6_105[7] = { 0xED, 's', 's', 'e', 'm', 'o', 's' };
+static const symbol s_6_106[4] = { 'i', 'm', 'o', 's' };
+static const symbol s_6_107[5] = { 'a', 'r', 'm', 'o', 's' };
+static const symbol s_6_108[5] = { 'e', 'r', 'm', 'o', 's' };
+static const symbol s_6_109[5] = { 'i', 'r', 'm', 'o', 's' };
+static const symbol s_6_110[4] = { 0xE1, 'm', 'o', 's' };
+static const symbol s_6_111[4] = { 'a', 'r', 0xE1, 's' };
+static const symbol s_6_112[4] = { 'e', 'r', 0xE1, 's' };
+static const symbol s_6_113[4] = { 'i', 'r', 0xE1, 's' };
+static const symbol s_6_114[2] = { 'e', 'u' };
+static const symbol s_6_115[2] = { 'i', 'u' };
+static const symbol s_6_116[2] = { 'o', 'u' };
+static const symbol s_6_117[3] = { 'a', 'r', 0xE1 };
+static const symbol s_6_118[3] = { 'e', 'r', 0xE1 };
+static const symbol s_6_119[3] = { 'i', 'r', 0xE1 };
+
+static const struct among a_6[120] =
+{
+/* 0 */ { 3, s_6_0, -1, 1, 0},
+/* 1 */ { 3, s_6_1, -1, 1, 0},
+/* 2 */ { 2, s_6_2, -1, 1, 0},
+/* 3 */ { 4, s_6_3, 2, 1, 0},
+/* 4 */ { 4, s_6_4, 2, 1, 0},
+/* 5 */ { 4, s_6_5, 2, 1, 0},
+/* 6 */ { 3, s_6_6, -1, 1, 0},
+/* 7 */ { 3, s_6_7, -1, 1, 0},
+/* 8 */ { 3, s_6_8, -1, 1, 0},
+/* 9 */ { 3, s_6_9, -1, 1, 0},
+/* 10 */ { 4, s_6_10, -1, 1, 0},
+/* 11 */ { 4, s_6_11, -1, 1, 0},
+/* 12 */ { 4, s_6_12, -1, 1, 0},
+/* 13 */ { 4, s_6_13, -1, 1, 0},
+/* 14 */ { 4, s_6_14, -1, 1, 0},
+/* 15 */ { 4, s_6_15, -1, 1, 0},
+/* 16 */ { 2, s_6_16, -1, 1, 0},
+/* 17 */ { 4, s_6_17, 16, 1, 0},
+/* 18 */ { 4, s_6_18, 16, 1, 0},
+/* 19 */ { 4, s_6_19, 16, 1, 0},
+/* 20 */ { 2, s_6_20, -1, 1, 0},
+/* 21 */ { 3, s_6_21, 20, 1, 0},
+/* 22 */ { 5, s_6_22, 21, 1, 0},
+/* 23 */ { 5, s_6_23, 21, 1, 0},
+/* 24 */ { 5, s_6_24, 21, 1, 0},
+/* 25 */ { 4, s_6_25, 20, 1, 0},
+/* 26 */ { 4, s_6_26, 20, 1, 0},
+/* 27 */ { 4, s_6_27, 20, 1, 0},
+/* 28 */ { 4, s_6_28, 20, 1, 0},
+/* 29 */ { 2, s_6_29, -1, 1, 0},
+/* 30 */ { 4, s_6_30, 29, 1, 0},
+/* 31 */ { 4, s_6_31, 29, 1, 0},
+/* 32 */ { 4, s_6_32, 29, 1, 0},
+/* 33 */ { 5, s_6_33, 29, 1, 0},
+/* 34 */ { 5, s_6_34, 29, 1, 0},
+/* 35 */ { 5, s_6_35, 29, 1, 0},
+/* 36 */ { 3, s_6_36, -1, 1, 0},
+/* 37 */ { 3, s_6_37, -1, 1, 0},
+/* 38 */ { 4, s_6_38, -1, 1, 0},
+/* 39 */ { 4, s_6_39, -1, 1, 0},
+/* 40 */ { 4, s_6_40, -1, 1, 0},
+/* 41 */ { 5, s_6_41, -1, 1, 0},
+/* 42 */ { 5, s_6_42, -1, 1, 0},
+/* 43 */ { 5, s_6_43, -1, 1, 0},
+/* 44 */ { 2, s_6_44, -1, 1, 0},
+/* 45 */ { 2, s_6_45, -1, 1, 0},
+/* 46 */ { 2, s_6_46, -1, 1, 0},
+/* 47 */ { 2, s_6_47, -1, 1, 0},
+/* 48 */ { 4, s_6_48, 47, 1, 0},
+/* 49 */ { 4, s_6_49, 47, 1, 0},
+/* 50 */ { 3, s_6_50, 47, 1, 0},
+/* 51 */ { 5, s_6_51, 50, 1, 0},
+/* 52 */ { 5, s_6_52, 50, 1, 0},
+/* 53 */ { 5, s_6_53, 50, 1, 0},
+/* 54 */ { 4, s_6_54, 47, 1, 0},
+/* 55 */ { 4, s_6_55, 47, 1, 0},
+/* 56 */ { 4, s_6_56, 47, 1, 0},
+/* 57 */ { 4, s_6_57, 47, 1, 0},
+/* 58 */ { 2, s_6_58, -1, 1, 0},
+/* 59 */ { 5, s_6_59, 58, 1, 0},
+/* 60 */ { 5, s_6_60, 58, 1, 0},
+/* 61 */ { 5, s_6_61, 58, 1, 0},
+/* 62 */ { 4, s_6_62, 58, 1, 0},
+/* 63 */ { 4, s_6_63, 58, 1, 0},
+/* 64 */ { 4, s_6_64, 58, 1, 0},
+/* 65 */ { 5, s_6_65, 58, 1, 0},
+/* 66 */ { 5, s_6_66, 58, 1, 0},
+/* 67 */ { 5, s_6_67, 58, 1, 0},
+/* 68 */ { 5, s_6_68, 58, 1, 0},
+/* 69 */ { 5, s_6_69, 58, 1, 0},
+/* 70 */ { 5, s_6_70, 58, 1, 0},
+/* 71 */ { 2, s_6_71, -1, 1, 0},
+/* 72 */ { 3, s_6_72, 71, 1, 0},
+/* 73 */ { 3, s_6_73, 71, 1, 0},
+/* 74 */ { 5, s_6_74, 73, 1, 0},
+/* 75 */ { 5, s_6_75, 73, 1, 0},
+/* 76 */ { 5, s_6_76, 73, 1, 0},
+/* 77 */ { 5, s_6_77, 73, 1, 0},
+/* 78 */ { 5, s_6_78, 73, 1, 0},
+/* 79 */ { 5, s_6_79, 73, 1, 0},
+/* 80 */ { 6, s_6_80, 73, 1, 0},
+/* 81 */ { 6, s_6_81, 73, 1, 0},
+/* 82 */ { 6, s_6_82, 73, 1, 0},
+/* 83 */ { 5, s_6_83, 73, 1, 0},
+/* 84 */ { 4, s_6_84, 73, 1, 0},
+/* 85 */ { 6, s_6_85, 84, 1, 0},
+/* 86 */ { 6, s_6_86, 84, 1, 0},
+/* 87 */ { 6, s_6_87, 84, 1, 0},
+/* 88 */ { 4, s_6_88, -1, 1, 0},
+/* 89 */ { 4, s_6_89, -1, 1, 0},
+/* 90 */ { 4, s_6_90, -1, 1, 0},
+/* 91 */ { 6, s_6_91, 90, 1, 0},
+/* 92 */ { 6, s_6_92, 90, 1, 0},
+/* 93 */ { 6, s_6_93, 90, 1, 0},
+/* 94 */ { 6, s_6_94, 90, 1, 0},
+/* 95 */ { 5, s_6_95, 90, 1, 0},
+/* 96 */ { 7, s_6_96, 95, 1, 0},
+/* 97 */ { 7, s_6_97, 95, 1, 0},
+/* 98 */ { 7, s_6_98, 95, 1, 0},
+/* 99 */ { 4, s_6_99, -1, 1, 0},
+/*100 */ { 6, s_6_100, 99, 1, 0},
+/*101 */ { 6, s_6_101, 99, 1, 0},
+/*102 */ { 6, s_6_102, 99, 1, 0},
+/*103 */ { 7, s_6_103, 99, 1, 0},
+/*104 */ { 7, s_6_104, 99, 1, 0},
+/*105 */ { 7, s_6_105, 99, 1, 0},
+/*106 */ { 4, s_6_106, -1, 1, 0},
+/*107 */ { 5, s_6_107, -1, 1, 0},
+/*108 */ { 5, s_6_108, -1, 1, 0},
+/*109 */ { 5, s_6_109, -1, 1, 0},
+/*110 */ { 4, s_6_110, -1, 1, 0},
+/*111 */ { 4, s_6_111, -1, 1, 0},
+/*112 */ { 4, s_6_112, -1, 1, 0},
+/*113 */ { 4, s_6_113, -1, 1, 0},
+/*114 */ { 2, s_6_114, -1, 1, 0},
+/*115 */ { 2, s_6_115, -1, 1, 0},
+/*116 */ { 2, s_6_116, -1, 1, 0},
+/*117 */ { 3, s_6_117, -1, 1, 0},
+/*118 */ { 3, s_6_118, -1, 1, 0},
+/*119 */ { 3, s_6_119, -1, 1, 0}
+};
+
+static const symbol s_7_0[1] = { 'a' };
+static const symbol s_7_1[1] = { 'i' };
+static const symbol s_7_2[1] = { 'o' };
+static const symbol s_7_3[2] = { 'o', 's' };
+static const symbol s_7_4[1] = { 0xE1 };
+static const symbol s_7_5[1] = { 0xED };
+static const symbol s_7_6[1] = { 0xF3 };
+
+static const struct among a_7[7] =
+{
+/* 0 */ { 1, s_7_0, -1, 1, 0},
+/* 1 */ { 1, s_7_1, -1, 1, 0},
+/* 2 */ { 1, s_7_2, -1, 1, 0},
+/* 3 */ { 2, s_7_3, -1, 1, 0},
+/* 4 */ { 1, s_7_4, -1, 1, 0},
+/* 5 */ { 1, s_7_5, -1, 1, 0},
+/* 6 */ { 1, s_7_6, -1, 1, 0}
+};
+
+static const symbol s_8_0[1] = { 'e' };
+static const symbol s_8_1[1] = { 0xE7 };
+static const symbol s_8_2[1] = { 0xE9 };
+static const symbol s_8_3[1] = { 0xEA };
+
+static const struct among a_8[4] =
+{
+/* 0 */ { 1, s_8_0, -1, 1, 0},
+/* 1 */ { 1, s_8_1, -1, 2, 0},
+/* 2 */ { 1, s_8_2, -1, 1, 0},
+/* 3 */ { 1, s_8_3, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2 };
+
+static const symbol s_0[] = { 'a', '~' };
+static const symbol s_1[] = { 'o', '~' };
+static const symbol s_2[] = { 0xE3 };
+static const symbol s_3[] = { 0xF5 };
+static const symbol s_4[] = { 'l', 'o', 'g' };
+static const symbol s_5[] = { 'u' };
+static const symbol s_6[] = { 'e', 'n', 't', 'e' };
+static const symbol s_7[] = { 'a', 't' };
+static const symbol s_8[] = { 'a', 't' };
+static const symbol s_9[] = { 'e' };
+static const symbol s_10[] = { 'i', 'r' };
+static const symbol s_11[] = { 'u' };
+static const symbol s_12[] = { 'g' };
+static const symbol s_13[] = { 'i' };
+static const symbol s_14[] = { 'c' };
+static const symbol s_15[] = { 'c' };
+static const symbol s_16[] = { 'i' };
+static const symbol s_17[] = { 'c' };
+
+static int r_prelude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 36 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 37 */
+ if (z->c >= z->l || (z->p[z->c + 0] != 227 && z->p[z->c + 0] != 245)) among_var = 3; else
+ among_var = find_among(z, a_0, 3); /* substring, line 37 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 37 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_0); /* <-, line 38 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 2, s_1); /* <-, line 39 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 40 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 50 */
+ { int c2 = z->c; /* or, line 52 */
+ if (in_grouping(z, g_v, 97, 250, 0)) goto lab2;
+ { int c3 = z->c; /* or, line 51 */
+ if (out_grouping(z, g_v, 97, 250, 0)) goto lab4;
+ { /* gopast */ /* grouping v, line 51 */
+ int ret = out_grouping(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c3;
+ if (in_grouping(z, g_v, 97, 250, 0)) goto lab2;
+ { /* gopast */ /* non v, line 51 */
+ int ret = in_grouping(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab2;
+ z->c += ret;
+ }
+ }
+ lab3:
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (out_grouping(z, g_v, 97, 250, 0)) goto lab0;
+ { int c4 = z->c; /* or, line 53 */
+ if (out_grouping(z, g_v, 97, 250, 0)) goto lab6;
+ { /* gopast */ /* grouping v, line 53 */
+ int ret = out_grouping(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab6;
+ z->c += ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c4;
+ if (in_grouping(z, g_v, 97, 250, 0)) goto lab0;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 53 */
+ }
+ lab5:
+ ;
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 54 */
+ lab0:
+ z->c = c1;
+ }
+ { int c5 = z->c; /* do, line 56 */
+ { /* gopast */ /* grouping v, line 57 */
+ int ret = out_grouping(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 57 */
+ int ret = in_grouping(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 57 */
+ { /* gopast */ /* grouping v, line 58 */
+ int ret = out_grouping(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 58 */
+ int ret = in_grouping(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 58 */
+ lab7:
+ z->c = c5;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 62 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 63 */
+ if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else
+ among_var = find_among(z, a_1, 3); /* substring, line 63 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 63 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 64 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 65 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 66 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 77 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((839714 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_5, 45); /* substring, line 77 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 77 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 93 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 93 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 98 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_4); /* <-, line 98 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 102 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 106 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 4, s_6); /* <-, line 106 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */
+ z->ket = z->c; /* [, line 112 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab0; }
+ among_var = find_among_b(z, a_2, 4); /* substring, line 112 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 112 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 112 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 112 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab0; }
+ case 1:
+ z->ket = z->c; /* [, line 113 */
+ if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 113 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 113 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 113 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ ;
+ }
+ break;
+ case 6:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 122 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 122 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 123 */
+ z->ket = z->c; /* [, line 124 */
+ if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m_keep; goto lab1; }
+ among_var = find_among_b(z, a_3, 3); /* substring, line 124 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 124 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab1; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 127 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 127 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab1:
+ ;
+ }
+ break;
+ case 7:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 135 */
+ z->ket = z->c; /* [, line 136 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab2; }
+ among_var = find_among_b(z, a_4, 3); /* substring, line 136 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab2; }
+ z->bra = z->c; /* ], line 136 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab2; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 139 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 139 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab2:
+ ;
+ }
+ break;
+ case 8:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 146 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 146 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 147 */
+ z->ket = z->c; /* [, line 148 */
+ if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 148 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 148 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 148 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ ;
+ }
+ break;
+ case 9:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 153 */
+ if (ret < 0) return ret;
+ }
+ if (!(eq_s_b(z, 1, s_9))) return 0;
+ { int ret = slice_from_s(z, 2, s_10); /* <-, line 154 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 159 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 159 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 160 */
+ among_var = find_among_b(z, a_6, 120); /* substring, line 160 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 160 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 179 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_residual_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 184 */
+ among_var = find_among_b(z, a_7, 7); /* substring, line 184 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 184 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 187 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 187 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_residual_form(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 192 */
+ among_var = find_among_b(z, a_8, 4); /* substring, line 192 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 192 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 194 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 194 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 194 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 194 */
+ if (!(eq_s_b(z, 1, s_11))) goto lab1;
+ z->bra = z->c; /* ], line 194 */
+ { int m_test = z->l - z->c; /* test, line 194 */
+ if (!(eq_s_b(z, 1, s_12))) goto lab1;
+ z->c = z->l - m_test;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_13))) return 0;
+ z->bra = z->c; /* ], line 195 */
+ { int m_test = z->l - z->c; /* test, line 195 */
+ if (!(eq_s_b(z, 1, s_14))) return 0;
+ z->c = z->l - m_test;
+ }
+ }
+ lab0:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 195 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 195 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_15); /* <-, line 196 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int portuguese_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 202 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 202 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 203 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 203 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 204 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 205 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 209 */
+ { int m5 = z->l - z->c; (void)m5; /* and, line 207 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 206 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab6; /* call standard_suffix, line 206 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab4; /* call verb_suffix, line 206 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ z->c = z->l - m5;
+ { int m7 = z->l - z->c; (void)m7; /* do, line 207 */
+ z->ket = z->c; /* [, line 207 */
+ if (!(eq_s_b(z, 1, s_16))) goto lab7;
+ z->bra = z->c; /* ], line 207 */
+ { int m_test = z->l - z->c; /* test, line 207 */
+ if (!(eq_s_b(z, 1, s_17))) goto lab7;
+ z->c = z->l - m_test;
+ }
+ { int ret = r_RV(z);
+ if (ret == 0) goto lab7; /* call RV, line 207 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 207 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m7;
+ }
+ }
+ goto lab3;
+ lab4:
+ z->c = z->l - m4;
+ { int ret = r_residual_suffix(z);
+ if (ret == 0) goto lab2; /* call residual_suffix, line 209 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab3:
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 211 */
+ { int ret = r_residual_form(z);
+ if (ret == 0) goto lab8; /* call residual_form, line 211 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = z->l - m8;
+ }
+ z->c = z->lb;
+ { int c9 = z->c; /* do, line 213 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab9; /* call postlude, line 213 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = c9;
+ }
+ return 1;
+}
+
+extern struct SN_env * portuguese_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void portuguese_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c
new file mode 100644
index 00000000000..27f26e7865e
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c
@@ -0,0 +1,1093 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int spanish_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_residual_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_y_verb_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_attached_pronoun(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * spanish_ISO_8859_1_create_env(void);
+extern void spanish_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[1] = { 0xE1 };
+static const symbol s_0_2[1] = { 0xE9 };
+static const symbol s_0_3[1] = { 0xED };
+static const symbol s_0_4[1] = { 0xF3 };
+static const symbol s_0_5[1] = { 0xFA };
+
+static const struct among a_0[6] =
+{
+/* 0 */ { 0, 0, -1, 6, 0},
+/* 1 */ { 1, s_0_1, 0, 1, 0},
+/* 2 */ { 1, s_0_2, 0, 2, 0},
+/* 3 */ { 1, s_0_3, 0, 3, 0},
+/* 4 */ { 1, s_0_4, 0, 4, 0},
+/* 5 */ { 1, s_0_5, 0, 5, 0}
+};
+
+static const symbol s_1_0[2] = { 'l', 'a' };
+static const symbol s_1_1[4] = { 's', 'e', 'l', 'a' };
+static const symbol s_1_2[2] = { 'l', 'e' };
+static const symbol s_1_3[2] = { 'm', 'e' };
+static const symbol s_1_4[2] = { 's', 'e' };
+static const symbol s_1_5[2] = { 'l', 'o' };
+static const symbol s_1_6[4] = { 's', 'e', 'l', 'o' };
+static const symbol s_1_7[3] = { 'l', 'a', 's' };
+static const symbol s_1_8[5] = { 's', 'e', 'l', 'a', 's' };
+static const symbol s_1_9[3] = { 'l', 'e', 's' };
+static const symbol s_1_10[3] = { 'l', 'o', 's' };
+static const symbol s_1_11[5] = { 's', 'e', 'l', 'o', 's' };
+static const symbol s_1_12[3] = { 'n', 'o', 's' };
+
+static const struct among a_1[13] =
+{
+/* 0 */ { 2, s_1_0, -1, -1, 0},
+/* 1 */ { 4, s_1_1, 0, -1, 0},
+/* 2 */ { 2, s_1_2, -1, -1, 0},
+/* 3 */ { 2, s_1_3, -1, -1, 0},
+/* 4 */ { 2, s_1_4, -1, -1, 0},
+/* 5 */ { 2, s_1_5, -1, -1, 0},
+/* 6 */ { 4, s_1_6, 5, -1, 0},
+/* 7 */ { 3, s_1_7, -1, -1, 0},
+/* 8 */ { 5, s_1_8, 7, -1, 0},
+/* 9 */ { 3, s_1_9, -1, -1, 0},
+/* 10 */ { 3, s_1_10, -1, -1, 0},
+/* 11 */ { 5, s_1_11, 10, -1, 0},
+/* 12 */ { 3, s_1_12, -1, -1, 0}
+};
+
+static const symbol s_2_0[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_2_1[5] = { 'i', 'e', 'n', 'd', 'o' };
+static const symbol s_2_2[5] = { 'y', 'e', 'n', 'd', 'o' };
+static const symbol s_2_3[4] = { 0xE1, 'n', 'd', 'o' };
+static const symbol s_2_4[5] = { 'i', 0xE9, 'n', 'd', 'o' };
+static const symbol s_2_5[2] = { 'a', 'r' };
+static const symbol s_2_6[2] = { 'e', 'r' };
+static const symbol s_2_7[2] = { 'i', 'r' };
+static const symbol s_2_8[2] = { 0xE1, 'r' };
+static const symbol s_2_9[2] = { 0xE9, 'r' };
+static const symbol s_2_10[2] = { 0xED, 'r' };
+
+static const struct among a_2[11] =
+{
+/* 0 */ { 4, s_2_0, -1, 6, 0},
+/* 1 */ { 5, s_2_1, -1, 6, 0},
+/* 2 */ { 5, s_2_2, -1, 7, 0},
+/* 3 */ { 4, s_2_3, -1, 2, 0},
+/* 4 */ { 5, s_2_4, -1, 1, 0},
+/* 5 */ { 2, s_2_5, -1, 6, 0},
+/* 6 */ { 2, s_2_6, -1, 6, 0},
+/* 7 */ { 2, s_2_7, -1, 6, 0},
+/* 8 */ { 2, s_2_8, -1, 3, 0},
+/* 9 */ { 2, s_2_9, -1, 4, 0},
+/* 10 */ { 2, s_2_10, -1, 5, 0}
+};
+
+static const symbol s_3_0[2] = { 'i', 'c' };
+static const symbol s_3_1[2] = { 'a', 'd' };
+static const symbol s_3_2[2] = { 'o', 's' };
+static const symbol s_3_3[2] = { 'i', 'v' };
+
+static const struct among a_3[4] =
+{
+/* 0 */ { 2, s_3_0, -1, -1, 0},
+/* 1 */ { 2, s_3_1, -1, -1, 0},
+/* 2 */ { 2, s_3_2, -1, -1, 0},
+/* 3 */ { 2, s_3_3, -1, 1, 0}
+};
+
+static const symbol s_4_0[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_4_1[4] = { 'i', 'b', 'l', 'e' };
+static const symbol s_4_2[4] = { 'a', 'n', 't', 'e' };
+
+static const struct among a_4[3] =
+{
+/* 0 */ { 4, s_4_0, -1, 1, 0},
+/* 1 */ { 4, s_4_1, -1, 1, 0},
+/* 2 */ { 4, s_4_2, -1, 1, 0}
+};
+
+static const symbol s_5_0[2] = { 'i', 'c' };
+static const symbol s_5_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_5_2[2] = { 'i', 'v' };
+
+static const struct among a_5[3] =
+{
+/* 0 */ { 2, s_5_0, -1, 1, 0},
+/* 1 */ { 4, s_5_1, -1, 1, 0},
+/* 2 */ { 2, s_5_2, -1, 1, 0}
+};
+
+static const symbol s_6_0[3] = { 'i', 'c', 'a' };
+static const symbol s_6_1[5] = { 'a', 'n', 'c', 'i', 'a' };
+static const symbol s_6_2[5] = { 'e', 'n', 'c', 'i', 'a' };
+static const symbol s_6_3[5] = { 'a', 'd', 'o', 'r', 'a' };
+static const symbol s_6_4[3] = { 'o', 's', 'a' };
+static const symbol s_6_5[4] = { 'i', 's', 't', 'a' };
+static const symbol s_6_6[3] = { 'i', 'v', 'a' };
+static const symbol s_6_7[4] = { 'a', 'n', 'z', 'a' };
+static const symbol s_6_8[5] = { 'l', 'o', 'g', 0xED, 'a' };
+static const symbol s_6_9[4] = { 'i', 'd', 'a', 'd' };
+static const symbol s_6_10[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_6_11[4] = { 'i', 'b', 'l', 'e' };
+static const symbol s_6_12[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_6_13[5] = { 'm', 'e', 'n', 't', 'e' };
+static const symbol s_6_14[6] = { 'a', 'm', 'e', 'n', 't', 'e' };
+static const symbol s_6_15[5] = { 'a', 'c', 'i', 0xF3, 'n' };
+static const symbol s_6_16[5] = { 'u', 'c', 'i', 0xF3, 'n' };
+static const symbol s_6_17[3] = { 'i', 'c', 'o' };
+static const symbol s_6_18[4] = { 'i', 's', 'm', 'o' };
+static const symbol s_6_19[3] = { 'o', 's', 'o' };
+static const symbol s_6_20[7] = { 'a', 'm', 'i', 'e', 'n', 't', 'o' };
+static const symbol s_6_21[7] = { 'i', 'm', 'i', 'e', 'n', 't', 'o' };
+static const symbol s_6_22[3] = { 'i', 'v', 'o' };
+static const symbol s_6_23[4] = { 'a', 'd', 'o', 'r' };
+static const symbol s_6_24[4] = { 'i', 'c', 'a', 's' };
+static const symbol s_6_25[6] = { 'a', 'n', 'c', 'i', 'a', 's' };
+static const symbol s_6_26[6] = { 'e', 'n', 'c', 'i', 'a', 's' };
+static const symbol s_6_27[6] = { 'a', 'd', 'o', 'r', 'a', 's' };
+static const symbol s_6_28[4] = { 'o', 's', 'a', 's' };
+static const symbol s_6_29[5] = { 'i', 's', 't', 'a', 's' };
+static const symbol s_6_30[4] = { 'i', 'v', 'a', 's' };
+static const symbol s_6_31[5] = { 'a', 'n', 'z', 'a', 's' };
+static const symbol s_6_32[6] = { 'l', 'o', 'g', 0xED, 'a', 's' };
+static const symbol s_6_33[6] = { 'i', 'd', 'a', 'd', 'e', 's' };
+static const symbol s_6_34[5] = { 'a', 'b', 'l', 'e', 's' };
+static const symbol s_6_35[5] = { 'i', 'b', 'l', 'e', 's' };
+static const symbol s_6_36[7] = { 'a', 'c', 'i', 'o', 'n', 'e', 's' };
+static const symbol s_6_37[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' };
+static const symbol s_6_38[6] = { 'a', 'd', 'o', 'r', 'e', 's' };
+static const symbol s_6_39[5] = { 'a', 'n', 't', 'e', 's' };
+static const symbol s_6_40[4] = { 'i', 'c', 'o', 's' };
+static const symbol s_6_41[5] = { 'i', 's', 'm', 'o', 's' };
+static const symbol s_6_42[4] = { 'o', 's', 'o', 's' };
+static const symbol s_6_43[8] = { 'a', 'm', 'i', 'e', 'n', 't', 'o', 's' };
+static const symbol s_6_44[8] = { 'i', 'm', 'i', 'e', 'n', 't', 'o', 's' };
+static const symbol s_6_45[4] = { 'i', 'v', 'o', 's' };
+
+static const struct among a_6[46] =
+{
+/* 0 */ { 3, s_6_0, -1, 1, 0},
+/* 1 */ { 5, s_6_1, -1, 2, 0},
+/* 2 */ { 5, s_6_2, -1, 5, 0},
+/* 3 */ { 5, s_6_3, -1, 2, 0},
+/* 4 */ { 3, s_6_4, -1, 1, 0},
+/* 5 */ { 4, s_6_5, -1, 1, 0},
+/* 6 */ { 3, s_6_6, -1, 9, 0},
+/* 7 */ { 4, s_6_7, -1, 1, 0},
+/* 8 */ { 5, s_6_8, -1, 3, 0},
+/* 9 */ { 4, s_6_9, -1, 8, 0},
+/* 10 */ { 4, s_6_10, -1, 1, 0},
+/* 11 */ { 4, s_6_11, -1, 1, 0},
+/* 12 */ { 4, s_6_12, -1, 2, 0},
+/* 13 */ { 5, s_6_13, -1, 7, 0},
+/* 14 */ { 6, s_6_14, 13, 6, 0},
+/* 15 */ { 5, s_6_15, -1, 2, 0},
+/* 16 */ { 5, s_6_16, -1, 4, 0},
+/* 17 */ { 3, s_6_17, -1, 1, 0},
+/* 18 */ { 4, s_6_18, -1, 1, 0},
+/* 19 */ { 3, s_6_19, -1, 1, 0},
+/* 20 */ { 7, s_6_20, -1, 1, 0},
+/* 21 */ { 7, s_6_21, -1, 1, 0},
+/* 22 */ { 3, s_6_22, -1, 9, 0},
+/* 23 */ { 4, s_6_23, -1, 2, 0},
+/* 24 */ { 4, s_6_24, -1, 1, 0},
+/* 25 */ { 6, s_6_25, -1, 2, 0},
+/* 26 */ { 6, s_6_26, -1, 5, 0},
+/* 27 */ { 6, s_6_27, -1, 2, 0},
+/* 28 */ { 4, s_6_28, -1, 1, 0},
+/* 29 */ { 5, s_6_29, -1, 1, 0},
+/* 30 */ { 4, s_6_30, -1, 9, 0},
+/* 31 */ { 5, s_6_31, -1, 1, 0},
+/* 32 */ { 6, s_6_32, -1, 3, 0},
+/* 33 */ { 6, s_6_33, -1, 8, 0},
+/* 34 */ { 5, s_6_34, -1, 1, 0},
+/* 35 */ { 5, s_6_35, -1, 1, 0},
+/* 36 */ { 7, s_6_36, -1, 2, 0},
+/* 37 */ { 7, s_6_37, -1, 4, 0},
+/* 38 */ { 6, s_6_38, -1, 2, 0},
+/* 39 */ { 5, s_6_39, -1, 2, 0},
+/* 40 */ { 4, s_6_40, -1, 1, 0},
+/* 41 */ { 5, s_6_41, -1, 1, 0},
+/* 42 */ { 4, s_6_42, -1, 1, 0},
+/* 43 */ { 8, s_6_43, -1, 1, 0},
+/* 44 */ { 8, s_6_44, -1, 1, 0},
+/* 45 */ { 4, s_6_45, -1, 9, 0}
+};
+
+static const symbol s_7_0[2] = { 'y', 'a' };
+static const symbol s_7_1[2] = { 'y', 'e' };
+static const symbol s_7_2[3] = { 'y', 'a', 'n' };
+static const symbol s_7_3[3] = { 'y', 'e', 'n' };
+static const symbol s_7_4[5] = { 'y', 'e', 'r', 'o', 'n' };
+static const symbol s_7_5[5] = { 'y', 'e', 'n', 'd', 'o' };
+static const symbol s_7_6[2] = { 'y', 'o' };
+static const symbol s_7_7[3] = { 'y', 'a', 's' };
+static const symbol s_7_8[3] = { 'y', 'e', 's' };
+static const symbol s_7_9[4] = { 'y', 'a', 'i', 's' };
+static const symbol s_7_10[5] = { 'y', 'a', 'm', 'o', 's' };
+static const symbol s_7_11[2] = { 'y', 0xF3 };
+
+static const struct among a_7[12] =
+{
+/* 0 */ { 2, s_7_0, -1, 1, 0},
+/* 1 */ { 2, s_7_1, -1, 1, 0},
+/* 2 */ { 3, s_7_2, -1, 1, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0},
+/* 4 */ { 5, s_7_4, -1, 1, 0},
+/* 5 */ { 5, s_7_5, -1, 1, 0},
+/* 6 */ { 2, s_7_6, -1, 1, 0},
+/* 7 */ { 3, s_7_7, -1, 1, 0},
+/* 8 */ { 3, s_7_8, -1, 1, 0},
+/* 9 */ { 4, s_7_9, -1, 1, 0},
+/* 10 */ { 5, s_7_10, -1, 1, 0},
+/* 11 */ { 2, s_7_11, -1, 1, 0}
+};
+
+static const symbol s_8_0[3] = { 'a', 'b', 'a' };
+static const symbol s_8_1[3] = { 'a', 'd', 'a' };
+static const symbol s_8_2[3] = { 'i', 'd', 'a' };
+static const symbol s_8_3[3] = { 'a', 'r', 'a' };
+static const symbol s_8_4[4] = { 'i', 'e', 'r', 'a' };
+static const symbol s_8_5[2] = { 0xED, 'a' };
+static const symbol s_8_6[4] = { 'a', 'r', 0xED, 'a' };
+static const symbol s_8_7[4] = { 'e', 'r', 0xED, 'a' };
+static const symbol s_8_8[4] = { 'i', 'r', 0xED, 'a' };
+static const symbol s_8_9[2] = { 'a', 'd' };
+static const symbol s_8_10[2] = { 'e', 'd' };
+static const symbol s_8_11[2] = { 'i', 'd' };
+static const symbol s_8_12[3] = { 'a', 's', 'e' };
+static const symbol s_8_13[4] = { 'i', 'e', 's', 'e' };
+static const symbol s_8_14[4] = { 'a', 's', 't', 'e' };
+static const symbol s_8_15[4] = { 'i', 's', 't', 'e' };
+static const symbol s_8_16[2] = { 'a', 'n' };
+static const symbol s_8_17[4] = { 'a', 'b', 'a', 'n' };
+static const symbol s_8_18[4] = { 'a', 'r', 'a', 'n' };
+static const symbol s_8_19[5] = { 'i', 'e', 'r', 'a', 'n' };
+static const symbol s_8_20[3] = { 0xED, 'a', 'n' };
+static const symbol s_8_21[5] = { 'a', 'r', 0xED, 'a', 'n' };
+static const symbol s_8_22[5] = { 'e', 'r', 0xED, 'a', 'n' };
+static const symbol s_8_23[5] = { 'i', 'r', 0xED, 'a', 'n' };
+static const symbol s_8_24[2] = { 'e', 'n' };
+static const symbol s_8_25[4] = { 'a', 's', 'e', 'n' };
+static const symbol s_8_26[5] = { 'i', 'e', 's', 'e', 'n' };
+static const symbol s_8_27[4] = { 'a', 'r', 'o', 'n' };
+static const symbol s_8_28[5] = { 'i', 'e', 'r', 'o', 'n' };
+static const symbol s_8_29[4] = { 'a', 'r', 0xE1, 'n' };
+static const symbol s_8_30[4] = { 'e', 'r', 0xE1, 'n' };
+static const symbol s_8_31[4] = { 'i', 'r', 0xE1, 'n' };
+static const symbol s_8_32[3] = { 'a', 'd', 'o' };
+static const symbol s_8_33[3] = { 'i', 'd', 'o' };
+static const symbol s_8_34[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_8_35[5] = { 'i', 'e', 'n', 'd', 'o' };
+static const symbol s_8_36[2] = { 'a', 'r' };
+static const symbol s_8_37[2] = { 'e', 'r' };
+static const symbol s_8_38[2] = { 'i', 'r' };
+static const symbol s_8_39[2] = { 'a', 's' };
+static const symbol s_8_40[4] = { 'a', 'b', 'a', 's' };
+static const symbol s_8_41[4] = { 'a', 'd', 'a', 's' };
+static const symbol s_8_42[4] = { 'i', 'd', 'a', 's' };
+static const symbol s_8_43[4] = { 'a', 'r', 'a', 's' };
+static const symbol s_8_44[5] = { 'i', 'e', 'r', 'a', 's' };
+static const symbol s_8_45[3] = { 0xED, 'a', 's' };
+static const symbol s_8_46[5] = { 'a', 'r', 0xED, 'a', 's' };
+static const symbol s_8_47[5] = { 'e', 'r', 0xED, 'a', 's' };
+static const symbol s_8_48[5] = { 'i', 'r', 0xED, 'a', 's' };
+static const symbol s_8_49[2] = { 'e', 's' };
+static const symbol s_8_50[4] = { 'a', 's', 'e', 's' };
+static const symbol s_8_51[5] = { 'i', 'e', 's', 'e', 's' };
+static const symbol s_8_52[5] = { 'a', 'b', 'a', 'i', 's' };
+static const symbol s_8_53[5] = { 'a', 'r', 'a', 'i', 's' };
+static const symbol s_8_54[6] = { 'i', 'e', 'r', 'a', 'i', 's' };
+static const symbol s_8_55[4] = { 0xED, 'a', 'i', 's' };
+static const symbol s_8_56[6] = { 'a', 'r', 0xED, 'a', 'i', 's' };
+static const symbol s_8_57[6] = { 'e', 'r', 0xED, 'a', 'i', 's' };
+static const symbol s_8_58[6] = { 'i', 'r', 0xED, 'a', 'i', 's' };
+static const symbol s_8_59[5] = { 'a', 's', 'e', 'i', 's' };
+static const symbol s_8_60[6] = { 'i', 'e', 's', 'e', 'i', 's' };
+static const symbol s_8_61[6] = { 'a', 's', 't', 'e', 'i', 's' };
+static const symbol s_8_62[6] = { 'i', 's', 't', 'e', 'i', 's' };
+static const symbol s_8_63[3] = { 0xE1, 'i', 's' };
+static const symbol s_8_64[3] = { 0xE9, 'i', 's' };
+static const symbol s_8_65[5] = { 'a', 'r', 0xE9, 'i', 's' };
+static const symbol s_8_66[5] = { 'e', 'r', 0xE9, 'i', 's' };
+static const symbol s_8_67[5] = { 'i', 'r', 0xE9, 'i', 's' };
+static const symbol s_8_68[4] = { 'a', 'd', 'o', 's' };
+static const symbol s_8_69[4] = { 'i', 'd', 'o', 's' };
+static const symbol s_8_70[4] = { 'a', 'm', 'o', 's' };
+static const symbol s_8_71[6] = { 0xE1, 'b', 'a', 'm', 'o', 's' };
+static const symbol s_8_72[6] = { 0xE1, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_8_73[7] = { 'i', 0xE9, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_8_74[5] = { 0xED, 'a', 'm', 'o', 's' };
+static const symbol s_8_75[7] = { 'a', 'r', 0xED, 'a', 'm', 'o', 's' };
+static const symbol s_8_76[7] = { 'e', 'r', 0xED, 'a', 'm', 'o', 's' };
+static const symbol s_8_77[7] = { 'i', 'r', 0xED, 'a', 'm', 'o', 's' };
+static const symbol s_8_78[4] = { 'e', 'm', 'o', 's' };
+static const symbol s_8_79[6] = { 'a', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_8_80[6] = { 'e', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_8_81[6] = { 'i', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_8_82[6] = { 0xE1, 's', 'e', 'm', 'o', 's' };
+static const symbol s_8_83[7] = { 'i', 0xE9, 's', 'e', 'm', 'o', 's' };
+static const symbol s_8_84[4] = { 'i', 'm', 'o', 's' };
+static const symbol s_8_85[4] = { 'a', 'r', 0xE1, 's' };
+static const symbol s_8_86[4] = { 'e', 'r', 0xE1, 's' };
+static const symbol s_8_87[4] = { 'i', 'r', 0xE1, 's' };
+static const symbol s_8_88[2] = { 0xED, 's' };
+static const symbol s_8_89[3] = { 'a', 'r', 0xE1 };
+static const symbol s_8_90[3] = { 'e', 'r', 0xE1 };
+static const symbol s_8_91[3] = { 'i', 'r', 0xE1 };
+static const symbol s_8_92[3] = { 'a', 'r', 0xE9 };
+static const symbol s_8_93[3] = { 'e', 'r', 0xE9 };
+static const symbol s_8_94[3] = { 'i', 'r', 0xE9 };
+static const symbol s_8_95[2] = { 'i', 0xF3 };
+
+static const struct among a_8[96] =
+{
+/* 0 */ { 3, s_8_0, -1, 2, 0},
+/* 1 */ { 3, s_8_1, -1, 2, 0},
+/* 2 */ { 3, s_8_2, -1, 2, 0},
+/* 3 */ { 3, s_8_3, -1, 2, 0},
+/* 4 */ { 4, s_8_4, -1, 2, 0},
+/* 5 */ { 2, s_8_5, -1, 2, 0},
+/* 6 */ { 4, s_8_6, 5, 2, 0},
+/* 7 */ { 4, s_8_7, 5, 2, 0},
+/* 8 */ { 4, s_8_8, 5, 2, 0},
+/* 9 */ { 2, s_8_9, -1, 2, 0},
+/* 10 */ { 2, s_8_10, -1, 2, 0},
+/* 11 */ { 2, s_8_11, -1, 2, 0},
+/* 12 */ { 3, s_8_12, -1, 2, 0},
+/* 13 */ { 4, s_8_13, -1, 2, 0},
+/* 14 */ { 4, s_8_14, -1, 2, 0},
+/* 15 */ { 4, s_8_15, -1, 2, 0},
+/* 16 */ { 2, s_8_16, -1, 2, 0},
+/* 17 */ { 4, s_8_17, 16, 2, 0},
+/* 18 */ { 4, s_8_18, 16, 2, 0},
+/* 19 */ { 5, s_8_19, 16, 2, 0},
+/* 20 */ { 3, s_8_20, 16, 2, 0},
+/* 21 */ { 5, s_8_21, 20, 2, 0},
+/* 22 */ { 5, s_8_22, 20, 2, 0},
+/* 23 */ { 5, s_8_23, 20, 2, 0},
+/* 24 */ { 2, s_8_24, -1, 1, 0},
+/* 25 */ { 4, s_8_25, 24, 2, 0},
+/* 26 */ { 5, s_8_26, 24, 2, 0},
+/* 27 */ { 4, s_8_27, -1, 2, 0},
+/* 28 */ { 5, s_8_28, -1, 2, 0},
+/* 29 */ { 4, s_8_29, -1, 2, 0},
+/* 30 */ { 4, s_8_30, -1, 2, 0},
+/* 31 */ { 4, s_8_31, -1, 2, 0},
+/* 32 */ { 3, s_8_32, -1, 2, 0},
+/* 33 */ { 3, s_8_33, -1, 2, 0},
+/* 34 */ { 4, s_8_34, -1, 2, 0},
+/* 35 */ { 5, s_8_35, -1, 2, 0},
+/* 36 */ { 2, s_8_36, -1, 2, 0},
+/* 37 */ { 2, s_8_37, -1, 2, 0},
+/* 38 */ { 2, s_8_38, -1, 2, 0},
+/* 39 */ { 2, s_8_39, -1, 2, 0},
+/* 40 */ { 4, s_8_40, 39, 2, 0},
+/* 41 */ { 4, s_8_41, 39, 2, 0},
+/* 42 */ { 4, s_8_42, 39, 2, 0},
+/* 43 */ { 4, s_8_43, 39, 2, 0},
+/* 44 */ { 5, s_8_44, 39, 2, 0},
+/* 45 */ { 3, s_8_45, 39, 2, 0},
+/* 46 */ { 5, s_8_46, 45, 2, 0},
+/* 47 */ { 5, s_8_47, 45, 2, 0},
+/* 48 */ { 5, s_8_48, 45, 2, 0},
+/* 49 */ { 2, s_8_49, -1, 1, 0},
+/* 50 */ { 4, s_8_50, 49, 2, 0},
+/* 51 */ { 5, s_8_51, 49, 2, 0},
+/* 52 */ { 5, s_8_52, -1, 2, 0},
+/* 53 */ { 5, s_8_53, -1, 2, 0},
+/* 54 */ { 6, s_8_54, -1, 2, 0},
+/* 55 */ { 4, s_8_55, -1, 2, 0},
+/* 56 */ { 6, s_8_56, 55, 2, 0},
+/* 57 */ { 6, s_8_57, 55, 2, 0},
+/* 58 */ { 6, s_8_58, 55, 2, 0},
+/* 59 */ { 5, s_8_59, -1, 2, 0},
+/* 60 */ { 6, s_8_60, -1, 2, 0},
+/* 61 */ { 6, s_8_61, -1, 2, 0},
+/* 62 */ { 6, s_8_62, -1, 2, 0},
+/* 63 */ { 3, s_8_63, -1, 2, 0},
+/* 64 */ { 3, s_8_64, -1, 1, 0},
+/* 65 */ { 5, s_8_65, 64, 2, 0},
+/* 66 */ { 5, s_8_66, 64, 2, 0},
+/* 67 */ { 5, s_8_67, 64, 2, 0},
+/* 68 */ { 4, s_8_68, -1, 2, 0},
+/* 69 */ { 4, s_8_69, -1, 2, 0},
+/* 70 */ { 4, s_8_70, -1, 2, 0},
+/* 71 */ { 6, s_8_71, 70, 2, 0},
+/* 72 */ { 6, s_8_72, 70, 2, 0},
+/* 73 */ { 7, s_8_73, 70, 2, 0},
+/* 74 */ { 5, s_8_74, 70, 2, 0},
+/* 75 */ { 7, s_8_75, 74, 2, 0},
+/* 76 */ { 7, s_8_76, 74, 2, 0},
+/* 77 */ { 7, s_8_77, 74, 2, 0},
+/* 78 */ { 4, s_8_78, -1, 1, 0},
+/* 79 */ { 6, s_8_79, 78, 2, 0},
+/* 80 */ { 6, s_8_80, 78, 2, 0},
+/* 81 */ { 6, s_8_81, 78, 2, 0},
+/* 82 */ { 6, s_8_82, 78, 2, 0},
+/* 83 */ { 7, s_8_83, 78, 2, 0},
+/* 84 */ { 4, s_8_84, -1, 2, 0},
+/* 85 */ { 4, s_8_85, -1, 2, 0},
+/* 86 */ { 4, s_8_86, -1, 2, 0},
+/* 87 */ { 4, s_8_87, -1, 2, 0},
+/* 88 */ { 2, s_8_88, -1, 2, 0},
+/* 89 */ { 3, s_8_89, -1, 2, 0},
+/* 90 */ { 3, s_8_90, -1, 2, 0},
+/* 91 */ { 3, s_8_91, -1, 2, 0},
+/* 92 */ { 3, s_8_92, -1, 2, 0},
+/* 93 */ { 3, s_8_93, -1, 2, 0},
+/* 94 */ { 3, s_8_94, -1, 2, 0},
+/* 95 */ { 2, s_8_95, -1, 2, 0}
+};
+
+static const symbol s_9_0[1] = { 'a' };
+static const symbol s_9_1[1] = { 'e' };
+static const symbol s_9_2[1] = { 'o' };
+static const symbol s_9_3[2] = { 'o', 's' };
+static const symbol s_9_4[1] = { 0xE1 };
+static const symbol s_9_5[1] = { 0xE9 };
+static const symbol s_9_6[1] = { 0xED };
+static const symbol s_9_7[1] = { 0xF3 };
+
+static const struct among a_9[8] =
+{
+/* 0 */ { 1, s_9_0, -1, 1, 0},
+/* 1 */ { 1, s_9_1, -1, 2, 0},
+/* 2 */ { 1, s_9_2, -1, 1, 0},
+/* 3 */ { 2, s_9_3, -1, 1, 0},
+/* 4 */ { 1, s_9_4, -1, 1, 0},
+/* 5 */ { 1, s_9_5, -1, 2, 0},
+/* 6 */ { 1, s_9_6, -1, 1, 0},
+/* 7 */ { 1, s_9_7, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10 };
+
+static const symbol s_0[] = { 'a' };
+static const symbol s_1[] = { 'e' };
+static const symbol s_2[] = { 'i' };
+static const symbol s_3[] = { 'o' };
+static const symbol s_4[] = { 'u' };
+static const symbol s_5[] = { 'i', 'e', 'n', 'd', 'o' };
+static const symbol s_6[] = { 'a', 'n', 'd', 'o' };
+static const symbol s_7[] = { 'a', 'r' };
+static const symbol s_8[] = { 'e', 'r' };
+static const symbol s_9[] = { 'i', 'r' };
+static const symbol s_10[] = { 'u' };
+static const symbol s_11[] = { 'i', 'c' };
+static const symbol s_12[] = { 'l', 'o', 'g' };
+static const symbol s_13[] = { 'u' };
+static const symbol s_14[] = { 'e', 'n', 't', 'e' };
+static const symbol s_15[] = { 'a', 't' };
+static const symbol s_16[] = { 'a', 't' };
+static const symbol s_17[] = { 'u' };
+static const symbol s_18[] = { 'u' };
+static const symbol s_19[] = { 'g' };
+static const symbol s_20[] = { 'u' };
+static const symbol s_21[] = { 'g' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 37 */
+ { int c2 = z->c; /* or, line 39 */
+ if (in_grouping(z, g_v, 97, 252, 0)) goto lab2;
+ { int c3 = z->c; /* or, line 38 */
+ if (out_grouping(z, g_v, 97, 252, 0)) goto lab4;
+ { /* gopast */ /* grouping v, line 38 */
+ int ret = out_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c3;
+ if (in_grouping(z, g_v, 97, 252, 0)) goto lab2;
+ { /* gopast */ /* non v, line 38 */
+ int ret = in_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab2;
+ z->c += ret;
+ }
+ }
+ lab3:
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (out_grouping(z, g_v, 97, 252, 0)) goto lab0;
+ { int c4 = z->c; /* or, line 40 */
+ if (out_grouping(z, g_v, 97, 252, 0)) goto lab6;
+ { /* gopast */ /* grouping v, line 40 */
+ int ret = out_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab6;
+ z->c += ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c4;
+ if (in_grouping(z, g_v, 97, 252, 0)) goto lab0;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 40 */
+ }
+ lab5:
+ ;
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 41 */
+ lab0:
+ z->c = c1;
+ }
+ { int c5 = z->c; /* do, line 43 */
+ { /* gopast */ /* grouping v, line 44 */
+ int ret = out_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 44 */
+ int ret = in_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 44 */
+ { /* gopast */ /* grouping v, line 45 */
+ int ret = out_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 45 */
+ int ret = in_grouping(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 45 */
+ lab7:
+ z->c = c5;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 49 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 50 */
+ if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((67641858 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else
+ among_var = find_among(z, a_0, 6); /* substring, line 50 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 50 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_0); /* <-, line 51 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 52 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 53 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 54 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 55 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 57 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_attached_pronoun(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 68 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_1, 13))) return 0; /* substring, line 68 */
+ z->bra = z->c; /* ], line 68 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0;
+ among_var = find_among_b(z, a_2, 11); /* substring, line 72 */
+ if (!(among_var)) return 0;
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 72 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ z->bra = z->c; /* ], line 73 */
+ { int ret = slice_from_s(z, 5, s_5); /* <-, line 73 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ z->bra = z->c; /* ], line 74 */
+ { int ret = slice_from_s(z, 4, s_6); /* <-, line 74 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ z->bra = z->c; /* ], line 75 */
+ { int ret = slice_from_s(z, 2, s_7); /* <-, line 75 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ z->bra = z->c; /* ], line 76 */
+ { int ret = slice_from_s(z, 2, s_8); /* <-, line 76 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ z->bra = z->c; /* ], line 77 */
+ { int ret = slice_from_s(z, 2, s_9); /* <-, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_del(z); /* delete, line 81 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ if (!(eq_s_b(z, 1, s_10))) return 0;
+ { int ret = slice_del(z); /* delete, line 82 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 87 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_6, 46); /* substring, line 87 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 87 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 99 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 99 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 105 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 105 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 106 */
+ z->ket = z->c; /* [, line 106 */
+ if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 106 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 106 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 106 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 111 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_12); /* <-, line 111 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 115 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 115 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 119 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 4, s_14); /* <-, line 119 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 123 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 123 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 124 */
+ z->ket = z->c; /* [, line 125 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab1; }
+ among_var = find_among_b(z, a_3, 4); /* substring, line 125 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 125 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 125 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 125 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab1; }
+ case 1:
+ z->ket = z->c; /* [, line 126 */
+ if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 126 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 126 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 126 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab1:
+ ;
+ }
+ break;
+ case 7:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 135 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 135 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 136 */
+ z->ket = z->c; /* [, line 137 */
+ if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m_keep; goto lab2; }
+ among_var = find_among_b(z, a_4, 3); /* substring, line 137 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab2; }
+ z->bra = z->c; /* ], line 137 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab2; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 140 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 140 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab2:
+ ;
+ }
+ break;
+ case 8:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 147 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 147 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 148 */
+ z->ket = z->c; /* [, line 149 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab3; }
+ among_var = find_among_b(z, a_5, 3); /* substring, line 149 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 149 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab3; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 152 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 152 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab3:
+ ;
+ }
+ break;
+ case 9:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 159 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 159 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 160 */
+ z->ket = z->c; /* [, line 161 */
+ if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m_keep; goto lab4; }
+ z->bra = z->c; /* ], line 161 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call R2, line 161 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 161 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ ;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_y_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 168 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 168 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 168 */
+ among_var = find_among_b(z, a_7, 12); /* substring, line 168 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 168 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ if (!(eq_s_b(z, 1, s_17))) return 0;
+ { int ret = slice_del(z); /* delete, line 171 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 176 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 176 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 176 */
+ among_var = find_among_b(z, a_8, 96); /* substring, line 176 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 176 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 179 */
+ if (!(eq_s_b(z, 1, s_18))) { z->c = z->l - m_keep; goto lab0; }
+ { int m_test = z->l - z->c; /* test, line 179 */
+ if (!(eq_s_b(z, 1, s_19))) { z->c = z->l - m_keep; goto lab0; }
+ z->c = z->l - m_test;
+ }
+ lab0:
+ ;
+ }
+ z->bra = z->c; /* ], line 179 */
+ { int ret = slice_del(z); /* delete, line 179 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 200 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_residual_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 205 */
+ among_var = find_among_b(z, a_9, 8); /* substring, line 205 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 205 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 208 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 208 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 210 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 210 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 210 */
+ z->ket = z->c; /* [, line 210 */
+ if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 210 */
+ { int m_test = z->l - z->c; /* test, line 210 */
+ if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m_keep; goto lab0; }
+ z->c = z->l - m_test;
+ }
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 210 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 210 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int spanish_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 216 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 216 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 217 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 218 */
+ { int ret = r_attached_pronoun(z);
+ if (ret == 0) goto lab1; /* call attached_pronoun, line 218 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 219 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 219 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab4; /* call standard_suffix, line 219 */
+ if (ret < 0) return ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = z->l - m4;
+ { int ret = r_y_verb_suffix(z);
+ if (ret == 0) goto lab5; /* call y_verb_suffix, line 220 */
+ if (ret < 0) return ret;
+ }
+ goto lab3;
+ lab5:
+ z->c = z->l - m4;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab2; /* call verb_suffix, line 221 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab3:
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 223 */
+ { int ret = r_residual_suffix(z);
+ if (ret == 0) goto lab6; /* call residual_suffix, line 223 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m5;
+ }
+ z->c = z->lb;
+ { int c6 = z->c; /* do, line 225 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab7; /* call postlude, line 225 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = c6;
+ }
+ return 1;
+}
+
+extern struct SN_env * spanish_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void spanish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c
new file mode 100644
index 00000000000..f9bef1ada56
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c
@@ -0,0 +1,307 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int swedish_ISO_8859_1_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_other_suffix(struct SN_env * z);
+static int r_consonant_pair(struct SN_env * z);
+static int r_main_suffix(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * swedish_ISO_8859_1_create_env(void);
+extern void swedish_ISO_8859_1_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[1] = { 'a' };
+static const symbol s_0_1[4] = { 'a', 'r', 'n', 'a' };
+static const symbol s_0_2[4] = { 'e', 'r', 'n', 'a' };
+static const symbol s_0_3[7] = { 'h', 'e', 't', 'e', 'r', 'n', 'a' };
+static const symbol s_0_4[4] = { 'o', 'r', 'n', 'a' };
+static const symbol s_0_5[2] = { 'a', 'd' };
+static const symbol s_0_6[1] = { 'e' };
+static const symbol s_0_7[3] = { 'a', 'd', 'e' };
+static const symbol s_0_8[4] = { 'a', 'n', 'd', 'e' };
+static const symbol s_0_9[4] = { 'a', 'r', 'n', 'e' };
+static const symbol s_0_10[3] = { 'a', 'r', 'e' };
+static const symbol s_0_11[4] = { 'a', 's', 't', 'e' };
+static const symbol s_0_12[2] = { 'e', 'n' };
+static const symbol s_0_13[5] = { 'a', 'n', 'd', 'e', 'n' };
+static const symbol s_0_14[4] = { 'a', 'r', 'e', 'n' };
+static const symbol s_0_15[5] = { 'h', 'e', 't', 'e', 'n' };
+static const symbol s_0_16[3] = { 'e', 'r', 'n' };
+static const symbol s_0_17[2] = { 'a', 'r' };
+static const symbol s_0_18[2] = { 'e', 'r' };
+static const symbol s_0_19[5] = { 'h', 'e', 't', 'e', 'r' };
+static const symbol s_0_20[2] = { 'o', 'r' };
+static const symbol s_0_21[1] = { 's' };
+static const symbol s_0_22[2] = { 'a', 's' };
+static const symbol s_0_23[5] = { 'a', 'r', 'n', 'a', 's' };
+static const symbol s_0_24[5] = { 'e', 'r', 'n', 'a', 's' };
+static const symbol s_0_25[5] = { 'o', 'r', 'n', 'a', 's' };
+static const symbol s_0_26[2] = { 'e', 's' };
+static const symbol s_0_27[4] = { 'a', 'd', 'e', 's' };
+static const symbol s_0_28[5] = { 'a', 'n', 'd', 'e', 's' };
+static const symbol s_0_29[3] = { 'e', 'n', 's' };
+static const symbol s_0_30[5] = { 'a', 'r', 'e', 'n', 's' };
+static const symbol s_0_31[6] = { 'h', 'e', 't', 'e', 'n', 's' };
+static const symbol s_0_32[4] = { 'e', 'r', 'n', 's' };
+static const symbol s_0_33[2] = { 'a', 't' };
+static const symbol s_0_34[5] = { 'a', 'n', 'd', 'e', 't' };
+static const symbol s_0_35[3] = { 'h', 'e', 't' };
+static const symbol s_0_36[3] = { 'a', 's', 't' };
+
+static const struct among a_0[37] =
+{
+/* 0 */ { 1, s_0_0, -1, 1, 0},
+/* 1 */ { 4, s_0_1, 0, 1, 0},
+/* 2 */ { 4, s_0_2, 0, 1, 0},
+/* 3 */ { 7, s_0_3, 2, 1, 0},
+/* 4 */ { 4, s_0_4, 0, 1, 0},
+/* 5 */ { 2, s_0_5, -1, 1, 0},
+/* 6 */ { 1, s_0_6, -1, 1, 0},
+/* 7 */ { 3, s_0_7, 6, 1, 0},
+/* 8 */ { 4, s_0_8, 6, 1, 0},
+/* 9 */ { 4, s_0_9, 6, 1, 0},
+/* 10 */ { 3, s_0_10, 6, 1, 0},
+/* 11 */ { 4, s_0_11, 6, 1, 0},
+/* 12 */ { 2, s_0_12, -1, 1, 0},
+/* 13 */ { 5, s_0_13, 12, 1, 0},
+/* 14 */ { 4, s_0_14, 12, 1, 0},
+/* 15 */ { 5, s_0_15, 12, 1, 0},
+/* 16 */ { 3, s_0_16, -1, 1, 0},
+/* 17 */ { 2, s_0_17, -1, 1, 0},
+/* 18 */ { 2, s_0_18, -1, 1, 0},
+/* 19 */ { 5, s_0_19, 18, 1, 0},
+/* 20 */ { 2, s_0_20, -1, 1, 0},
+/* 21 */ { 1, s_0_21, -1, 2, 0},
+/* 22 */ { 2, s_0_22, 21, 1, 0},
+/* 23 */ { 5, s_0_23, 22, 1, 0},
+/* 24 */ { 5, s_0_24, 22, 1, 0},
+/* 25 */ { 5, s_0_25, 22, 1, 0},
+/* 26 */ { 2, s_0_26, 21, 1, 0},
+/* 27 */ { 4, s_0_27, 26, 1, 0},
+/* 28 */ { 5, s_0_28, 26, 1, 0},
+/* 29 */ { 3, s_0_29, 21, 1, 0},
+/* 30 */ { 5, s_0_30, 29, 1, 0},
+/* 31 */ { 6, s_0_31, 29, 1, 0},
+/* 32 */ { 4, s_0_32, 21, 1, 0},
+/* 33 */ { 2, s_0_33, -1, 1, 0},
+/* 34 */ { 5, s_0_34, -1, 1, 0},
+/* 35 */ { 3, s_0_35, -1, 1, 0},
+/* 36 */ { 3, s_0_36, -1, 1, 0}
+};
+
+static const symbol s_1_0[2] = { 'd', 'd' };
+static const symbol s_1_1[2] = { 'g', 'd' };
+static const symbol s_1_2[2] = { 'n', 'n' };
+static const symbol s_1_3[2] = { 'd', 't' };
+static const symbol s_1_4[2] = { 'g', 't' };
+static const symbol s_1_5[2] = { 'k', 't' };
+static const symbol s_1_6[2] = { 't', 't' };
+
+static const struct among a_1[7] =
+{
+/* 0 */ { 2, s_1_0, -1, -1, 0},
+/* 1 */ { 2, s_1_1, -1, -1, 0},
+/* 2 */ { 2, s_1_2, -1, -1, 0},
+/* 3 */ { 2, s_1_3, -1, -1, 0},
+/* 4 */ { 2, s_1_4, -1, -1, 0},
+/* 5 */ { 2, s_1_5, -1, -1, 0},
+/* 6 */ { 2, s_1_6, -1, -1, 0}
+};
+
+static const symbol s_2_0[2] = { 'i', 'g' };
+static const symbol s_2_1[3] = { 'l', 'i', 'g' };
+static const symbol s_2_2[3] = { 'e', 'l', 's' };
+static const symbol s_2_3[5] = { 'f', 'u', 'l', 'l', 't' };
+static const symbol s_2_4[4] = { 'l', 0xF6, 's', 't' };
+
+static const struct among a_2[5] =
+{
+/* 0 */ { 2, s_2_0, -1, 1, 0},
+/* 1 */ { 3, s_2_1, 0, 1, 0},
+/* 2 */ { 3, s_2_2, -1, 1, 0},
+/* 3 */ { 5, s_2_3, -1, 3, 0},
+/* 4 */ { 4, s_2_4, -1, 2, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32 };
+
+static const unsigned char g_s_ending[] = { 119, 127, 149 };
+
+static const symbol s_0[] = { 'l', 0xF6, 's' };
+static const symbol s_1[] = { 'f', 'u', 'l', 'l' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ { int c_test = z->c; /* test, line 29 */
+ { int ret = z->c + 3;
+ if (0 > ret || ret > z->l) return 0;
+ z->c = ret; /* hop, line 29 */
+ }
+ z->I[1] = z->c; /* setmark x, line 29 */
+ z->c = c_test;
+ }
+ if (out_grouping(z, g_v, 97, 246, 1) < 0) return 0; /* goto */ /* grouping v, line 30 */
+ { /* gopast */ /* non v, line 30 */
+ int ret = in_grouping(z, g_v, 97, 246, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 30 */
+ /* try, line 31 */
+ if (!(z->I[0] < z->I[1])) goto lab0;
+ z->I[0] = z->I[1];
+lab0:
+ return 1;
+}
+
+static int r_main_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 37 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 37 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 37 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_0, 37); /* substring, line 37 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 37 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 44 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (in_grouping_b(z, g_s_ending, 98, 121, 0)) return 0;
+ { int ret = slice_del(z); /* delete, line 46 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_consonant_pair(struct SN_env * z) {
+ { int mlimit; /* setlimit, line 50 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 50 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* and, line 52 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ if (!(find_among_b(z, a_1, 7))) { z->lb = mlimit; return 0; } /* among, line 51 */
+ z->c = z->l - m2;
+ z->ket = z->c; /* [, line 52 */
+ if (z->c <= z->lb) { z->lb = mlimit; return 0; }
+ z->c--; /* next, line 52 */
+ z->bra = z->c; /* ], line 52 */
+ { int ret = slice_del(z); /* delete, line 52 */
+ if (ret < 0) return ret;
+ }
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_other_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 55 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 55 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 56 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_2, 5); /* substring, line 56 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 56 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 57 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 3, s_0); /* <-, line 58 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 4, s_1); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+extern int swedish_ISO_8859_1_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 66 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 66 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 67 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 68 */
+ { int ret = r_main_suffix(z);
+ if (ret == 0) goto lab1; /* call main_suffix, line 68 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 69 */
+ { int ret = r_consonant_pair(z);
+ if (ret == 0) goto lab2; /* call consonant_pair, line 69 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 70 */
+ { int ret = r_other_suffix(z);
+ if (ret == 0) goto lab3; /* call other_suffix, line 70 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * swedish_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); }
+
+extern void swedish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c
new file mode 100644
index 00000000000..d5cc2bec3fc
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c
@@ -0,0 +1,998 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int romanian_ISO_8859_2_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_vowel_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_combo_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_step_0(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * romanian_ISO_8859_2_create_env(void);
+extern void romanian_ISO_8859_2_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[1] = { 'I' };
+static const symbol s_0_2[1] = { 'U' };
+
+static const struct among a_0[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 1, s_0_1, 0, 1, 0},
+/* 2 */ { 1, s_0_2, 0, 2, 0}
+};
+
+static const symbol s_1_0[2] = { 'e', 'a' };
+static const symbol s_1_1[4] = { 'a', 0xFE, 'i', 'a' };
+static const symbol s_1_2[3] = { 'a', 'u', 'a' };
+static const symbol s_1_3[3] = { 'i', 'u', 'a' };
+static const symbol s_1_4[4] = { 'a', 0xFE, 'i', 'e' };
+static const symbol s_1_5[3] = { 'e', 'l', 'e' };
+static const symbol s_1_6[3] = { 'i', 'l', 'e' };
+static const symbol s_1_7[4] = { 'i', 'i', 'l', 'e' };
+static const symbol s_1_8[3] = { 'i', 'e', 'i' };
+static const symbol s_1_9[4] = { 'a', 't', 'e', 'i' };
+static const symbol s_1_10[2] = { 'i', 'i' };
+static const symbol s_1_11[4] = { 'u', 'l', 'u', 'i' };
+static const symbol s_1_12[2] = { 'u', 'l' };
+static const symbol s_1_13[4] = { 'e', 'l', 'o', 'r' };
+static const symbol s_1_14[4] = { 'i', 'l', 'o', 'r' };
+static const symbol s_1_15[5] = { 'i', 'i', 'l', 'o', 'r' };
+
+static const struct among a_1[16] =
+{
+/* 0 */ { 2, s_1_0, -1, 3, 0},
+/* 1 */ { 4, s_1_1, -1, 7, 0},
+/* 2 */ { 3, s_1_2, -1, 2, 0},
+/* 3 */ { 3, s_1_3, -1, 4, 0},
+/* 4 */ { 4, s_1_4, -1, 7, 0},
+/* 5 */ { 3, s_1_5, -1, 3, 0},
+/* 6 */ { 3, s_1_6, -1, 5, 0},
+/* 7 */ { 4, s_1_7, 6, 4, 0},
+/* 8 */ { 3, s_1_8, -1, 4, 0},
+/* 9 */ { 4, s_1_9, -1, 6, 0},
+/* 10 */ { 2, s_1_10, -1, 4, 0},
+/* 11 */ { 4, s_1_11, -1, 1, 0},
+/* 12 */ { 2, s_1_12, -1, 1, 0},
+/* 13 */ { 4, s_1_13, -1, 3, 0},
+/* 14 */ { 4, s_1_14, -1, 4, 0},
+/* 15 */ { 5, s_1_15, 14, 4, 0}
+};
+
+static const symbol s_2_0[5] = { 'i', 'c', 'a', 'l', 'a' };
+static const symbol s_2_1[5] = { 'i', 'c', 'i', 'v', 'a' };
+static const symbol s_2_2[5] = { 'a', 't', 'i', 'v', 'a' };
+static const symbol s_2_3[5] = { 'i', 't', 'i', 'v', 'a' };
+static const symbol s_2_4[5] = { 'i', 'c', 'a', 'l', 'e' };
+static const symbol s_2_5[6] = { 'a', 0xFE, 'i', 'u', 'n', 'e' };
+static const symbol s_2_6[6] = { 'i', 0xFE, 'i', 'u', 'n', 'e' };
+static const symbol s_2_7[6] = { 'a', 't', 'o', 'a', 'r', 'e' };
+static const symbol s_2_8[6] = { 'i', 't', 'o', 'a', 'r', 'e' };
+static const symbol s_2_9[6] = { 0xE3, 't', 'o', 'a', 'r', 'e' };
+static const symbol s_2_10[7] = { 'i', 'c', 'i', 't', 'a', 't', 'e' };
+static const symbol s_2_11[9] = { 'a', 'b', 'i', 'l', 'i', 't', 'a', 't', 'e' };
+static const symbol s_2_12[9] = { 'i', 'b', 'i', 'l', 'i', 't', 'a', 't', 'e' };
+static const symbol s_2_13[7] = { 'i', 'v', 'i', 't', 'a', 't', 'e' };
+static const symbol s_2_14[5] = { 'i', 'c', 'i', 'v', 'e' };
+static const symbol s_2_15[5] = { 'a', 't', 'i', 'v', 'e' };
+static const symbol s_2_16[5] = { 'i', 't', 'i', 'v', 'e' };
+static const symbol s_2_17[5] = { 'i', 'c', 'a', 'l', 'i' };
+static const symbol s_2_18[5] = { 'a', 't', 'o', 'r', 'i' };
+static const symbol s_2_19[7] = { 'i', 'c', 'a', 't', 'o', 'r', 'i' };
+static const symbol s_2_20[5] = { 'i', 't', 'o', 'r', 'i' };
+static const symbol s_2_21[5] = { 0xE3, 't', 'o', 'r', 'i' };
+static const symbol s_2_22[7] = { 'i', 'c', 'i', 't', 'a', 't', 'i' };
+static const symbol s_2_23[9] = { 'a', 'b', 'i', 'l', 'i', 't', 'a', 't', 'i' };
+static const symbol s_2_24[7] = { 'i', 'v', 'i', 't', 'a', 't', 'i' };
+static const symbol s_2_25[5] = { 'i', 'c', 'i', 'v', 'i' };
+static const symbol s_2_26[5] = { 'a', 't', 'i', 'v', 'i' };
+static const symbol s_2_27[5] = { 'i', 't', 'i', 'v', 'i' };
+static const symbol s_2_28[6] = { 'i', 'c', 'i', 't', 0xE3, 'i' };
+static const symbol s_2_29[8] = { 'a', 'b', 'i', 'l', 'i', 't', 0xE3, 'i' };
+static const symbol s_2_30[6] = { 'i', 'v', 'i', 't', 0xE3, 'i' };
+static const symbol s_2_31[7] = { 'i', 'c', 'i', 't', 0xE3, 0xFE, 'i' };
+static const symbol s_2_32[9] = { 'a', 'b', 'i', 'l', 'i', 't', 0xE3, 0xFE, 'i' };
+static const symbol s_2_33[7] = { 'i', 'v', 'i', 't', 0xE3, 0xFE, 'i' };
+static const symbol s_2_34[4] = { 'i', 'c', 'a', 'l' };
+static const symbol s_2_35[4] = { 'a', 't', 'o', 'r' };
+static const symbol s_2_36[6] = { 'i', 'c', 'a', 't', 'o', 'r' };
+static const symbol s_2_37[4] = { 'i', 't', 'o', 'r' };
+static const symbol s_2_38[4] = { 0xE3, 't', 'o', 'r' };
+static const symbol s_2_39[4] = { 'i', 'c', 'i', 'v' };
+static const symbol s_2_40[4] = { 'a', 't', 'i', 'v' };
+static const symbol s_2_41[4] = { 'i', 't', 'i', 'v' };
+static const symbol s_2_42[5] = { 'i', 'c', 'a', 'l', 0xE3 };
+static const symbol s_2_43[5] = { 'i', 'c', 'i', 'v', 0xE3 };
+static const symbol s_2_44[5] = { 'a', 't', 'i', 'v', 0xE3 };
+static const symbol s_2_45[5] = { 'i', 't', 'i', 'v', 0xE3 };
+
+static const struct among a_2[46] =
+{
+/* 0 */ { 5, s_2_0, -1, 4, 0},
+/* 1 */ { 5, s_2_1, -1, 4, 0},
+/* 2 */ { 5, s_2_2, -1, 5, 0},
+/* 3 */ { 5, s_2_3, -1, 6, 0},
+/* 4 */ { 5, s_2_4, -1, 4, 0},
+/* 5 */ { 6, s_2_5, -1, 5, 0},
+/* 6 */ { 6, s_2_6, -1, 6, 0},
+/* 7 */ { 6, s_2_7, -1, 5, 0},
+/* 8 */ { 6, s_2_8, -1, 6, 0},
+/* 9 */ { 6, s_2_9, -1, 5, 0},
+/* 10 */ { 7, s_2_10, -1, 4, 0},
+/* 11 */ { 9, s_2_11, -1, 1, 0},
+/* 12 */ { 9, s_2_12, -1, 2, 0},
+/* 13 */ { 7, s_2_13, -1, 3, 0},
+/* 14 */ { 5, s_2_14, -1, 4, 0},
+/* 15 */ { 5, s_2_15, -1, 5, 0},
+/* 16 */ { 5, s_2_16, -1, 6, 0},
+/* 17 */ { 5, s_2_17, -1, 4, 0},
+/* 18 */ { 5, s_2_18, -1, 5, 0},
+/* 19 */ { 7, s_2_19, 18, 4, 0},
+/* 20 */ { 5, s_2_20, -1, 6, 0},
+/* 21 */ { 5, s_2_21, -1, 5, 0},
+/* 22 */ { 7, s_2_22, -1, 4, 0},
+/* 23 */ { 9, s_2_23, -1, 1, 0},
+/* 24 */ { 7, s_2_24, -1, 3, 0},
+/* 25 */ { 5, s_2_25, -1, 4, 0},
+/* 26 */ { 5, s_2_26, -1, 5, 0},
+/* 27 */ { 5, s_2_27, -1, 6, 0},
+/* 28 */ { 6, s_2_28, -1, 4, 0},
+/* 29 */ { 8, s_2_29, -1, 1, 0},
+/* 30 */ { 6, s_2_30, -1, 3, 0},
+/* 31 */ { 7, s_2_31, -1, 4, 0},
+/* 32 */ { 9, s_2_32, -1, 1, 0},
+/* 33 */ { 7, s_2_33, -1, 3, 0},
+/* 34 */ { 4, s_2_34, -1, 4, 0},
+/* 35 */ { 4, s_2_35, -1, 5, 0},
+/* 36 */ { 6, s_2_36, 35, 4, 0},
+/* 37 */ { 4, s_2_37, -1, 6, 0},
+/* 38 */ { 4, s_2_38, -1, 5, 0},
+/* 39 */ { 4, s_2_39, -1, 4, 0},
+/* 40 */ { 4, s_2_40, -1, 5, 0},
+/* 41 */ { 4, s_2_41, -1, 6, 0},
+/* 42 */ { 5, s_2_42, -1, 4, 0},
+/* 43 */ { 5, s_2_43, -1, 4, 0},
+/* 44 */ { 5, s_2_44, -1, 5, 0},
+/* 45 */ { 5, s_2_45, -1, 6, 0}
+};
+
+static const symbol s_3_0[3] = { 'i', 'c', 'a' };
+static const symbol s_3_1[5] = { 'a', 'b', 'i', 'l', 'a' };
+static const symbol s_3_2[5] = { 'i', 'b', 'i', 'l', 'a' };
+static const symbol s_3_3[4] = { 'o', 'a', 's', 'a' };
+static const symbol s_3_4[3] = { 'a', 't', 'a' };
+static const symbol s_3_5[3] = { 'i', 't', 'a' };
+static const symbol s_3_6[4] = { 'a', 'n', 't', 'a' };
+static const symbol s_3_7[4] = { 'i', 's', 't', 'a' };
+static const symbol s_3_8[3] = { 'u', 't', 'a' };
+static const symbol s_3_9[3] = { 'i', 'v', 'a' };
+static const symbol s_3_10[2] = { 'i', 'c' };
+static const symbol s_3_11[3] = { 'i', 'c', 'e' };
+static const symbol s_3_12[5] = { 'a', 'b', 'i', 'l', 'e' };
+static const symbol s_3_13[5] = { 'i', 'b', 'i', 'l', 'e' };
+static const symbol s_3_14[4] = { 'i', 's', 'm', 'e' };
+static const symbol s_3_15[4] = { 'i', 'u', 'n', 'e' };
+static const symbol s_3_16[4] = { 'o', 'a', 's', 'e' };
+static const symbol s_3_17[3] = { 'a', 't', 'e' };
+static const symbol s_3_18[5] = { 'i', 't', 'a', 't', 'e' };
+static const symbol s_3_19[3] = { 'i', 't', 'e' };
+static const symbol s_3_20[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_3_21[4] = { 'i', 's', 't', 'e' };
+static const symbol s_3_22[3] = { 'u', 't', 'e' };
+static const symbol s_3_23[3] = { 'i', 'v', 'e' };
+static const symbol s_3_24[3] = { 'i', 'c', 'i' };
+static const symbol s_3_25[5] = { 'a', 'b', 'i', 'l', 'i' };
+static const symbol s_3_26[5] = { 'i', 'b', 'i', 'l', 'i' };
+static const symbol s_3_27[4] = { 'i', 'u', 'n', 'i' };
+static const symbol s_3_28[5] = { 'a', 't', 'o', 'r', 'i' };
+static const symbol s_3_29[3] = { 'o', 's', 'i' };
+static const symbol s_3_30[3] = { 'a', 't', 'i' };
+static const symbol s_3_31[5] = { 'i', 't', 'a', 't', 'i' };
+static const symbol s_3_32[3] = { 'i', 't', 'i' };
+static const symbol s_3_33[4] = { 'a', 'n', 't', 'i' };
+static const symbol s_3_34[4] = { 'i', 's', 't', 'i' };
+static const symbol s_3_35[3] = { 'u', 't', 'i' };
+static const symbol s_3_36[4] = { 'i', 0xBA, 't', 'i' };
+static const symbol s_3_37[3] = { 'i', 'v', 'i' };
+static const symbol s_3_38[3] = { 'o', 0xBA, 'i' };
+static const symbol s_3_39[4] = { 'i', 't', 0xE3, 'i' };
+static const symbol s_3_40[5] = { 'i', 't', 0xE3, 0xFE, 'i' };
+static const symbol s_3_41[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_3_42[4] = { 'i', 'b', 'i', 'l' };
+static const symbol s_3_43[3] = { 'i', 's', 'm' };
+static const symbol s_3_44[4] = { 'a', 't', 'o', 'r' };
+static const symbol s_3_45[2] = { 'o', 's' };
+static const symbol s_3_46[2] = { 'a', 't' };
+static const symbol s_3_47[2] = { 'i', 't' };
+static const symbol s_3_48[3] = { 'a', 'n', 't' };
+static const symbol s_3_49[3] = { 'i', 's', 't' };
+static const symbol s_3_50[2] = { 'u', 't' };
+static const symbol s_3_51[2] = { 'i', 'v' };
+static const symbol s_3_52[3] = { 'i', 'c', 0xE3 };
+static const symbol s_3_53[5] = { 'a', 'b', 'i', 'l', 0xE3 };
+static const symbol s_3_54[5] = { 'i', 'b', 'i', 'l', 0xE3 };
+static const symbol s_3_55[4] = { 'o', 'a', 's', 0xE3 };
+static const symbol s_3_56[3] = { 'a', 't', 0xE3 };
+static const symbol s_3_57[3] = { 'i', 't', 0xE3 };
+static const symbol s_3_58[4] = { 'a', 'n', 't', 0xE3 };
+static const symbol s_3_59[4] = { 'i', 's', 't', 0xE3 };
+static const symbol s_3_60[3] = { 'u', 't', 0xE3 };
+static const symbol s_3_61[3] = { 'i', 'v', 0xE3 };
+
+static const struct among a_3[62] =
+{
+/* 0 */ { 3, s_3_0, -1, 1, 0},
+/* 1 */ { 5, s_3_1, -1, 1, 0},
+/* 2 */ { 5, s_3_2, -1, 1, 0},
+/* 3 */ { 4, s_3_3, -1, 1, 0},
+/* 4 */ { 3, s_3_4, -1, 1, 0},
+/* 5 */ { 3, s_3_5, -1, 1, 0},
+/* 6 */ { 4, s_3_6, -1, 1, 0},
+/* 7 */ { 4, s_3_7, -1, 3, 0},
+/* 8 */ { 3, s_3_8, -1, 1, 0},
+/* 9 */ { 3, s_3_9, -1, 1, 0},
+/* 10 */ { 2, s_3_10, -1, 1, 0},
+/* 11 */ { 3, s_3_11, -1, 1, 0},
+/* 12 */ { 5, s_3_12, -1, 1, 0},
+/* 13 */ { 5, s_3_13, -1, 1, 0},
+/* 14 */ { 4, s_3_14, -1, 3, 0},
+/* 15 */ { 4, s_3_15, -1, 2, 0},
+/* 16 */ { 4, s_3_16, -1, 1, 0},
+/* 17 */ { 3, s_3_17, -1, 1, 0},
+/* 18 */ { 5, s_3_18, 17, 1, 0},
+/* 19 */ { 3, s_3_19, -1, 1, 0},
+/* 20 */ { 4, s_3_20, -1, 1, 0},
+/* 21 */ { 4, s_3_21, -1, 3, 0},
+/* 22 */ { 3, s_3_22, -1, 1, 0},
+/* 23 */ { 3, s_3_23, -1, 1, 0},
+/* 24 */ { 3, s_3_24, -1, 1, 0},
+/* 25 */ { 5, s_3_25, -1, 1, 0},
+/* 26 */ { 5, s_3_26, -1, 1, 0},
+/* 27 */ { 4, s_3_27, -1, 2, 0},
+/* 28 */ { 5, s_3_28, -1, 1, 0},
+/* 29 */ { 3, s_3_29, -1, 1, 0},
+/* 30 */ { 3, s_3_30, -1, 1, 0},
+/* 31 */ { 5, s_3_31, 30, 1, 0},
+/* 32 */ { 3, s_3_32, -1, 1, 0},
+/* 33 */ { 4, s_3_33, -1, 1, 0},
+/* 34 */ { 4, s_3_34, -1, 3, 0},
+/* 35 */ { 3, s_3_35, -1, 1, 0},
+/* 36 */ { 4, s_3_36, -1, 3, 0},
+/* 37 */ { 3, s_3_37, -1, 1, 0},
+/* 38 */ { 3, s_3_38, -1, 1, 0},
+/* 39 */ { 4, s_3_39, -1, 1, 0},
+/* 40 */ { 5, s_3_40, -1, 1, 0},
+/* 41 */ { 4, s_3_41, -1, 1, 0},
+/* 42 */ { 4, s_3_42, -1, 1, 0},
+/* 43 */ { 3, s_3_43, -1, 3, 0},
+/* 44 */ { 4, s_3_44, -1, 1, 0},
+/* 45 */ { 2, s_3_45, -1, 1, 0},
+/* 46 */ { 2, s_3_46, -1, 1, 0},
+/* 47 */ { 2, s_3_47, -1, 1, 0},
+/* 48 */ { 3, s_3_48, -1, 1, 0},
+/* 49 */ { 3, s_3_49, -1, 3, 0},
+/* 50 */ { 2, s_3_50, -1, 1, 0},
+/* 51 */ { 2, s_3_51, -1, 1, 0},
+/* 52 */ { 3, s_3_52, -1, 1, 0},
+/* 53 */ { 5, s_3_53, -1, 1, 0},
+/* 54 */ { 5, s_3_54, -1, 1, 0},
+/* 55 */ { 4, s_3_55, -1, 1, 0},
+/* 56 */ { 3, s_3_56, -1, 1, 0},
+/* 57 */ { 3, s_3_57, -1, 1, 0},
+/* 58 */ { 4, s_3_58, -1, 1, 0},
+/* 59 */ { 4, s_3_59, -1, 3, 0},
+/* 60 */ { 3, s_3_60, -1, 1, 0},
+/* 61 */ { 3, s_3_61, -1, 1, 0}
+};
+
+static const symbol s_4_0[2] = { 'e', 'a' };
+static const symbol s_4_1[2] = { 'i', 'a' };
+static const symbol s_4_2[3] = { 'e', 's', 'c' };
+static const symbol s_4_3[3] = { 0xE3, 's', 'c' };
+static const symbol s_4_4[3] = { 'i', 'n', 'd' };
+static const symbol s_4_5[3] = { 0xE2, 'n', 'd' };
+static const symbol s_4_6[3] = { 'a', 'r', 'e' };
+static const symbol s_4_7[3] = { 'e', 'r', 'e' };
+static const symbol s_4_8[3] = { 'i', 'r', 'e' };
+static const symbol s_4_9[3] = { 0xE2, 'r', 'e' };
+static const symbol s_4_10[2] = { 's', 'e' };
+static const symbol s_4_11[3] = { 'a', 's', 'e' };
+static const symbol s_4_12[4] = { 's', 'e', 's', 'e' };
+static const symbol s_4_13[3] = { 'i', 's', 'e' };
+static const symbol s_4_14[3] = { 'u', 's', 'e' };
+static const symbol s_4_15[3] = { 0xE2, 's', 'e' };
+static const symbol s_4_16[4] = { 'e', 0xBA, 't', 'e' };
+static const symbol s_4_17[4] = { 0xE3, 0xBA, 't', 'e' };
+static const symbol s_4_18[3] = { 'e', 'z', 'e' };
+static const symbol s_4_19[2] = { 'a', 'i' };
+static const symbol s_4_20[3] = { 'e', 'a', 'i' };
+static const symbol s_4_21[3] = { 'i', 'a', 'i' };
+static const symbol s_4_22[3] = { 's', 'e', 'i' };
+static const symbol s_4_23[4] = { 'e', 0xBA, 't', 'i' };
+static const symbol s_4_24[4] = { 0xE3, 0xBA, 't', 'i' };
+static const symbol s_4_25[2] = { 'u', 'i' };
+static const symbol s_4_26[3] = { 'e', 'z', 'i' };
+static const symbol s_4_27[3] = { 'a', 0xBA, 'i' };
+static const symbol s_4_28[4] = { 's', 'e', 0xBA, 'i' };
+static const symbol s_4_29[5] = { 'a', 's', 'e', 0xBA, 'i' };
+static const symbol s_4_30[6] = { 's', 'e', 's', 'e', 0xBA, 'i' };
+static const symbol s_4_31[5] = { 'i', 's', 'e', 0xBA, 'i' };
+static const symbol s_4_32[5] = { 'u', 's', 'e', 0xBA, 'i' };
+static const symbol s_4_33[5] = { 0xE2, 's', 'e', 0xBA, 'i' };
+static const symbol s_4_34[3] = { 'i', 0xBA, 'i' };
+static const symbol s_4_35[3] = { 'u', 0xBA, 'i' };
+static const symbol s_4_36[3] = { 0xE2, 0xBA, 'i' };
+static const symbol s_4_37[2] = { 0xE2, 'i' };
+static const symbol s_4_38[3] = { 'a', 0xFE, 'i' };
+static const symbol s_4_39[4] = { 'e', 'a', 0xFE, 'i' };
+static const symbol s_4_40[4] = { 'i', 'a', 0xFE, 'i' };
+static const symbol s_4_41[3] = { 'e', 0xFE, 'i' };
+static const symbol s_4_42[3] = { 'i', 0xFE, 'i' };
+static const symbol s_4_43[3] = { 0xE2, 0xFE, 'i' };
+static const symbol s_4_44[5] = { 'a', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_45[6] = { 's', 'e', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_46[7] = { 'a', 's', 'e', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_47[8] = { 's', 'e', 's', 'e', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_48[7] = { 'i', 's', 'e', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_49[7] = { 'u', 's', 'e', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_50[7] = { 0xE2, 's', 'e', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_51[5] = { 'i', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_52[5] = { 'u', 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_53[5] = { 0xE2, 'r', 0xE3, 0xFE, 'i' };
+static const symbol s_4_54[2] = { 'a', 'm' };
+static const symbol s_4_55[3] = { 'e', 'a', 'm' };
+static const symbol s_4_56[3] = { 'i', 'a', 'm' };
+static const symbol s_4_57[2] = { 'e', 'm' };
+static const symbol s_4_58[4] = { 'a', 's', 'e', 'm' };
+static const symbol s_4_59[5] = { 's', 'e', 's', 'e', 'm' };
+static const symbol s_4_60[4] = { 'i', 's', 'e', 'm' };
+static const symbol s_4_61[4] = { 'u', 's', 'e', 'm' };
+static const symbol s_4_62[4] = { 0xE2, 's', 'e', 'm' };
+static const symbol s_4_63[2] = { 'i', 'm' };
+static const symbol s_4_64[2] = { 0xE2, 'm' };
+static const symbol s_4_65[2] = { 0xE3, 'm' };
+static const symbol s_4_66[4] = { 'a', 'r', 0xE3, 'm' };
+static const symbol s_4_67[5] = { 's', 'e', 'r', 0xE3, 'm' };
+static const symbol s_4_68[6] = { 'a', 's', 'e', 'r', 0xE3, 'm' };
+static const symbol s_4_69[7] = { 's', 'e', 's', 'e', 'r', 0xE3, 'm' };
+static const symbol s_4_70[6] = { 'i', 's', 'e', 'r', 0xE3, 'm' };
+static const symbol s_4_71[6] = { 'u', 's', 'e', 'r', 0xE3, 'm' };
+static const symbol s_4_72[6] = { 0xE2, 's', 'e', 'r', 0xE3, 'm' };
+static const symbol s_4_73[4] = { 'i', 'r', 0xE3, 'm' };
+static const symbol s_4_74[4] = { 'u', 'r', 0xE3, 'm' };
+static const symbol s_4_75[4] = { 0xE2, 'r', 0xE3, 'm' };
+static const symbol s_4_76[2] = { 'a', 'u' };
+static const symbol s_4_77[3] = { 'e', 'a', 'u' };
+static const symbol s_4_78[3] = { 'i', 'a', 'u' };
+static const symbol s_4_79[4] = { 'i', 'n', 'd', 'u' };
+static const symbol s_4_80[4] = { 0xE2, 'n', 'd', 'u' };
+static const symbol s_4_81[2] = { 'e', 'z' };
+static const symbol s_4_82[5] = { 'e', 'a', 's', 'c', 0xE3 };
+static const symbol s_4_83[3] = { 'a', 'r', 0xE3 };
+static const symbol s_4_84[4] = { 's', 'e', 'r', 0xE3 };
+static const symbol s_4_85[5] = { 'a', 's', 'e', 'r', 0xE3 };
+static const symbol s_4_86[6] = { 's', 'e', 's', 'e', 'r', 0xE3 };
+static const symbol s_4_87[5] = { 'i', 's', 'e', 'r', 0xE3 };
+static const symbol s_4_88[5] = { 'u', 's', 'e', 'r', 0xE3 };
+static const symbol s_4_89[5] = { 0xE2, 's', 'e', 'r', 0xE3 };
+static const symbol s_4_90[3] = { 'i', 'r', 0xE3 };
+static const symbol s_4_91[3] = { 'u', 'r', 0xE3 };
+static const symbol s_4_92[3] = { 0xE2, 'r', 0xE3 };
+static const symbol s_4_93[4] = { 'e', 'a', 'z', 0xE3 };
+
+static const struct among a_4[94] =
+{
+/* 0 */ { 2, s_4_0, -1, 1, 0},
+/* 1 */ { 2, s_4_1, -1, 1, 0},
+/* 2 */ { 3, s_4_2, -1, 1, 0},
+/* 3 */ { 3, s_4_3, -1, 1, 0},
+/* 4 */ { 3, s_4_4, -1, 1, 0},
+/* 5 */ { 3, s_4_5, -1, 1, 0},
+/* 6 */ { 3, s_4_6, -1, 1, 0},
+/* 7 */ { 3, s_4_7, -1, 1, 0},
+/* 8 */ { 3, s_4_8, -1, 1, 0},
+/* 9 */ { 3, s_4_9, -1, 1, 0},
+/* 10 */ { 2, s_4_10, -1, 2, 0},
+/* 11 */ { 3, s_4_11, 10, 1, 0},
+/* 12 */ { 4, s_4_12, 10, 2, 0},
+/* 13 */ { 3, s_4_13, 10, 1, 0},
+/* 14 */ { 3, s_4_14, 10, 1, 0},
+/* 15 */ { 3, s_4_15, 10, 1, 0},
+/* 16 */ { 4, s_4_16, -1, 1, 0},
+/* 17 */ { 4, s_4_17, -1, 1, 0},
+/* 18 */ { 3, s_4_18, -1, 1, 0},
+/* 19 */ { 2, s_4_19, -1, 1, 0},
+/* 20 */ { 3, s_4_20, 19, 1, 0},
+/* 21 */ { 3, s_4_21, 19, 1, 0},
+/* 22 */ { 3, s_4_22, -1, 2, 0},
+/* 23 */ { 4, s_4_23, -1, 1, 0},
+/* 24 */ { 4, s_4_24, -1, 1, 0},
+/* 25 */ { 2, s_4_25, -1, 1, 0},
+/* 26 */ { 3, s_4_26, -1, 1, 0},
+/* 27 */ { 3, s_4_27, -1, 1, 0},
+/* 28 */ { 4, s_4_28, -1, 2, 0},
+/* 29 */ { 5, s_4_29, 28, 1, 0},
+/* 30 */ { 6, s_4_30, 28, 2, 0},
+/* 31 */ { 5, s_4_31, 28, 1, 0},
+/* 32 */ { 5, s_4_32, 28, 1, 0},
+/* 33 */ { 5, s_4_33, 28, 1, 0},
+/* 34 */ { 3, s_4_34, -1, 1, 0},
+/* 35 */ { 3, s_4_35, -1, 1, 0},
+/* 36 */ { 3, s_4_36, -1, 1, 0},
+/* 37 */ { 2, s_4_37, -1, 1, 0},
+/* 38 */ { 3, s_4_38, -1, 2, 0},
+/* 39 */ { 4, s_4_39, 38, 1, 0},
+/* 40 */ { 4, s_4_40, 38, 1, 0},
+/* 41 */ { 3, s_4_41, -1, 2, 0},
+/* 42 */ { 3, s_4_42, -1, 2, 0},
+/* 43 */ { 3, s_4_43, -1, 2, 0},
+/* 44 */ { 5, s_4_44, -1, 1, 0},
+/* 45 */ { 6, s_4_45, -1, 2, 0},
+/* 46 */ { 7, s_4_46, 45, 1, 0},
+/* 47 */ { 8, s_4_47, 45, 2, 0},
+/* 48 */ { 7, s_4_48, 45, 1, 0},
+/* 49 */ { 7, s_4_49, 45, 1, 0},
+/* 50 */ { 7, s_4_50, 45, 1, 0},
+/* 51 */ { 5, s_4_51, -1, 1, 0},
+/* 52 */ { 5, s_4_52, -1, 1, 0},
+/* 53 */ { 5, s_4_53, -1, 1, 0},
+/* 54 */ { 2, s_4_54, -1, 1, 0},
+/* 55 */ { 3, s_4_55, 54, 1, 0},
+/* 56 */ { 3, s_4_56, 54, 1, 0},
+/* 57 */ { 2, s_4_57, -1, 2, 0},
+/* 58 */ { 4, s_4_58, 57, 1, 0},
+/* 59 */ { 5, s_4_59, 57, 2, 0},
+/* 60 */ { 4, s_4_60, 57, 1, 0},
+/* 61 */ { 4, s_4_61, 57, 1, 0},
+/* 62 */ { 4, s_4_62, 57, 1, 0},
+/* 63 */ { 2, s_4_63, -1, 2, 0},
+/* 64 */ { 2, s_4_64, -1, 2, 0},
+/* 65 */ { 2, s_4_65, -1, 2, 0},
+/* 66 */ { 4, s_4_66, 65, 1, 0},
+/* 67 */ { 5, s_4_67, 65, 2, 0},
+/* 68 */ { 6, s_4_68, 67, 1, 0},
+/* 69 */ { 7, s_4_69, 67, 2, 0},
+/* 70 */ { 6, s_4_70, 67, 1, 0},
+/* 71 */ { 6, s_4_71, 67, 1, 0},
+/* 72 */ { 6, s_4_72, 67, 1, 0},
+/* 73 */ { 4, s_4_73, 65, 1, 0},
+/* 74 */ { 4, s_4_74, 65, 1, 0},
+/* 75 */ { 4, s_4_75, 65, 1, 0},
+/* 76 */ { 2, s_4_76, -1, 1, 0},
+/* 77 */ { 3, s_4_77, 76, 1, 0},
+/* 78 */ { 3, s_4_78, 76, 1, 0},
+/* 79 */ { 4, s_4_79, -1, 1, 0},
+/* 80 */ { 4, s_4_80, -1, 1, 0},
+/* 81 */ { 2, s_4_81, -1, 1, 0},
+/* 82 */ { 5, s_4_82, -1, 1, 0},
+/* 83 */ { 3, s_4_83, -1, 1, 0},
+/* 84 */ { 4, s_4_84, -1, 2, 0},
+/* 85 */ { 5, s_4_85, 84, 1, 0},
+/* 86 */ { 6, s_4_86, 84, 2, 0},
+/* 87 */ { 5, s_4_87, 84, 1, 0},
+/* 88 */ { 5, s_4_88, 84, 1, 0},
+/* 89 */ { 5, s_4_89, 84, 1, 0},
+/* 90 */ { 3, s_4_90, -1, 1, 0},
+/* 91 */ { 3, s_4_91, -1, 1, 0},
+/* 92 */ { 3, s_4_92, -1, 1, 0},
+/* 93 */ { 4, s_4_93, -1, 1, 0}
+};
+
+static const symbol s_5_0[1] = { 'a' };
+static const symbol s_5_1[1] = { 'e' };
+static const symbol s_5_2[2] = { 'i', 'e' };
+static const symbol s_5_3[1] = { 'i' };
+static const symbol s_5_4[1] = { 0xE3 };
+
+static const struct among a_5[5] =
+{
+/* 0 */ { 1, s_5_0, -1, 1, 0},
+/* 1 */ { 1, s_5_1, -1, 1, 0},
+/* 2 */ { 2, s_5_2, 1, 1, 0},
+/* 3 */ { 1, s_5_3, -1, 1, 0},
+/* 4 */ { 1, s_5_4, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 32 };
+
+static const symbol s_0[] = { 'u' };
+static const symbol s_1[] = { 'U' };
+static const symbol s_2[] = { 'i' };
+static const symbol s_3[] = { 'I' };
+static const symbol s_4[] = { 'i' };
+static const symbol s_5[] = { 'u' };
+static const symbol s_6[] = { 'a' };
+static const symbol s_7[] = { 'e' };
+static const symbol s_8[] = { 'i' };
+static const symbol s_9[] = { 'a', 'b' };
+static const symbol s_10[] = { 'i' };
+static const symbol s_11[] = { 'a', 't' };
+static const symbol s_12[] = { 'a', 0xFE, 'i' };
+static const symbol s_13[] = { 'a', 'b', 'i', 'l' };
+static const symbol s_14[] = { 'i', 'b', 'i', 'l' };
+static const symbol s_15[] = { 'i', 'v' };
+static const symbol s_16[] = { 'i', 'c' };
+static const symbol s_17[] = { 'a', 't' };
+static const symbol s_18[] = { 'i', 't' };
+static const symbol s_19[] = { 0xFE };
+static const symbol s_20[] = { 't' };
+static const symbol s_21[] = { 'i', 's', 't' };
+static const symbol s_22[] = { 'u' };
+
+static int r_prelude(struct SN_env * z) {
+ while(1) { /* repeat, line 32 */
+ int c1 = z->c;
+ while(1) { /* goto, line 32 */
+ int c2 = z->c;
+ if (in_grouping(z, g_v, 97, 238, 0)) goto lab1;
+ z->bra = z->c; /* [, line 33 */
+ { int c3 = z->c; /* or, line 33 */
+ if (!(eq_s(z, 1, s_0))) goto lab3;
+ z->ket = z->c; /* ], line 33 */
+ if (in_grouping(z, g_v, 97, 238, 0)) goto lab3;
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 33 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab3:
+ z->c = c3;
+ if (!(eq_s(z, 1, s_2))) goto lab1;
+ z->ket = z->c; /* ], line 34 */
+ if (in_grouping(z, g_v, 97, 238, 0)) goto lab1;
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 34 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab2:
+ z->c = c2;
+ break;
+ lab1:
+ z->c = c2;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* goto, line 32 */
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 44 */
+ { int c2 = z->c; /* or, line 46 */
+ if (in_grouping(z, g_v, 97, 238, 0)) goto lab2;
+ { int c3 = z->c; /* or, line 45 */
+ if (out_grouping(z, g_v, 97, 238, 0)) goto lab4;
+ { /* gopast */ /* grouping v, line 45 */
+ int ret = out_grouping(z, g_v, 97, 238, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c3;
+ if (in_grouping(z, g_v, 97, 238, 0)) goto lab2;
+ { /* gopast */ /* non v, line 45 */
+ int ret = in_grouping(z, g_v, 97, 238, 1);
+ if (ret < 0) goto lab2;
+ z->c += ret;
+ }
+ }
+ lab3:
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (out_grouping(z, g_v, 97, 238, 0)) goto lab0;
+ { int c4 = z->c; /* or, line 47 */
+ if (out_grouping(z, g_v, 97, 238, 0)) goto lab6;
+ { /* gopast */ /* grouping v, line 47 */
+ int ret = out_grouping(z, g_v, 97, 238, 1);
+ if (ret < 0) goto lab6;
+ z->c += ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c4;
+ if (in_grouping(z, g_v, 97, 238, 0)) goto lab0;
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 47 */
+ }
+ lab5:
+ ;
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 48 */
+ lab0:
+ z->c = c1;
+ }
+ { int c5 = z->c; /* do, line 50 */
+ { /* gopast */ /* grouping v, line 51 */
+ int ret = out_grouping(z, g_v, 97, 238, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 51 */
+ int ret = in_grouping(z, g_v, 97, 238, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 51 */
+ { /* gopast */ /* grouping v, line 52 */
+ int ret = out_grouping(z, g_v, 97, 238, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 52 */
+ int ret = in_grouping(z, g_v, 97, 238, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 52 */
+ lab7:
+ z->c = c5;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 56 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 58 */
+ if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else
+ among_var = find_among(z, a_0, 3); /* substring, line 58 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 58 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 60 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c >= z->l) goto lab0;
+ z->c++; /* next, line 61 */
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_step_0(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 73 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_1, 16); /* substring, line 73 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 73 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 73 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 75 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 79 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_8); /* <-, line 81 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int m1 = z->l - z->c; (void)m1; /* not, line 83 */
+ if (!(eq_s_b(z, 2, s_9))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m1;
+ }
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 83 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 2, s_11); /* <-, line 85 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 3, s_12); /* <-, line 87 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_combo_suffix(struct SN_env * z) {
+ int among_var;
+ { int m_test = z->l - z->c; /* test, line 91 */
+ z->ket = z->c; /* [, line 92 */
+ among_var = find_among_b(z, a_2, 46); /* substring, line 92 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 92 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 92 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 4, s_13); /* <-, line 101 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 4, s_14); /* <-, line 104 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 2, s_15); /* <-, line 107 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 2, s_16); /* <-, line 113 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 2, s_17); /* <-, line 118 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 2, s_18); /* <-, line 122 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->B[0] = 1; /* set standard_suffix_removed, line 125 */
+ z->c = z->l - m_test;
+ }
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->B[0] = 0; /* unset standard_suffix_removed, line 130 */
+ while(1) { /* repeat, line 131 */
+ int m1 = z->l - z->c; (void)m1;
+ { int ret = r_combo_suffix(z);
+ if (ret == 0) goto lab0; /* call combo_suffix, line 131 */
+ if (ret < 0) return ret;
+ }
+ continue;
+ lab0:
+ z->c = z->l - m1;
+ break;
+ }
+ z->ket = z->c; /* [, line 132 */
+ among_var = find_among_b(z, a_3, 62); /* substring, line 132 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 132 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 132 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 149 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (!(eq_s_b(z, 1, s_19))) return 0;
+ z->bra = z->c; /* ], line 152 */
+ { int ret = slice_from_s(z, 1, s_20); /* <-, line 152 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 3, s_21); /* <-, line 156 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->B[0] = 1; /* set standard_suffix_removed, line 160 */
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 164 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 164 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 165 */
+ among_var = find_among_b(z, a_4, 94); /* substring, line 165 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 165 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int m2 = z->l - z->c; (void)m2; /* or, line 200 */
+ if (out_grouping_b(z, g_v, 97, 238, 0)) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m2;
+ if (!(eq_s_b(z, 1, s_22))) { z->lb = mlimit; return 0; }
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 200 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 214 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_vowel_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 219 */
+ among_var = find_among_b(z, a_5, 5); /* substring, line 219 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 219 */
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 219 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 220 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int romanian_ISO_8859_2_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 226 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 226 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 227 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 227 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 228 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 229 */
+ { int ret = r_step_0(z);
+ if (ret == 0) goto lab2; /* call step_0, line 229 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 230 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab3; /* call standard_suffix, line 230 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 231 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 231 */
+ if (!(z->B[0])) goto lab6; /* Boolean test standard_suffix_removed, line 231 */
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab4; /* call verb_suffix, line 231 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ lab4:
+ z->c = z->l - m5;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 232 */
+ { int ret = r_vowel_suffix(z);
+ if (ret == 0) goto lab7; /* call vowel_suffix, line 232 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m7;
+ }
+ z->c = z->lb;
+ { int c8 = z->c; /* do, line 234 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab8; /* call postlude, line 234 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = c8;
+ }
+ return 1;
+}
+
+extern struct SN_env * romanian_ISO_8859_2_create_env(void) { return SN_create_env(0, 3, 1); }
+
+extern void romanian_ISO_8859_2_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c b/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c
new file mode 100644
index 00000000000..be7feb752ee
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c
@@ -0,0 +1,700 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int russian_KOI8_R_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_tidy_up(struct SN_env * z);
+static int r_derivational(struct SN_env * z);
+static int r_noun(struct SN_env * z);
+static int r_verb(struct SN_env * z);
+static int r_reflexive(struct SN_env * z);
+static int r_adjectival(struct SN_env * z);
+static int r_adjective(struct SN_env * z);
+static int r_perfective_gerund(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * russian_KOI8_R_create_env(void);
+extern void russian_KOI8_R_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[3] = { 0xD7, 0xDB, 0xC9 };
+static const symbol s_0_1[4] = { 0xC9, 0xD7, 0xDB, 0xC9 };
+static const symbol s_0_2[4] = { 0xD9, 0xD7, 0xDB, 0xC9 };
+static const symbol s_0_3[1] = { 0xD7 };
+static const symbol s_0_4[2] = { 0xC9, 0xD7 };
+static const symbol s_0_5[2] = { 0xD9, 0xD7 };
+static const symbol s_0_6[5] = { 0xD7, 0xDB, 0xC9, 0xD3, 0xD8 };
+static const symbol s_0_7[6] = { 0xC9, 0xD7, 0xDB, 0xC9, 0xD3, 0xD8 };
+static const symbol s_0_8[6] = { 0xD9, 0xD7, 0xDB, 0xC9, 0xD3, 0xD8 };
+
+static const struct among a_0[9] =
+{
+/* 0 */ { 3, s_0_0, -1, 1, 0},
+/* 1 */ { 4, s_0_1, 0, 2, 0},
+/* 2 */ { 4, s_0_2, 0, 2, 0},
+/* 3 */ { 1, s_0_3, -1, 1, 0},
+/* 4 */ { 2, s_0_4, 3, 2, 0},
+/* 5 */ { 2, s_0_5, 3, 2, 0},
+/* 6 */ { 5, s_0_6, -1, 1, 0},
+/* 7 */ { 6, s_0_7, 6, 2, 0},
+/* 8 */ { 6, s_0_8, 6, 2, 0}
+};
+
+static const symbol s_1_0[2] = { 0xC0, 0xC0 };
+static const symbol s_1_1[2] = { 0xC5, 0xC0 };
+static const symbol s_1_2[2] = { 0xCF, 0xC0 };
+static const symbol s_1_3[2] = { 0xD5, 0xC0 };
+static const symbol s_1_4[2] = { 0xC5, 0xC5 };
+static const symbol s_1_5[2] = { 0xC9, 0xC5 };
+static const symbol s_1_6[2] = { 0xCF, 0xC5 };
+static const symbol s_1_7[2] = { 0xD9, 0xC5 };
+static const symbol s_1_8[2] = { 0xC9, 0xC8 };
+static const symbol s_1_9[2] = { 0xD9, 0xC8 };
+static const symbol s_1_10[3] = { 0xC9, 0xCD, 0xC9 };
+static const symbol s_1_11[3] = { 0xD9, 0xCD, 0xC9 };
+static const symbol s_1_12[2] = { 0xC5, 0xCA };
+static const symbol s_1_13[2] = { 0xC9, 0xCA };
+static const symbol s_1_14[2] = { 0xCF, 0xCA };
+static const symbol s_1_15[2] = { 0xD9, 0xCA };
+static const symbol s_1_16[2] = { 0xC5, 0xCD };
+static const symbol s_1_17[2] = { 0xC9, 0xCD };
+static const symbol s_1_18[2] = { 0xCF, 0xCD };
+static const symbol s_1_19[2] = { 0xD9, 0xCD };
+static const symbol s_1_20[3] = { 0xC5, 0xC7, 0xCF };
+static const symbol s_1_21[3] = { 0xCF, 0xC7, 0xCF };
+static const symbol s_1_22[2] = { 0xC1, 0xD1 };
+static const symbol s_1_23[2] = { 0xD1, 0xD1 };
+static const symbol s_1_24[3] = { 0xC5, 0xCD, 0xD5 };
+static const symbol s_1_25[3] = { 0xCF, 0xCD, 0xD5 };
+
+static const struct among a_1[26] =
+{
+/* 0 */ { 2, s_1_0, -1, 1, 0},
+/* 1 */ { 2, s_1_1, -1, 1, 0},
+/* 2 */ { 2, s_1_2, -1, 1, 0},
+/* 3 */ { 2, s_1_3, -1, 1, 0},
+/* 4 */ { 2, s_1_4, -1, 1, 0},
+/* 5 */ { 2, s_1_5, -1, 1, 0},
+/* 6 */ { 2, s_1_6, -1, 1, 0},
+/* 7 */ { 2, s_1_7, -1, 1, 0},
+/* 8 */ { 2, s_1_8, -1, 1, 0},
+/* 9 */ { 2, s_1_9, -1, 1, 0},
+/* 10 */ { 3, s_1_10, -1, 1, 0},
+/* 11 */ { 3, s_1_11, -1, 1, 0},
+/* 12 */ { 2, s_1_12, -1, 1, 0},
+/* 13 */ { 2, s_1_13, -1, 1, 0},
+/* 14 */ { 2, s_1_14, -1, 1, 0},
+/* 15 */ { 2, s_1_15, -1, 1, 0},
+/* 16 */ { 2, s_1_16, -1, 1, 0},
+/* 17 */ { 2, s_1_17, -1, 1, 0},
+/* 18 */ { 2, s_1_18, -1, 1, 0},
+/* 19 */ { 2, s_1_19, -1, 1, 0},
+/* 20 */ { 3, s_1_20, -1, 1, 0},
+/* 21 */ { 3, s_1_21, -1, 1, 0},
+/* 22 */ { 2, s_1_22, -1, 1, 0},
+/* 23 */ { 2, s_1_23, -1, 1, 0},
+/* 24 */ { 3, s_1_24, -1, 1, 0},
+/* 25 */ { 3, s_1_25, -1, 1, 0}
+};
+
+static const symbol s_2_0[2] = { 0xC5, 0xCD };
+static const symbol s_2_1[2] = { 0xCE, 0xCE };
+static const symbol s_2_2[2] = { 0xD7, 0xDB };
+static const symbol s_2_3[3] = { 0xC9, 0xD7, 0xDB };
+static const symbol s_2_4[3] = { 0xD9, 0xD7, 0xDB };
+static const symbol s_2_5[1] = { 0xDD };
+static const symbol s_2_6[2] = { 0xC0, 0xDD };
+static const symbol s_2_7[3] = { 0xD5, 0xC0, 0xDD };
+
+static const struct among a_2[8] =
+{
+/* 0 */ { 2, s_2_0, -1, 1, 0},
+/* 1 */ { 2, s_2_1, -1, 1, 0},
+/* 2 */ { 2, s_2_2, -1, 1, 0},
+/* 3 */ { 3, s_2_3, 2, 2, 0},
+/* 4 */ { 3, s_2_4, 2, 2, 0},
+/* 5 */ { 1, s_2_5, -1, 1, 0},
+/* 6 */ { 2, s_2_6, 5, 1, 0},
+/* 7 */ { 3, s_2_7, 6, 2, 0}
+};
+
+static const symbol s_3_0[2] = { 0xD3, 0xD1 };
+static const symbol s_3_1[2] = { 0xD3, 0xD8 };
+
+static const struct among a_3[2] =
+{
+/* 0 */ { 2, s_3_0, -1, 1, 0},
+/* 1 */ { 2, s_3_1, -1, 1, 0}
+};
+
+static const symbol s_4_0[1] = { 0xC0 };
+static const symbol s_4_1[2] = { 0xD5, 0xC0 };
+static const symbol s_4_2[2] = { 0xCC, 0xC1 };
+static const symbol s_4_3[3] = { 0xC9, 0xCC, 0xC1 };
+static const symbol s_4_4[3] = { 0xD9, 0xCC, 0xC1 };
+static const symbol s_4_5[2] = { 0xCE, 0xC1 };
+static const symbol s_4_6[3] = { 0xC5, 0xCE, 0xC1 };
+static const symbol s_4_7[3] = { 0xC5, 0xD4, 0xC5 };
+static const symbol s_4_8[3] = { 0xC9, 0xD4, 0xC5 };
+static const symbol s_4_9[3] = { 0xCA, 0xD4, 0xC5 };
+static const symbol s_4_10[4] = { 0xC5, 0xCA, 0xD4, 0xC5 };
+static const symbol s_4_11[4] = { 0xD5, 0xCA, 0xD4, 0xC5 };
+static const symbol s_4_12[2] = { 0xCC, 0xC9 };
+static const symbol s_4_13[3] = { 0xC9, 0xCC, 0xC9 };
+static const symbol s_4_14[3] = { 0xD9, 0xCC, 0xC9 };
+static const symbol s_4_15[1] = { 0xCA };
+static const symbol s_4_16[2] = { 0xC5, 0xCA };
+static const symbol s_4_17[2] = { 0xD5, 0xCA };
+static const symbol s_4_18[1] = { 0xCC };
+static const symbol s_4_19[2] = { 0xC9, 0xCC };
+static const symbol s_4_20[2] = { 0xD9, 0xCC };
+static const symbol s_4_21[2] = { 0xC5, 0xCD };
+static const symbol s_4_22[2] = { 0xC9, 0xCD };
+static const symbol s_4_23[2] = { 0xD9, 0xCD };
+static const symbol s_4_24[1] = { 0xCE };
+static const symbol s_4_25[2] = { 0xC5, 0xCE };
+static const symbol s_4_26[2] = { 0xCC, 0xCF };
+static const symbol s_4_27[3] = { 0xC9, 0xCC, 0xCF };
+static const symbol s_4_28[3] = { 0xD9, 0xCC, 0xCF };
+static const symbol s_4_29[2] = { 0xCE, 0xCF };
+static const symbol s_4_30[3] = { 0xC5, 0xCE, 0xCF };
+static const symbol s_4_31[3] = { 0xCE, 0xCE, 0xCF };
+static const symbol s_4_32[2] = { 0xC0, 0xD4 };
+static const symbol s_4_33[3] = { 0xD5, 0xC0, 0xD4 };
+static const symbol s_4_34[2] = { 0xC5, 0xD4 };
+static const symbol s_4_35[3] = { 0xD5, 0xC5, 0xD4 };
+static const symbol s_4_36[2] = { 0xC9, 0xD4 };
+static const symbol s_4_37[2] = { 0xD1, 0xD4 };
+static const symbol s_4_38[2] = { 0xD9, 0xD4 };
+static const symbol s_4_39[2] = { 0xD4, 0xD8 };
+static const symbol s_4_40[3] = { 0xC9, 0xD4, 0xD8 };
+static const symbol s_4_41[3] = { 0xD9, 0xD4, 0xD8 };
+static const symbol s_4_42[3] = { 0xC5, 0xDB, 0xD8 };
+static const symbol s_4_43[3] = { 0xC9, 0xDB, 0xD8 };
+static const symbol s_4_44[2] = { 0xCE, 0xD9 };
+static const symbol s_4_45[3] = { 0xC5, 0xCE, 0xD9 };
+
+static const struct among a_4[46] =
+{
+/* 0 */ { 1, s_4_0, -1, 2, 0},
+/* 1 */ { 2, s_4_1, 0, 2, 0},
+/* 2 */ { 2, s_4_2, -1, 1, 0},
+/* 3 */ { 3, s_4_3, 2, 2, 0},
+/* 4 */ { 3, s_4_4, 2, 2, 0},
+/* 5 */ { 2, s_4_5, -1, 1, 0},
+/* 6 */ { 3, s_4_6, 5, 2, 0},
+/* 7 */ { 3, s_4_7, -1, 1, 0},
+/* 8 */ { 3, s_4_8, -1, 2, 0},
+/* 9 */ { 3, s_4_9, -1, 1, 0},
+/* 10 */ { 4, s_4_10, 9, 2, 0},
+/* 11 */ { 4, s_4_11, 9, 2, 0},
+/* 12 */ { 2, s_4_12, -1, 1, 0},
+/* 13 */ { 3, s_4_13, 12, 2, 0},
+/* 14 */ { 3, s_4_14, 12, 2, 0},
+/* 15 */ { 1, s_4_15, -1, 1, 0},
+/* 16 */ { 2, s_4_16, 15, 2, 0},
+/* 17 */ { 2, s_4_17, 15, 2, 0},
+/* 18 */ { 1, s_4_18, -1, 1, 0},
+/* 19 */ { 2, s_4_19, 18, 2, 0},
+/* 20 */ { 2, s_4_20, 18, 2, 0},
+/* 21 */ { 2, s_4_21, -1, 1, 0},
+/* 22 */ { 2, s_4_22, -1, 2, 0},
+/* 23 */ { 2, s_4_23, -1, 2, 0},
+/* 24 */ { 1, s_4_24, -1, 1, 0},
+/* 25 */ { 2, s_4_25, 24, 2, 0},
+/* 26 */ { 2, s_4_26, -1, 1, 0},
+/* 27 */ { 3, s_4_27, 26, 2, 0},
+/* 28 */ { 3, s_4_28, 26, 2, 0},
+/* 29 */ { 2, s_4_29, -1, 1, 0},
+/* 30 */ { 3, s_4_30, 29, 2, 0},
+/* 31 */ { 3, s_4_31, 29, 1, 0},
+/* 32 */ { 2, s_4_32, -1, 1, 0},
+/* 33 */ { 3, s_4_33, 32, 2, 0},
+/* 34 */ { 2, s_4_34, -1, 1, 0},
+/* 35 */ { 3, s_4_35, 34, 2, 0},
+/* 36 */ { 2, s_4_36, -1, 2, 0},
+/* 37 */ { 2, s_4_37, -1, 2, 0},
+/* 38 */ { 2, s_4_38, -1, 2, 0},
+/* 39 */ { 2, s_4_39, -1, 1, 0},
+/* 40 */ { 3, s_4_40, 39, 2, 0},
+/* 41 */ { 3, s_4_41, 39, 2, 0},
+/* 42 */ { 3, s_4_42, -1, 1, 0},
+/* 43 */ { 3, s_4_43, -1, 2, 0},
+/* 44 */ { 2, s_4_44, -1, 1, 0},
+/* 45 */ { 3, s_4_45, 44, 2, 0}
+};
+
+static const symbol s_5_0[1] = { 0xC0 };
+static const symbol s_5_1[2] = { 0xC9, 0xC0 };
+static const symbol s_5_2[2] = { 0xD8, 0xC0 };
+static const symbol s_5_3[1] = { 0xC1 };
+static const symbol s_5_4[1] = { 0xC5 };
+static const symbol s_5_5[2] = { 0xC9, 0xC5 };
+static const symbol s_5_6[2] = { 0xD8, 0xC5 };
+static const symbol s_5_7[2] = { 0xC1, 0xC8 };
+static const symbol s_5_8[2] = { 0xD1, 0xC8 };
+static const symbol s_5_9[3] = { 0xC9, 0xD1, 0xC8 };
+static const symbol s_5_10[1] = { 0xC9 };
+static const symbol s_5_11[2] = { 0xC5, 0xC9 };
+static const symbol s_5_12[2] = { 0xC9, 0xC9 };
+static const symbol s_5_13[3] = { 0xC1, 0xCD, 0xC9 };
+static const symbol s_5_14[3] = { 0xD1, 0xCD, 0xC9 };
+static const symbol s_5_15[4] = { 0xC9, 0xD1, 0xCD, 0xC9 };
+static const symbol s_5_16[1] = { 0xCA };
+static const symbol s_5_17[2] = { 0xC5, 0xCA };
+static const symbol s_5_18[3] = { 0xC9, 0xC5, 0xCA };
+static const symbol s_5_19[2] = { 0xC9, 0xCA };
+static const symbol s_5_20[2] = { 0xCF, 0xCA };
+static const symbol s_5_21[2] = { 0xC1, 0xCD };
+static const symbol s_5_22[2] = { 0xC5, 0xCD };
+static const symbol s_5_23[3] = { 0xC9, 0xC5, 0xCD };
+static const symbol s_5_24[2] = { 0xCF, 0xCD };
+static const symbol s_5_25[2] = { 0xD1, 0xCD };
+static const symbol s_5_26[3] = { 0xC9, 0xD1, 0xCD };
+static const symbol s_5_27[1] = { 0xCF };
+static const symbol s_5_28[1] = { 0xD1 };
+static const symbol s_5_29[2] = { 0xC9, 0xD1 };
+static const symbol s_5_30[2] = { 0xD8, 0xD1 };
+static const symbol s_5_31[1] = { 0xD5 };
+static const symbol s_5_32[2] = { 0xC5, 0xD7 };
+static const symbol s_5_33[2] = { 0xCF, 0xD7 };
+static const symbol s_5_34[1] = { 0xD8 };
+static const symbol s_5_35[1] = { 0xD9 };
+
+static const struct among a_5[36] =
+{
+/* 0 */ { 1, s_5_0, -1, 1, 0},
+/* 1 */ { 2, s_5_1, 0, 1, 0},
+/* 2 */ { 2, s_5_2, 0, 1, 0},
+/* 3 */ { 1, s_5_3, -1, 1, 0},
+/* 4 */ { 1, s_5_4, -1, 1, 0},
+/* 5 */ { 2, s_5_5, 4, 1, 0},
+/* 6 */ { 2, s_5_6, 4, 1, 0},
+/* 7 */ { 2, s_5_7, -1, 1, 0},
+/* 8 */ { 2, s_5_8, -1, 1, 0},
+/* 9 */ { 3, s_5_9, 8, 1, 0},
+/* 10 */ { 1, s_5_10, -1, 1, 0},
+/* 11 */ { 2, s_5_11, 10, 1, 0},
+/* 12 */ { 2, s_5_12, 10, 1, 0},
+/* 13 */ { 3, s_5_13, 10, 1, 0},
+/* 14 */ { 3, s_5_14, 10, 1, 0},
+/* 15 */ { 4, s_5_15, 14, 1, 0},
+/* 16 */ { 1, s_5_16, -1, 1, 0},
+/* 17 */ { 2, s_5_17, 16, 1, 0},
+/* 18 */ { 3, s_5_18, 17, 1, 0},
+/* 19 */ { 2, s_5_19, 16, 1, 0},
+/* 20 */ { 2, s_5_20, 16, 1, 0},
+/* 21 */ { 2, s_5_21, -1, 1, 0},
+/* 22 */ { 2, s_5_22, -1, 1, 0},
+/* 23 */ { 3, s_5_23, 22, 1, 0},
+/* 24 */ { 2, s_5_24, -1, 1, 0},
+/* 25 */ { 2, s_5_25, -1, 1, 0},
+/* 26 */ { 3, s_5_26, 25, 1, 0},
+/* 27 */ { 1, s_5_27, -1, 1, 0},
+/* 28 */ { 1, s_5_28, -1, 1, 0},
+/* 29 */ { 2, s_5_29, 28, 1, 0},
+/* 30 */ { 2, s_5_30, 28, 1, 0},
+/* 31 */ { 1, s_5_31, -1, 1, 0},
+/* 32 */ { 2, s_5_32, -1, 1, 0},
+/* 33 */ { 2, s_5_33, -1, 1, 0},
+/* 34 */ { 1, s_5_34, -1, 1, 0},
+/* 35 */ { 1, s_5_35, -1, 1, 0}
+};
+
+static const symbol s_6_0[3] = { 0xCF, 0xD3, 0xD4 };
+static const symbol s_6_1[4] = { 0xCF, 0xD3, 0xD4, 0xD8 };
+
+static const struct among a_6[2] =
+{
+/* 0 */ { 3, s_6_0, -1, 1, 0},
+/* 1 */ { 4, s_6_1, -1, 1, 0}
+};
+
+static const symbol s_7_0[4] = { 0xC5, 0xCA, 0xDB, 0xC5 };
+static const symbol s_7_1[1] = { 0xCE };
+static const symbol s_7_2[1] = { 0xD8 };
+static const symbol s_7_3[3] = { 0xC5, 0xCA, 0xDB };
+
+static const struct among a_7[4] =
+{
+/* 0 */ { 4, s_7_0, -1, 1, 0},
+/* 1 */ { 1, s_7_1, -1, 2, 0},
+/* 2 */ { 1, s_7_2, -1, 3, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 35, 130, 34, 18 };
+
+static const symbol s_0[] = { 0xC1 };
+static const symbol s_1[] = { 0xD1 };
+static const symbol s_2[] = { 0xC1 };
+static const symbol s_3[] = { 0xD1 };
+static const symbol s_4[] = { 0xC1 };
+static const symbol s_5[] = { 0xD1 };
+static const symbol s_6[] = { 0xCE };
+static const symbol s_7[] = { 0xCE };
+static const symbol s_8[] = { 0xCE };
+static const symbol s_9[] = { 0xC9 };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { int c1 = z->c; /* do, line 63 */
+ { /* gopast */ /* grouping v, line 64 */
+ int ret = out_grouping(z, g_v, 192, 220, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark pV, line 64 */
+ { /* gopast */ /* non v, line 64 */
+ int ret = in_grouping(z, g_v, 192, 220, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ { /* gopast */ /* grouping v, line 65 */
+ int ret = out_grouping(z, g_v, 192, 220, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 65 */
+ int ret = in_grouping(z, g_v, 192, 220, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 65 */
+ lab0:
+ z->c = c1;
+ }
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_perfective_gerund(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 74 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((25166336 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_0, 9); /* substring, line 74 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 74 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 78 */
+ if (!(eq_s_b(z, 1, s_0))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_1))) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 85 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_adjective(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 90 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((2271009 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_1, 26); /* substring, line 90 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 90 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 99 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_adjectival(struct SN_env * z) {
+ int among_var;
+ { int ret = r_adjective(z);
+ if (ret == 0) return 0; /* call adjective, line 104 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */
+ z->ket = z->c; /* [, line 112 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((671113216 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab0; }
+ among_var = find_among_b(z, a_2, 8); /* substring, line 112 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 112 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab0; }
+ case 1:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 117 */
+ if (!(eq_s_b(z, 1, s_2))) goto lab2;
+ goto lab1;
+ lab2:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_3))) { z->c = z->l - m_keep; goto lab0; }
+ }
+ lab1:
+ { int ret = slice_del(z); /* delete, line 117 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 124 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ ;
+ }
+ return 1;
+}
+
+static int r_reflexive(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 131 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 209 && z->p[z->c - 1] != 216)) return 0;
+ among_var = find_among_b(z, a_3, 2); /* substring, line 131 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 131 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_verb(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 139 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((51443235 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_4, 46); /* substring, line 139 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 139 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 145 */
+ if (!(eq_s_b(z, 1, s_4))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_5))) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 145 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 153 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_noun(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 162 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((60991267 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_5, 36); /* substring, line 162 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 162 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 169 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_derivational(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 178 */
+ if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 212 && z->p[z->c - 1] != 216)) return 0;
+ among_var = find_among_b(z, a_6, 2); /* substring, line 178 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 178 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 178 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 181 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_tidy_up(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 186 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((151011360 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_7, 4); /* substring, line 186 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 186 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 190 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 191 */
+ if (!(eq_s_b(z, 1, s_6))) return 0;
+ z->bra = z->c; /* ], line 191 */
+ if (!(eq_s_b(z, 1, s_7))) return 0;
+ { int ret = slice_del(z); /* delete, line 191 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (!(eq_s_b(z, 1, s_8))) return 0;
+ { int ret = slice_del(z); /* delete, line 194 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 196 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int russian_KOI8_R_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 203 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 203 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 204 */
+
+ { int mlimit; /* setlimit, line 204 */
+ int m2 = z->l - z->c; (void)m2;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 204 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m2;
+ { int m3 = z->l - z->c; (void)m3; /* do, line 205 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 206 */
+ { int ret = r_perfective_gerund(z);
+ if (ret == 0) goto lab3; /* call perfective_gerund, line 206 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab3:
+ z->c = z->l - m4;
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 207 */
+ { int ret = r_reflexive(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call reflexive, line 207 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ ;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* or, line 208 */
+ { int ret = r_adjectival(z);
+ if (ret == 0) goto lab6; /* call adjectival, line 208 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m5;
+ { int ret = r_verb(z);
+ if (ret == 0) goto lab7; /* call verb, line 208 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab7:
+ z->c = z->l - m5;
+ { int ret = r_noun(z);
+ if (ret == 0) goto lab1; /* call noun, line 208 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ ;
+ }
+ lab2:
+ lab1:
+ z->c = z->l - m3;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 211 */
+ z->ket = z->c; /* [, line 211 */
+ if (!(eq_s_b(z, 1, s_9))) { z->c = z->l - m_keep; goto lab8; }
+ z->bra = z->c; /* ], line 211 */
+ { int ret = slice_del(z); /* delete, line 211 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ ;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* do, line 214 */
+ { int ret = r_derivational(z);
+ if (ret == 0) goto lab9; /* call derivational, line 214 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m6;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 215 */
+ { int ret = r_tidy_up(z);
+ if (ret == 0) goto lab10; /* call tidy_up, line 215 */
+ if (ret < 0) return ret;
+ }
+ lab10:
+ z->c = z->l - m7;
+ }
+ z->lb = mlimit;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * russian_KOI8_R_create_env(void) { return SN_create_env(0, 2, 0); }
+
+extern void russian_KOI8_R_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_danish.c b/src/backend/snowball/libstemmer/stem_UTF_8_danish.c
new file mode 100644
index 00000000000..cfd41376da2
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_danish.c
@@ -0,0 +1,339 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int danish_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_undouble(struct SN_env * z);
+static int r_other_suffix(struct SN_env * z);
+static int r_consonant_pair(struct SN_env * z);
+static int r_main_suffix(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * danish_UTF_8_create_env(void);
+extern void danish_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[3] = { 'h', 'e', 'd' };
+static const symbol s_0_1[5] = { 'e', 't', 'h', 'e', 'd' };
+static const symbol s_0_2[4] = { 'e', 'r', 'e', 'd' };
+static const symbol s_0_3[1] = { 'e' };
+static const symbol s_0_4[5] = { 'e', 'r', 'e', 'd', 'e' };
+static const symbol s_0_5[4] = { 'e', 'n', 'd', 'e' };
+static const symbol s_0_6[6] = { 'e', 'r', 'e', 'n', 'd', 'e' };
+static const symbol s_0_7[3] = { 'e', 'n', 'e' };
+static const symbol s_0_8[4] = { 'e', 'r', 'n', 'e' };
+static const symbol s_0_9[3] = { 'e', 'r', 'e' };
+static const symbol s_0_10[2] = { 'e', 'n' };
+static const symbol s_0_11[5] = { 'h', 'e', 'd', 'e', 'n' };
+static const symbol s_0_12[4] = { 'e', 'r', 'e', 'n' };
+static const symbol s_0_13[2] = { 'e', 'r' };
+static const symbol s_0_14[5] = { 'h', 'e', 'd', 'e', 'r' };
+static const symbol s_0_15[4] = { 'e', 'r', 'e', 'r' };
+static const symbol s_0_16[1] = { 's' };
+static const symbol s_0_17[4] = { 'h', 'e', 'd', 's' };
+static const symbol s_0_18[2] = { 'e', 's' };
+static const symbol s_0_19[5] = { 'e', 'n', 'd', 'e', 's' };
+static const symbol s_0_20[7] = { 'e', 'r', 'e', 'n', 'd', 'e', 's' };
+static const symbol s_0_21[4] = { 'e', 'n', 'e', 's' };
+static const symbol s_0_22[5] = { 'e', 'r', 'n', 'e', 's' };
+static const symbol s_0_23[4] = { 'e', 'r', 'e', 's' };
+static const symbol s_0_24[3] = { 'e', 'n', 's' };
+static const symbol s_0_25[6] = { 'h', 'e', 'd', 'e', 'n', 's' };
+static const symbol s_0_26[5] = { 'e', 'r', 'e', 'n', 's' };
+static const symbol s_0_27[3] = { 'e', 'r', 's' };
+static const symbol s_0_28[3] = { 'e', 't', 's' };
+static const symbol s_0_29[5] = { 'e', 'r', 'e', 't', 's' };
+static const symbol s_0_30[2] = { 'e', 't' };
+static const symbol s_0_31[4] = { 'e', 'r', 'e', 't' };
+
+static const struct among a_0[32] =
+{
+/* 0 */ { 3, s_0_0, -1, 1, 0},
+/* 1 */ { 5, s_0_1, 0, 1, 0},
+/* 2 */ { 4, s_0_2, -1, 1, 0},
+/* 3 */ { 1, s_0_3, -1, 1, 0},
+/* 4 */ { 5, s_0_4, 3, 1, 0},
+/* 5 */ { 4, s_0_5, 3, 1, 0},
+/* 6 */ { 6, s_0_6, 5, 1, 0},
+/* 7 */ { 3, s_0_7, 3, 1, 0},
+/* 8 */ { 4, s_0_8, 3, 1, 0},
+/* 9 */ { 3, s_0_9, 3, 1, 0},
+/* 10 */ { 2, s_0_10, -1, 1, 0},
+/* 11 */ { 5, s_0_11, 10, 1, 0},
+/* 12 */ { 4, s_0_12, 10, 1, 0},
+/* 13 */ { 2, s_0_13, -1, 1, 0},
+/* 14 */ { 5, s_0_14, 13, 1, 0},
+/* 15 */ { 4, s_0_15, 13, 1, 0},
+/* 16 */ { 1, s_0_16, -1, 2, 0},
+/* 17 */ { 4, s_0_17, 16, 1, 0},
+/* 18 */ { 2, s_0_18, 16, 1, 0},
+/* 19 */ { 5, s_0_19, 18, 1, 0},
+/* 20 */ { 7, s_0_20, 19, 1, 0},
+/* 21 */ { 4, s_0_21, 18, 1, 0},
+/* 22 */ { 5, s_0_22, 18, 1, 0},
+/* 23 */ { 4, s_0_23, 18, 1, 0},
+/* 24 */ { 3, s_0_24, 16, 1, 0},
+/* 25 */ { 6, s_0_25, 24, 1, 0},
+/* 26 */ { 5, s_0_26, 24, 1, 0},
+/* 27 */ { 3, s_0_27, 16, 1, 0},
+/* 28 */ { 3, s_0_28, 16, 1, 0},
+/* 29 */ { 5, s_0_29, 28, 1, 0},
+/* 30 */ { 2, s_0_30, -1, 1, 0},
+/* 31 */ { 4, s_0_31, 30, 1, 0}
+};
+
+static const symbol s_1_0[2] = { 'g', 'd' };
+static const symbol s_1_1[2] = { 'd', 't' };
+static const symbol s_1_2[2] = { 'g', 't' };
+static const symbol s_1_3[2] = { 'k', 't' };
+
+static const struct among a_1[4] =
+{
+/* 0 */ { 2, s_1_0, -1, -1, 0},
+/* 1 */ { 2, s_1_1, -1, -1, 0},
+/* 2 */ { 2, s_1_2, -1, -1, 0},
+/* 3 */ { 2, s_1_3, -1, -1, 0}
+};
+
+static const symbol s_2_0[2] = { 'i', 'g' };
+static const symbol s_2_1[3] = { 'l', 'i', 'g' };
+static const symbol s_2_2[4] = { 'e', 'l', 'i', 'g' };
+static const symbol s_2_3[3] = { 'e', 'l', 's' };
+static const symbol s_2_4[5] = { 'l', 0xC3, 0xB8, 's', 't' };
+
+static const struct among a_2[5] =
+{
+/* 0 */ { 2, s_2_0, -1, 1, 0},
+/* 1 */ { 3, s_2_1, 0, 1, 0},
+/* 2 */ { 4, s_2_2, 1, 1, 0},
+/* 3 */ { 3, s_2_3, -1, 1, 0},
+/* 4 */ { 5, s_2_4, -1, 2, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 };
+
+static const unsigned char g_s_ending[] = { 239, 254, 42, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 };
+
+static const symbol s_0[] = { 's', 't' };
+static const symbol s_1[] = { 'i', 'g' };
+static const symbol s_2[] = { 'l', 0xC3, 0xB8, 's' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ { int c_test = z->c; /* test, line 33 */
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3);
+ if (ret < 0) return 0;
+ z->c = ret; /* hop, line 33 */
+ }
+ z->I[1] = z->c; /* setmark x, line 33 */
+ z->c = c_test;
+ }
+ if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 34 */
+ { /* gopast */ /* non v, line 34 */
+ int ret = in_grouping_U(z, g_v, 97, 248, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 34 */
+ /* try, line 35 */
+ if (!(z->I[0] < z->I[1])) goto lab0;
+ z->I[0] = z->I[1];
+lab0:
+ return 1;
+}
+
+static int r_main_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 41 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 41 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 41 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_0, 32); /* substring, line 41 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 41 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 48 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (in_grouping_b_U(z, g_s_ending, 97, 229, 0)) return 0;
+ { int ret = slice_del(z); /* delete, line 50 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_consonant_pair(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 55 */
+ { int mlimit; /* setlimit, line 56 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 56 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 56 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit; return 0; }
+ if (!(find_among_b(z, a_1, 4))) { z->lb = mlimit; return 0; } /* substring, line 56 */
+ z->bra = z->c; /* ], line 56 */
+ z->lb = mlimit;
+ }
+ z->c = z->l - m_test;
+ }
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 62 */
+ }
+ z->bra = z->c; /* ], line 62 */
+ { int ret = slice_del(z); /* delete, line 62 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_other_suffix(struct SN_env * z) {
+ int among_var;
+ { int m1 = z->l - z->c; (void)m1; /* do, line 66 */
+ z->ket = z->c; /* [, line 66 */
+ if (!(eq_s_b(z, 2, s_0))) goto lab0;
+ z->bra = z->c; /* ], line 66 */
+ if (!(eq_s_b(z, 2, s_1))) goto lab0;
+ { int ret = slice_del(z); /* delete, line 66 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = z->l - m1;
+ }
+ { int mlimit; /* setlimit, line 67 */
+ int m2 = z->l - z->c; (void)m2;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 67 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m2;
+ z->ket = z->c; /* [, line 67 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_2, 5); /* substring, line 67 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 67 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 70 */
+ if (ret < 0) return ret;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 70 */
+ { int ret = r_consonant_pair(z);
+ if (ret == 0) goto lab1; /* call consonant_pair, line 70 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m3;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 4, s_2); /* <-, line 72 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_undouble(struct SN_env * z) {
+ { int mlimit; /* setlimit, line 76 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 76 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 76 */
+ if (out_grouping_b_U(z, g_v, 97, 248, 0)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 76 */
+ z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 76 */
+ if (z->S[0] == 0) return -1; /* -> ch, line 76 */
+ z->lb = mlimit;
+ }
+ if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 77 */
+ { int ret = slice_del(z); /* delete, line 78 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern int danish_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 84 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 84 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 85 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 86 */
+ { int ret = r_main_suffix(z);
+ if (ret == 0) goto lab1; /* call main_suffix, line 86 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 87 */
+ { int ret = r_consonant_pair(z);
+ if (ret == 0) goto lab2; /* call consonant_pair, line 87 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 88 */
+ { int ret = r_other_suffix(z);
+ if (ret == 0) goto lab3; /* call other_suffix, line 88 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 89 */
+ { int ret = r_undouble(z);
+ if (ret == 0) goto lab4; /* call undouble, line 89 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ z->c = z->l - m5;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * danish_UTF_8_create_env(void) { return SN_create_env(1, 2, 0); }
+
+extern void danish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 1); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c b/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c
new file mode 100644
index 00000000000..f04c88d3e6a
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c
@@ -0,0 +1,634 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int dutch_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_standard_suffix(struct SN_env * z);
+static int r_undouble(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_en_ending(struct SN_env * z);
+static int r_e_ending(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * dutch_UTF_8_create_env(void);
+extern void dutch_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[2] = { 0xC3, 0xA1 };
+static const symbol s_0_2[2] = { 0xC3, 0xA4 };
+static const symbol s_0_3[2] = { 0xC3, 0xA9 };
+static const symbol s_0_4[2] = { 0xC3, 0xAB };
+static const symbol s_0_5[2] = { 0xC3, 0xAD };
+static const symbol s_0_6[2] = { 0xC3, 0xAF };
+static const symbol s_0_7[2] = { 0xC3, 0xB3 };
+static const symbol s_0_8[2] = { 0xC3, 0xB6 };
+static const symbol s_0_9[2] = { 0xC3, 0xBA };
+static const symbol s_0_10[2] = { 0xC3, 0xBC };
+
+static const struct among a_0[11] =
+{
+/* 0 */ { 0, 0, -1, 6, 0},
+/* 1 */ { 2, s_0_1, 0, 1, 0},
+/* 2 */ { 2, s_0_2, 0, 1, 0},
+/* 3 */ { 2, s_0_3, 0, 2, 0},
+/* 4 */ { 2, s_0_4, 0, 2, 0},
+/* 5 */ { 2, s_0_5, 0, 3, 0},
+/* 6 */ { 2, s_0_6, 0, 3, 0},
+/* 7 */ { 2, s_0_7, 0, 4, 0},
+/* 8 */ { 2, s_0_8, 0, 4, 0},
+/* 9 */ { 2, s_0_9, 0, 5, 0},
+/* 10 */ { 2, s_0_10, 0, 5, 0}
+};
+
+static const symbol s_1_1[1] = { 'I' };
+static const symbol s_1_2[1] = { 'Y' };
+
+static const struct among a_1[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 1, s_1_1, 0, 2, 0},
+/* 2 */ { 1, s_1_2, 0, 1, 0}
+};
+
+static const symbol s_2_0[2] = { 'd', 'd' };
+static const symbol s_2_1[2] = { 'k', 'k' };
+static const symbol s_2_2[2] = { 't', 't' };
+
+static const struct among a_2[3] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 2, s_2_1, -1, -1, 0},
+/* 2 */ { 2, s_2_2, -1, -1, 0}
+};
+
+static const symbol s_3_0[3] = { 'e', 'n', 'e' };
+static const symbol s_3_1[2] = { 's', 'e' };
+static const symbol s_3_2[2] = { 'e', 'n' };
+static const symbol s_3_3[5] = { 'h', 'e', 'd', 'e', 'n' };
+static const symbol s_3_4[1] = { 's' };
+
+static const struct among a_3[5] =
+{
+/* 0 */ { 3, s_3_0, -1, 2, 0},
+/* 1 */ { 2, s_3_1, -1, 3, 0},
+/* 2 */ { 2, s_3_2, -1, 2, 0},
+/* 3 */ { 5, s_3_3, 2, 1, 0},
+/* 4 */ { 1, s_3_4, -1, 3, 0}
+};
+
+static const symbol s_4_0[3] = { 'e', 'n', 'd' };
+static const symbol s_4_1[2] = { 'i', 'g' };
+static const symbol s_4_2[3] = { 'i', 'n', 'g' };
+static const symbol s_4_3[4] = { 'l', 'i', 'j', 'k' };
+static const symbol s_4_4[4] = { 'b', 'a', 'a', 'r' };
+static const symbol s_4_5[3] = { 'b', 'a', 'r' };
+
+static const struct among a_4[6] =
+{
+/* 0 */ { 3, s_4_0, -1, 1, 0},
+/* 1 */ { 2, s_4_1, -1, 2, 0},
+/* 2 */ { 3, s_4_2, -1, 1, 0},
+/* 3 */ { 4, s_4_3, -1, 3, 0},
+/* 4 */ { 4, s_4_4, -1, 4, 0},
+/* 5 */ { 3, s_4_5, -1, 5, 0}
+};
+
+static const symbol s_5_0[2] = { 'a', 'a' };
+static const symbol s_5_1[2] = { 'e', 'e' };
+static const symbol s_5_2[2] = { 'o', 'o' };
+static const symbol s_5_3[2] = { 'u', 'u' };
+
+static const struct among a_5[4] =
+{
+/* 0 */ { 2, s_5_0, -1, -1, 0},
+/* 1 */ { 2, s_5_1, -1, -1, 0},
+/* 2 */ { 2, s_5_2, -1, -1, 0},
+/* 3 */ { 2, s_5_3, -1, -1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
+
+static const unsigned char g_v_I[] = { 1, 0, 0, 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
+
+static const unsigned char g_v_j[] = { 17, 67, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
+
+static const symbol s_0[] = { 'a' };
+static const symbol s_1[] = { 'e' };
+static const symbol s_2[] = { 'i' };
+static const symbol s_3[] = { 'o' };
+static const symbol s_4[] = { 'u' };
+static const symbol s_5[] = { 'y' };
+static const symbol s_6[] = { 'Y' };
+static const symbol s_7[] = { 'i' };
+static const symbol s_8[] = { 'I' };
+static const symbol s_9[] = { 'y' };
+static const symbol s_10[] = { 'Y' };
+static const symbol s_11[] = { 'y' };
+static const symbol s_12[] = { 'i' };
+static const symbol s_13[] = { 'e' };
+static const symbol s_14[] = { 'g', 'e', 'm' };
+static const symbol s_15[] = { 'h', 'e', 'i', 'd' };
+static const symbol s_16[] = { 'h', 'e', 'i', 'd' };
+static const symbol s_17[] = { 'c' };
+static const symbol s_18[] = { 'e', 'n' };
+static const symbol s_19[] = { 'i', 'g' };
+static const symbol s_20[] = { 'e' };
+static const symbol s_21[] = { 'e' };
+
+static int r_prelude(struct SN_env * z) {
+ int among_var;
+ { int c_test = z->c; /* test, line 42 */
+ while(1) { /* repeat, line 42 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 43 */
+ if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((340306450 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else
+ among_var = find_among(z, a_0, 11); /* substring, line 43 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 43 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_0); /* <-, line 45 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 47 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 49 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 51 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 53 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 54 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ z->c = c_test;
+ }
+ { int c_keep = z->c; /* try, line 57 */
+ z->bra = z->c; /* [, line 57 */
+ if (!(eq_s(z, 1, s_5))) { z->c = c_keep; goto lab1; }
+ z->ket = z->c; /* ], line 57 */
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 57 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ ;
+ }
+ while(1) { /* repeat, line 58 */
+ int c2 = z->c;
+ while(1) { /* goto, line 58 */
+ int c3 = z->c;
+ if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab3;
+ z->bra = z->c; /* [, line 59 */
+ { int c4 = z->c; /* or, line 59 */
+ if (!(eq_s(z, 1, s_7))) goto lab5;
+ z->ket = z->c; /* ], line 59 */
+ if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab5;
+ { int ret = slice_from_s(z, 1, s_8); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab5:
+ z->c = c4;
+ if (!(eq_s(z, 1, s_9))) goto lab3;
+ z->ket = z->c; /* ], line 60 */
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 60 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab4:
+ z->c = c3;
+ break;
+ lab3:
+ z->c = c3;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab2;
+ z->c = ret; /* goto, line 58 */
+ }
+ }
+ continue;
+ lab2:
+ z->c = c2;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { /* gopast */ /* grouping v, line 69 */
+ int ret = out_grouping_U(z, g_v, 97, 232, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 69 */
+ int ret = in_grouping_U(z, g_v, 97, 232, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 69 */
+ /* try, line 70 */
+ if (!(z->I[0] < 3)) goto lab0;
+ z->I[0] = 3;
+lab0:
+ { /* gopast */ /* grouping v, line 71 */
+ int ret = out_grouping_U(z, g_v, 97, 232, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 71 */
+ int ret = in_grouping_U(z, g_v, 97, 232, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 71 */
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 75 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 77 */
+ if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else
+ among_var = find_among(z, a_1, 3); /* substring, line 77 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 77 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_11); /* <-, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_12); /* <-, line 79 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 80 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_undouble(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 91 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_2, 3))) return 0; /* among, line 91 */
+ z->c = z->l - m_test;
+ }
+ z->ket = z->c; /* [, line 91 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 91 */
+ }
+ z->bra = z->c; /* ], line 91 */
+ { int ret = slice_del(z); /* delete, line 91 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_e_ending(struct SN_env * z) {
+ z->B[0] = 0; /* unset e_found, line 95 */
+ z->ket = z->c; /* [, line 96 */
+ if (!(eq_s_b(z, 1, s_13))) return 0;
+ z->bra = z->c; /* ], line 96 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 96 */
+ if (ret < 0) return ret;
+ }
+ { int m_test = z->l - z->c; /* test, line 96 */
+ if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0;
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 96 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set e_found, line 97 */
+ { int ret = r_undouble(z);
+ if (ret == 0) return 0; /* call undouble, line 98 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_en_ending(struct SN_env * z) {
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int m1 = z->l - z->c; (void)m1; /* and, line 102 */
+ if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0;
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* not, line 102 */
+ if (!(eq_s_b(z, 3, s_14))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m2;
+ }
+ }
+ { int ret = slice_del(z); /* delete, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_undouble(z);
+ if (ret == 0) return 0; /* call undouble, line 103 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ { int m1 = z->l - z->c; (void)m1; /* do, line 107 */
+ z->ket = z->c; /* [, line 108 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0;
+ among_var = find_among_b(z, a_3, 5); /* substring, line 108 */
+ if (!(among_var)) goto lab0;
+ z->bra = z->c; /* ], line 108 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = r_R1(z);
+ if (ret == 0) goto lab0; /* call R1, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 4, s_15); /* <-, line 110 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_en_ending(z);
+ if (ret == 0) goto lab0; /* call en_ending, line 113 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = r_R1(z);
+ if (ret == 0) goto lab0; /* call R1, line 116 */
+ if (ret < 0) return ret;
+ }
+ if (out_grouping_b_U(z, g_v_j, 97, 232, 0)) goto lab0;
+ { int ret = slice_del(z); /* delete, line 116 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ z->c = z->l - m1;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* do, line 120 */
+ { int ret = r_e_ending(z);
+ if (ret == 0) goto lab1; /* call e_ending, line 120 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 122 */
+ z->ket = z->c; /* [, line 122 */
+ if (!(eq_s_b(z, 4, s_16))) goto lab2;
+ z->bra = z->c; /* ], line 122 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab2; /* call R2, line 122 */
+ if (ret < 0) return ret;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* not, line 122 */
+ if (!(eq_s_b(z, 1, s_17))) goto lab3;
+ goto lab2;
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int ret = slice_del(z); /* delete, line 122 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 123 */
+ if (!(eq_s_b(z, 2, s_18))) goto lab2;
+ z->bra = z->c; /* ], line 123 */
+ { int ret = r_en_ending(z);
+ if (ret == 0) goto lab2; /* call en_ending, line 123 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 126 */
+ z->ket = z->c; /* [, line 127 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab4;
+ among_var = find_among_b(z, a_4, 6); /* substring, line 127 */
+ if (!(among_var)) goto lab4;
+ z->bra = z->c; /* ], line 127 */
+ switch(among_var) {
+ case 0: goto lab4;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 129 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 129 */
+ if (ret < 0) return ret;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* or, line 130 */
+ z->ket = z->c; /* [, line 130 */
+ if (!(eq_s_b(z, 2, s_19))) goto lab6;
+ z->bra = z->c; /* ], line 130 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab6; /* call R2, line 130 */
+ if (ret < 0) return ret;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* not, line 130 */
+ if (!(eq_s_b(z, 1, s_20))) goto lab7;
+ goto lab6;
+ lab7:
+ z->c = z->l - m7;
+ }
+ { int ret = slice_del(z); /* delete, line 130 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int ret = r_undouble(z);
+ if (ret == 0) goto lab4; /* call undouble, line 130 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 133 */
+ if (ret < 0) return ret;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* not, line 133 */
+ if (!(eq_s_b(z, 1, s_21))) goto lab8;
+ goto lab4;
+ lab8:
+ z->c = z->l - m8;
+ }
+ { int ret = slice_del(z); /* delete, line 133 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 136 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 136 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_e_ending(z);
+ if (ret == 0) goto lab4; /* call e_ending, line 136 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 139 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 139 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab4; /* call R2, line 142 */
+ if (ret < 0) return ret;
+ }
+ if (!(z->B[0])) goto lab4; /* Boolean test e_found, line 142 */
+ { int ret = slice_del(z); /* delete, line 142 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab4:
+ z->c = z->l - m5;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 146 */
+ if (out_grouping_b_U(z, g_v_I, 73, 232, 0)) goto lab9;
+ { int m_test = z->l - z->c; /* test, line 148 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab9;
+ if (!(find_among_b(z, a_5, 4))) goto lab9; /* among, line 149 */
+ if (out_grouping_b_U(z, g_v, 97, 232, 0)) goto lab9;
+ z->c = z->l - m_test;
+ }
+ z->ket = z->c; /* [, line 152 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) goto lab9;
+ z->c = ret; /* next, line 152 */
+ }
+ z->bra = z->c; /* ], line 152 */
+ { int ret = slice_del(z); /* delete, line 152 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m9;
+ }
+ return 1;
+}
+
+extern int dutch_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 159 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 159 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 160 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 160 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 161 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 162 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab2; /* call standard_suffix, line 162 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ z->c = z->lb;
+ { int c4 = z->c; /* do, line 163 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab3; /* call postlude, line 163 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = c4;
+ }
+ return 1;
+}
+
+extern struct SN_env * dutch_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); }
+
+extern void dutch_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_english.c b/src/backend/snowball/libstemmer/stem_UTF_8_english.c
new file mode 100644
index 00000000000..c5d4c2a445d
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_english.c
@@ -0,0 +1,1125 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int english_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_exception2(struct SN_env * z);
+static int r_exception1(struct SN_env * z);
+static int r_Step_5(struct SN_env * z);
+static int r_Step_4(struct SN_env * z);
+static int r_Step_3(struct SN_env * z);
+static int r_Step_2(struct SN_env * z);
+static int r_Step_1c(struct SN_env * z);
+static int r_Step_1b(struct SN_env * z);
+static int r_Step_1a(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_shortv(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * english_UTF_8_create_env(void);
+extern void english_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[5] = { 'a', 'r', 's', 'e', 'n' };
+static const symbol s_0_1[6] = { 'c', 'o', 'm', 'm', 'u', 'n' };
+static const symbol s_0_2[5] = { 'g', 'e', 'n', 'e', 'r' };
+
+static const struct among a_0[3] =
+{
+/* 0 */ { 5, s_0_0, -1, -1, 0},
+/* 1 */ { 6, s_0_1, -1, -1, 0},
+/* 2 */ { 5, s_0_2, -1, -1, 0}
+};
+
+static const symbol s_1_0[1] = { '\'' };
+static const symbol s_1_1[3] = { '\'', 's', '\'' };
+static const symbol s_1_2[2] = { '\'', 's' };
+
+static const struct among a_1[3] =
+{
+/* 0 */ { 1, s_1_0, -1, 1, 0},
+/* 1 */ { 3, s_1_1, 0, 1, 0},
+/* 2 */ { 2, s_1_2, -1, 1, 0}
+};
+
+static const symbol s_2_0[3] = { 'i', 'e', 'd' };
+static const symbol s_2_1[1] = { 's' };
+static const symbol s_2_2[3] = { 'i', 'e', 's' };
+static const symbol s_2_3[4] = { 's', 's', 'e', 's' };
+static const symbol s_2_4[2] = { 's', 's' };
+static const symbol s_2_5[2] = { 'u', 's' };
+
+static const struct among a_2[6] =
+{
+/* 0 */ { 3, s_2_0, -1, 2, 0},
+/* 1 */ { 1, s_2_1, -1, 3, 0},
+/* 2 */ { 3, s_2_2, 1, 2, 0},
+/* 3 */ { 4, s_2_3, 1, 1, 0},
+/* 4 */ { 2, s_2_4, 1, -1, 0},
+/* 5 */ { 2, s_2_5, 1, -1, 0}
+};
+
+static const symbol s_3_1[2] = { 'b', 'b' };
+static const symbol s_3_2[2] = { 'd', 'd' };
+static const symbol s_3_3[2] = { 'f', 'f' };
+static const symbol s_3_4[2] = { 'g', 'g' };
+static const symbol s_3_5[2] = { 'b', 'l' };
+static const symbol s_3_6[2] = { 'm', 'm' };
+static const symbol s_3_7[2] = { 'n', 'n' };
+static const symbol s_3_8[2] = { 'p', 'p' };
+static const symbol s_3_9[2] = { 'r', 'r' };
+static const symbol s_3_10[2] = { 'a', 't' };
+static const symbol s_3_11[2] = { 't', 't' };
+static const symbol s_3_12[2] = { 'i', 'z' };
+
+static const struct among a_3[13] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 2, s_3_1, 0, 2, 0},
+/* 2 */ { 2, s_3_2, 0, 2, 0},
+/* 3 */ { 2, s_3_3, 0, 2, 0},
+/* 4 */ { 2, s_3_4, 0, 2, 0},
+/* 5 */ { 2, s_3_5, 0, 1, 0},
+/* 6 */ { 2, s_3_6, 0, 2, 0},
+/* 7 */ { 2, s_3_7, 0, 2, 0},
+/* 8 */ { 2, s_3_8, 0, 2, 0},
+/* 9 */ { 2, s_3_9, 0, 2, 0},
+/* 10 */ { 2, s_3_10, 0, 1, 0},
+/* 11 */ { 2, s_3_11, 0, 2, 0},
+/* 12 */ { 2, s_3_12, 0, 1, 0}
+};
+
+static const symbol s_4_0[2] = { 'e', 'd' };
+static const symbol s_4_1[3] = { 'e', 'e', 'd' };
+static const symbol s_4_2[3] = { 'i', 'n', 'g' };
+static const symbol s_4_3[4] = { 'e', 'd', 'l', 'y' };
+static const symbol s_4_4[5] = { 'e', 'e', 'd', 'l', 'y' };
+static const symbol s_4_5[5] = { 'i', 'n', 'g', 'l', 'y' };
+
+static const struct among a_4[6] =
+{
+/* 0 */ { 2, s_4_0, -1, 2, 0},
+/* 1 */ { 3, s_4_1, 0, 1, 0},
+/* 2 */ { 3, s_4_2, -1, 2, 0},
+/* 3 */ { 4, s_4_3, -1, 2, 0},
+/* 4 */ { 5, s_4_4, 3, 1, 0},
+/* 5 */ { 5, s_4_5, -1, 2, 0}
+};
+
+static const symbol s_5_0[4] = { 'a', 'n', 'c', 'i' };
+static const symbol s_5_1[4] = { 'e', 'n', 'c', 'i' };
+static const symbol s_5_2[3] = { 'o', 'g', 'i' };
+static const symbol s_5_3[2] = { 'l', 'i' };
+static const symbol s_5_4[3] = { 'b', 'l', 'i' };
+static const symbol s_5_5[4] = { 'a', 'b', 'l', 'i' };
+static const symbol s_5_6[4] = { 'a', 'l', 'l', 'i' };
+static const symbol s_5_7[5] = { 'f', 'u', 'l', 'l', 'i' };
+static const symbol s_5_8[6] = { 'l', 'e', 's', 's', 'l', 'i' };
+static const symbol s_5_9[5] = { 'o', 'u', 's', 'l', 'i' };
+static const symbol s_5_10[5] = { 'e', 'n', 't', 'l', 'i' };
+static const symbol s_5_11[5] = { 'a', 'l', 'i', 't', 'i' };
+static const symbol s_5_12[6] = { 'b', 'i', 'l', 'i', 't', 'i' };
+static const symbol s_5_13[5] = { 'i', 'v', 'i', 't', 'i' };
+static const symbol s_5_14[6] = { 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_5_15[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_5_16[5] = { 'a', 'l', 'i', 's', 'm' };
+static const symbol s_5_17[5] = { 'a', 't', 'i', 'o', 'n' };
+static const symbol s_5_18[7] = { 'i', 'z', 'a', 't', 'i', 'o', 'n' };
+static const symbol s_5_19[4] = { 'i', 'z', 'e', 'r' };
+static const symbol s_5_20[4] = { 'a', 't', 'o', 'r' };
+static const symbol s_5_21[7] = { 'i', 'v', 'e', 'n', 'e', 's', 's' };
+static const symbol s_5_22[7] = { 'f', 'u', 'l', 'n', 'e', 's', 's' };
+static const symbol s_5_23[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' };
+
+static const struct among a_5[24] =
+{
+/* 0 */ { 4, s_5_0, -1, 3, 0},
+/* 1 */ { 4, s_5_1, -1, 2, 0},
+/* 2 */ { 3, s_5_2, -1, 13, 0},
+/* 3 */ { 2, s_5_3, -1, 16, 0},
+/* 4 */ { 3, s_5_4, 3, 12, 0},
+/* 5 */ { 4, s_5_5, 4, 4, 0},
+/* 6 */ { 4, s_5_6, 3, 8, 0},
+/* 7 */ { 5, s_5_7, 3, 14, 0},
+/* 8 */ { 6, s_5_8, 3, 15, 0},
+/* 9 */ { 5, s_5_9, 3, 10, 0},
+/* 10 */ { 5, s_5_10, 3, 5, 0},
+/* 11 */ { 5, s_5_11, -1, 8, 0},
+/* 12 */ { 6, s_5_12, -1, 12, 0},
+/* 13 */ { 5, s_5_13, -1, 11, 0},
+/* 14 */ { 6, s_5_14, -1, 1, 0},
+/* 15 */ { 7, s_5_15, 14, 7, 0},
+/* 16 */ { 5, s_5_16, -1, 8, 0},
+/* 17 */ { 5, s_5_17, -1, 7, 0},
+/* 18 */ { 7, s_5_18, 17, 6, 0},
+/* 19 */ { 4, s_5_19, -1, 6, 0},
+/* 20 */ { 4, s_5_20, -1, 7, 0},
+/* 21 */ { 7, s_5_21, -1, 11, 0},
+/* 22 */ { 7, s_5_22, -1, 9, 0},
+/* 23 */ { 7, s_5_23, -1, 10, 0}
+};
+
+static const symbol s_6_0[5] = { 'i', 'c', 'a', 't', 'e' };
+static const symbol s_6_1[5] = { 'a', 't', 'i', 'v', 'e' };
+static const symbol s_6_2[5] = { 'a', 'l', 'i', 'z', 'e' };
+static const symbol s_6_3[5] = { 'i', 'c', 'i', 't', 'i' };
+static const symbol s_6_4[4] = { 'i', 'c', 'a', 'l' };
+static const symbol s_6_5[6] = { 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_6_6[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_6_7[3] = { 'f', 'u', 'l' };
+static const symbol s_6_8[4] = { 'n', 'e', 's', 's' };
+
+static const struct among a_6[9] =
+{
+/* 0 */ { 5, s_6_0, -1, 4, 0},
+/* 1 */ { 5, s_6_1, -1, 6, 0},
+/* 2 */ { 5, s_6_2, -1, 3, 0},
+/* 3 */ { 5, s_6_3, -1, 4, 0},
+/* 4 */ { 4, s_6_4, -1, 4, 0},
+/* 5 */ { 6, s_6_5, -1, 1, 0},
+/* 6 */ { 7, s_6_6, 5, 2, 0},
+/* 7 */ { 3, s_6_7, -1, 5, 0},
+/* 8 */ { 4, s_6_8, -1, 5, 0}
+};
+
+static const symbol s_7_0[2] = { 'i', 'c' };
+static const symbol s_7_1[4] = { 'a', 'n', 'c', 'e' };
+static const symbol s_7_2[4] = { 'e', 'n', 'c', 'e' };
+static const symbol s_7_3[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_7_4[4] = { 'i', 'b', 'l', 'e' };
+static const symbol s_7_5[3] = { 'a', 't', 'e' };
+static const symbol s_7_6[3] = { 'i', 'v', 'e' };
+static const symbol s_7_7[3] = { 'i', 'z', 'e' };
+static const symbol s_7_8[3] = { 'i', 't', 'i' };
+static const symbol s_7_9[2] = { 'a', 'l' };
+static const symbol s_7_10[3] = { 'i', 's', 'm' };
+static const symbol s_7_11[3] = { 'i', 'o', 'n' };
+static const symbol s_7_12[2] = { 'e', 'r' };
+static const symbol s_7_13[3] = { 'o', 'u', 's' };
+static const symbol s_7_14[3] = { 'a', 'n', 't' };
+static const symbol s_7_15[3] = { 'e', 'n', 't' };
+static const symbol s_7_16[4] = { 'm', 'e', 'n', 't' };
+static const symbol s_7_17[5] = { 'e', 'm', 'e', 'n', 't' };
+
+static const struct among a_7[18] =
+{
+/* 0 */ { 2, s_7_0, -1, 1, 0},
+/* 1 */ { 4, s_7_1, -1, 1, 0},
+/* 2 */ { 4, s_7_2, -1, 1, 0},
+/* 3 */ { 4, s_7_3, -1, 1, 0},
+/* 4 */ { 4, s_7_4, -1, 1, 0},
+/* 5 */ { 3, s_7_5, -1, 1, 0},
+/* 6 */ { 3, s_7_6, -1, 1, 0},
+/* 7 */ { 3, s_7_7, -1, 1, 0},
+/* 8 */ { 3, s_7_8, -1, 1, 0},
+/* 9 */ { 2, s_7_9, -1, 1, 0},
+/* 10 */ { 3, s_7_10, -1, 1, 0},
+/* 11 */ { 3, s_7_11, -1, 2, 0},
+/* 12 */ { 2, s_7_12, -1, 1, 0},
+/* 13 */ { 3, s_7_13, -1, 1, 0},
+/* 14 */ { 3, s_7_14, -1, 1, 0},
+/* 15 */ { 3, s_7_15, -1, 1, 0},
+/* 16 */ { 4, s_7_16, 15, 1, 0},
+/* 17 */ { 5, s_7_17, 16, 1, 0}
+};
+
+static const symbol s_8_0[1] = { 'e' };
+static const symbol s_8_1[1] = { 'l' };
+
+static const struct among a_8[2] =
+{
+/* 0 */ { 1, s_8_0, -1, 1, 0},
+/* 1 */ { 1, s_8_1, -1, 2, 0}
+};
+
+static const symbol s_9_0[7] = { 's', 'u', 'c', 'c', 'e', 'e', 'd' };
+static const symbol s_9_1[7] = { 'p', 'r', 'o', 'c', 'e', 'e', 'd' };
+static const symbol s_9_2[6] = { 'e', 'x', 'c', 'e', 'e', 'd' };
+static const symbol s_9_3[7] = { 'c', 'a', 'n', 'n', 'i', 'n', 'g' };
+static const symbol s_9_4[6] = { 'i', 'n', 'n', 'i', 'n', 'g' };
+static const symbol s_9_5[7] = { 'e', 'a', 'r', 'r', 'i', 'n', 'g' };
+static const symbol s_9_6[7] = { 'h', 'e', 'r', 'r', 'i', 'n', 'g' };
+static const symbol s_9_7[6] = { 'o', 'u', 't', 'i', 'n', 'g' };
+
+static const struct among a_9[8] =
+{
+/* 0 */ { 7, s_9_0, -1, -1, 0},
+/* 1 */ { 7, s_9_1, -1, -1, 0},
+/* 2 */ { 6, s_9_2, -1, -1, 0},
+/* 3 */ { 7, s_9_3, -1, -1, 0},
+/* 4 */ { 6, s_9_4, -1, -1, 0},
+/* 5 */ { 7, s_9_5, -1, -1, 0},
+/* 6 */ { 7, s_9_6, -1, -1, 0},
+/* 7 */ { 6, s_9_7, -1, -1, 0}
+};
+
+static const symbol s_10_0[5] = { 'a', 'n', 'd', 'e', 's' };
+static const symbol s_10_1[5] = { 'a', 't', 'l', 'a', 's' };
+static const symbol s_10_2[4] = { 'b', 'i', 'a', 's' };
+static const symbol s_10_3[6] = { 'c', 'o', 's', 'm', 'o', 's' };
+static const symbol s_10_4[5] = { 'd', 'y', 'i', 'n', 'g' };
+static const symbol s_10_5[5] = { 'e', 'a', 'r', 'l', 'y' };
+static const symbol s_10_6[6] = { 'g', 'e', 'n', 't', 'l', 'y' };
+static const symbol s_10_7[4] = { 'h', 'o', 'w', 'e' };
+static const symbol s_10_8[4] = { 'i', 'd', 'l', 'y' };
+static const symbol s_10_9[5] = { 'l', 'y', 'i', 'n', 'g' };
+static const symbol s_10_10[4] = { 'n', 'e', 'w', 's' };
+static const symbol s_10_11[4] = { 'o', 'n', 'l', 'y' };
+static const symbol s_10_12[6] = { 's', 'i', 'n', 'g', 'l', 'y' };
+static const symbol s_10_13[5] = { 's', 'k', 'i', 'e', 's' };
+static const symbol s_10_14[4] = { 's', 'k', 'i', 's' };
+static const symbol s_10_15[3] = { 's', 'k', 'y' };
+static const symbol s_10_16[5] = { 't', 'y', 'i', 'n', 'g' };
+static const symbol s_10_17[4] = { 'u', 'g', 'l', 'y' };
+
+static const struct among a_10[18] =
+{
+/* 0 */ { 5, s_10_0, -1, -1, 0},
+/* 1 */ { 5, s_10_1, -1, -1, 0},
+/* 2 */ { 4, s_10_2, -1, -1, 0},
+/* 3 */ { 6, s_10_3, -1, -1, 0},
+/* 4 */ { 5, s_10_4, -1, 3, 0},
+/* 5 */ { 5, s_10_5, -1, 9, 0},
+/* 6 */ { 6, s_10_6, -1, 7, 0},
+/* 7 */ { 4, s_10_7, -1, -1, 0},
+/* 8 */ { 4, s_10_8, -1, 6, 0},
+/* 9 */ { 5, s_10_9, -1, 4, 0},
+/* 10 */ { 4, s_10_10, -1, -1, 0},
+/* 11 */ { 4, s_10_11, -1, 10, 0},
+/* 12 */ { 6, s_10_12, -1, 11, 0},
+/* 13 */ { 5, s_10_13, -1, 2, 0},
+/* 14 */ { 4, s_10_14, -1, 1, 0},
+/* 15 */ { 3, s_10_15, -1, -1, 0},
+/* 16 */ { 5, s_10_16, -1, 5, 0},
+/* 17 */ { 4, s_10_17, -1, 8, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1 };
+
+static const unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 };
+
+static const unsigned char g_valid_LI[] = { 55, 141, 2 };
+
+static const symbol s_0[] = { '\'' };
+static const symbol s_1[] = { 'y' };
+static const symbol s_2[] = { 'Y' };
+static const symbol s_3[] = { 'y' };
+static const symbol s_4[] = { 'Y' };
+static const symbol s_5[] = { 's', 's' };
+static const symbol s_6[] = { 'i' };
+static const symbol s_7[] = { 'i', 'e' };
+static const symbol s_8[] = { 'e', 'e' };
+static const symbol s_9[] = { 'e' };
+static const symbol s_10[] = { 'e' };
+static const symbol s_11[] = { 'y' };
+static const symbol s_12[] = { 'Y' };
+static const symbol s_13[] = { 'i' };
+static const symbol s_14[] = { 't', 'i', 'o', 'n' };
+static const symbol s_15[] = { 'e', 'n', 'c', 'e' };
+static const symbol s_16[] = { 'a', 'n', 'c', 'e' };
+static const symbol s_17[] = { 'a', 'b', 'l', 'e' };
+static const symbol s_18[] = { 'e', 'n', 't' };
+static const symbol s_19[] = { 'i', 'z', 'e' };
+static const symbol s_20[] = { 'a', 't', 'e' };
+static const symbol s_21[] = { 'a', 'l' };
+static const symbol s_22[] = { 'f', 'u', 'l' };
+static const symbol s_23[] = { 'o', 'u', 's' };
+static const symbol s_24[] = { 'i', 'v', 'e' };
+static const symbol s_25[] = { 'b', 'l', 'e' };
+static const symbol s_26[] = { 'l' };
+static const symbol s_27[] = { 'o', 'g' };
+static const symbol s_28[] = { 'f', 'u', 'l' };
+static const symbol s_29[] = { 'l', 'e', 's', 's' };
+static const symbol s_30[] = { 't', 'i', 'o', 'n' };
+static const symbol s_31[] = { 'a', 't', 'e' };
+static const symbol s_32[] = { 'a', 'l' };
+static const symbol s_33[] = { 'i', 'c' };
+static const symbol s_34[] = { 's' };
+static const symbol s_35[] = { 't' };
+static const symbol s_36[] = { 'l' };
+static const symbol s_37[] = { 's', 'k', 'i' };
+static const symbol s_38[] = { 's', 'k', 'y' };
+static const symbol s_39[] = { 'd', 'i', 'e' };
+static const symbol s_40[] = { 'l', 'i', 'e' };
+static const symbol s_41[] = { 't', 'i', 'e' };
+static const symbol s_42[] = { 'i', 'd', 'l' };
+static const symbol s_43[] = { 'g', 'e', 'n', 't', 'l' };
+static const symbol s_44[] = { 'u', 'g', 'l', 'i' };
+static const symbol s_45[] = { 'e', 'a', 'r', 'l', 'i' };
+static const symbol s_46[] = { 'o', 'n', 'l', 'i' };
+static const symbol s_47[] = { 's', 'i', 'n', 'g', 'l' };
+static const symbol s_48[] = { 'Y' };
+static const symbol s_49[] = { 'y' };
+
+static int r_prelude(struct SN_env * z) {
+ z->B[0] = 0; /* unset Y_found, line 26 */
+ { int c1 = z->c; /* do, line 27 */
+ z->bra = z->c; /* [, line 27 */
+ if (!(eq_s(z, 1, s_0))) goto lab0;
+ z->ket = z->c; /* ], line 27 */
+ { int ret = slice_del(z); /* delete, line 27 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 28 */
+ z->bra = z->c; /* [, line 28 */
+ if (!(eq_s(z, 1, s_1))) goto lab1;
+ z->ket = z->c; /* ], line 28 */
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 28 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set Y_found, line 28 */
+ lab1:
+ z->c = c2;
+ }
+ { int c3 = z->c; /* do, line 29 */
+ while(1) { /* repeat, line 29 */
+ int c4 = z->c;
+ while(1) { /* goto, line 29 */
+ int c5 = z->c;
+ if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab4;
+ z->bra = z->c; /* [, line 29 */
+ if (!(eq_s(z, 1, s_3))) goto lab4;
+ z->ket = z->c; /* ], line 29 */
+ z->c = c5;
+ break;
+ lab4:
+ z->c = c5;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab3;
+ z->c = ret; /* goto, line 29 */
+ }
+ }
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 29 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set Y_found, line 29 */
+ continue;
+ lab3:
+ z->c = c4;
+ break;
+ }
+ z->c = c3;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { int c1 = z->c; /* do, line 35 */
+ { int c2 = z->c; /* or, line 41 */
+ if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2;
+ if (!(find_among(z, a_0, 3))) goto lab2; /* among, line 36 */
+ goto lab1;
+ lab2:
+ z->c = c2;
+ { /* gopast */ /* grouping v, line 41 */
+ int ret = out_grouping_U(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 41 */
+ int ret = in_grouping_U(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark p1, line 42 */
+ { /* gopast */ /* grouping v, line 43 */
+ int ret = out_grouping_U(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 43 */
+ int ret = in_grouping_U(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 43 */
+ lab0:
+ z->c = c1;
+ }
+ return 1;
+}
+
+static int r_shortv(struct SN_env * z) {
+ { int m1 = z->l - z->c; (void)m1; /* or, line 51 */
+ if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) goto lab1;
+ if (in_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1;
+ if (out_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0;
+ if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0;
+ if (z->c > z->lb) return 0; /* atlimit, line 52 */
+ }
+lab0:
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_Step_1a(struct SN_env * z) {
+ int among_var;
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 59 */
+ z->ket = z->c; /* [, line 60 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m_keep; goto lab0; }
+ among_var = find_among_b(z, a_1, 3); /* substring, line 60 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 60 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab0; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 62 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ ;
+ }
+ z->ket = z->c; /* [, line 65 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0;
+ among_var = find_among_b(z, a_2, 6); /* substring, line 65 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 65 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_5); /* <-, line 66 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 68 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 2);
+ if (ret < 0) goto lab2;
+ z->c = ret; /* hop, line 68 */
+ }
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 68 */
+ if (ret < 0) return ret;
+ }
+ goto lab1;
+ lab2:
+ z->c = z->l - m1;
+ { int ret = slice_from_s(z, 2, s_7); /* <-, line 68 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab1:
+ break;
+ case 3:
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 69 */
+ }
+ { /* gopast */ /* grouping v, line 69 */
+ int ret = out_grouping_b_U(z, g_v, 97, 121, 1);
+ if (ret < 0) return 0;
+ z->c -= ret;
+ }
+ { int ret = slice_del(z); /* delete, line 69 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_1b(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 75 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_4, 6); /* substring, line 75 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 75 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 77 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 2, s_8); /* <-, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m_test = z->l - z->c; /* test, line 80 */
+ { /* gopast */ /* grouping v, line 80 */
+ int ret = out_grouping_b_U(z, g_v, 97, 121, 1);
+ if (ret < 0) return 0;
+ z->c -= ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 80 */
+ if (ret < 0) return ret;
+ }
+ { int m_test = z->l - z->c; /* test, line 81 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else
+ among_var = find_among_b(z, a_3, 13); /* substring, line 81 */
+ if (!(among_var)) return 0;
+ z->c = z->l - m_test;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_9); /* <+, line 83 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ z->ket = z->c; /* [, line 86 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 86 */
+ }
+ z->bra = z->c; /* ], line 86 */
+ { int ret = slice_del(z); /* delete, line 86 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c != z->I[0]) return 0; /* atmark, line 87 */
+ { int m_test = z->l - z->c; /* test, line 87 */
+ { int ret = r_shortv(z);
+ if (ret == 0) return 0; /* call shortv, line 87 */
+ if (ret < 0) return ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_10); /* <+, line 87 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_1c(struct SN_env * z) {
+ z->ket = z->c; /* [, line 94 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 94 */
+ if (!(eq_s_b(z, 1, s_11))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_12))) return 0;
+ }
+lab0:
+ z->bra = z->c; /* ], line 94 */
+ if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0;
+ { int m2 = z->l - z->c; (void)m2; /* not, line 95 */
+ if (z->c > z->lb) goto lab2; /* atlimit, line 95 */
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 96 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_Step_2(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 100 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_5, 24); /* substring, line 100 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 100 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 100 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 4, s_14); /* <-, line 101 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 4, s_15); /* <-, line 102 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 4, s_16); /* <-, line 103 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 4, s_17); /* <-, line 104 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 3, s_18); /* <-, line 105 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 3, s_19); /* <-, line 107 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 3, s_20); /* <-, line 109 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 2, s_21); /* <-, line 111 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_from_s(z, 3, s_22); /* <-, line 112 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_from_s(z, 3, s_23); /* <-, line 114 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_from_s(z, 3, s_24); /* <-, line 116 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 12:
+ { int ret = slice_from_s(z, 3, s_25); /* <-, line 118 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ if (!(eq_s_b(z, 1, s_26))) return 0;
+ { int ret = slice_from_s(z, 2, s_27); /* <-, line 119 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 14:
+ { int ret = slice_from_s(z, 3, s_28); /* <-, line 120 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 15:
+ { int ret = slice_from_s(z, 4, s_29); /* <-, line 121 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 16:
+ if (in_grouping_b_U(z, g_valid_LI, 99, 116, 0)) return 0;
+ { int ret = slice_del(z); /* delete, line 122 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_3(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 127 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_6, 9); /* substring, line 127 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 127 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 127 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 4, s_30); /* <-, line 128 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 3, s_31); /* <-, line 129 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 2, s_32); /* <-, line 130 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 2, s_33); /* <-, line 132 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 136 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 136 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_4(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 141 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_7, 18); /* substring, line 141 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 141 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 141 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 144 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 145 */
+ if (!(eq_s_b(z, 1, s_34))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_35))) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 145 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_5(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 150 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0;
+ among_var = find_among_b(z, a_8, 2); /* substring, line 150 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 150 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 151 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab1; /* call R2, line 151 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 151 */
+ if (ret < 0) return ret;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* not, line 151 */
+ { int ret = r_shortv(z);
+ if (ret == 0) goto lab2; /* call shortv, line 151 */
+ if (ret < 0) return ret;
+ }
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 151 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 152 */
+ if (ret < 0) return ret;
+ }
+ if (!(eq_s_b(z, 1, s_36))) return 0;
+ { int ret = slice_del(z); /* delete, line 152 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_exception2(struct SN_env * z) {
+ z->ket = z->c; /* [, line 158 */
+ if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0;
+ if (!(find_among_b(z, a_9, 8))) return 0; /* substring, line 158 */
+ z->bra = z->c; /* ], line 158 */
+ if (z->c > z->lb) return 0; /* atlimit, line 158 */
+ return 1;
+}
+
+static int r_exception1(struct SN_env * z) {
+ int among_var;
+ z->bra = z->c; /* [, line 170 */
+ if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0;
+ among_var = find_among(z, a_10, 18); /* substring, line 170 */
+ if (!(among_var)) return 0;
+ z->ket = z->c; /* ], line 170 */
+ if (z->c < z->l) return 0; /* atlimit, line 170 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 3, s_37); /* <-, line 174 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 3, s_38); /* <-, line 175 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 3, s_39); /* <-, line 176 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 3, s_40); /* <-, line 177 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 3, s_41); /* <-, line 178 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 3, s_42); /* <-, line 182 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 5, s_43); /* <-, line 183 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 4, s_44); /* <-, line 184 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_from_s(z, 5, s_45); /* <-, line 185 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_from_s(z, 4, s_46); /* <-, line 186 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_from_s(z, 5, s_47); /* <-, line 187 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ if (!(z->B[0])) return 0; /* Boolean test Y_found, line 203 */
+ while(1) { /* repeat, line 203 */
+ int c1 = z->c;
+ while(1) { /* goto, line 203 */
+ int c2 = z->c;
+ z->bra = z->c; /* [, line 203 */
+ if (!(eq_s(z, 1, s_48))) goto lab1;
+ z->ket = z->c; /* ], line 203 */
+ z->c = c2;
+ break;
+ lab1:
+ z->c = c2;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* goto, line 203 */
+ }
+ }
+ { int ret = slice_from_s(z, 1, s_49); /* <-, line 203 */
+ if (ret < 0) return ret;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+extern int english_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* or, line 207 */
+ { int ret = r_exception1(z);
+ if (ret == 0) goto lab1; /* call exception1, line 207 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab1:
+ z->c = c1;
+ { int c2 = z->c; /* not, line 208 */
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3);
+ if (ret < 0) goto lab3;
+ z->c = ret; /* hop, line 208 */
+ }
+ goto lab2;
+ lab3:
+ z->c = c2;
+ }
+ goto lab0;
+ lab2:
+ z->c = c1;
+ { int c3 = z->c; /* do, line 209 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab4; /* call prelude, line 209 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ z->c = c3;
+ }
+ { int c4 = z->c; /* do, line 210 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab5; /* call mark_regions, line 210 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ z->c = c4;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 211 */
+
+ { int m5 = z->l - z->c; (void)m5; /* do, line 213 */
+ { int ret = r_Step_1a(z);
+ if (ret == 0) goto lab6; /* call Step_1a, line 213 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m5;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* or, line 215 */
+ { int ret = r_exception2(z);
+ if (ret == 0) goto lab8; /* call exception2, line 215 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab8:
+ z->c = z->l - m6;
+ { int m7 = z->l - z->c; (void)m7; /* do, line 217 */
+ { int ret = r_Step_1b(z);
+ if (ret == 0) goto lab9; /* call Step_1b, line 217 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m7;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 218 */
+ { int ret = r_Step_1c(z);
+ if (ret == 0) goto lab10; /* call Step_1c, line 218 */
+ if (ret < 0) return ret;
+ }
+ lab10:
+ z->c = z->l - m8;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 220 */
+ { int ret = r_Step_2(z);
+ if (ret == 0) goto lab11; /* call Step_2, line 220 */
+ if (ret < 0) return ret;
+ }
+ lab11:
+ z->c = z->l - m9;
+ }
+ { int m10 = z->l - z->c; (void)m10; /* do, line 221 */
+ { int ret = r_Step_3(z);
+ if (ret == 0) goto lab12; /* call Step_3, line 221 */
+ if (ret < 0) return ret;
+ }
+ lab12:
+ z->c = z->l - m10;
+ }
+ { int m11 = z->l - z->c; (void)m11; /* do, line 222 */
+ { int ret = r_Step_4(z);
+ if (ret == 0) goto lab13; /* call Step_4, line 222 */
+ if (ret < 0) return ret;
+ }
+ lab13:
+ z->c = z->l - m11;
+ }
+ { int m12 = z->l - z->c; (void)m12; /* do, line 224 */
+ { int ret = r_Step_5(z);
+ if (ret == 0) goto lab14; /* call Step_5, line 224 */
+ if (ret < 0) return ret;
+ }
+ lab14:
+ z->c = z->l - m12;
+ }
+ }
+ lab7:
+ z->c = z->lb;
+ { int c13 = z->c; /* do, line 227 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab15; /* call postlude, line 227 */
+ if (ret < 0) return ret;
+ }
+ lab15:
+ z->c = c13;
+ }
+ }
+lab0:
+ return 1;
+}
+
+extern struct SN_env * english_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); }
+
+extern void english_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c b/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c
new file mode 100644
index 00000000000..55fba0a732d
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c
@@ -0,0 +1,768 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int finnish_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_tidy(struct SN_env * z);
+static int r_other_endings(struct SN_env * z);
+static int r_t_plural(struct SN_env * z);
+static int r_i_plural(struct SN_env * z);
+static int r_case_ending(struct SN_env * z);
+static int r_VI(struct SN_env * z);
+static int r_LONG(struct SN_env * z);
+static int r_possessive(struct SN_env * z);
+static int r_particle_etc(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * finnish_UTF_8_create_env(void);
+extern void finnish_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[2] = { 'p', 'a' };
+static const symbol s_0_1[3] = { 's', 't', 'i' };
+static const symbol s_0_2[4] = { 'k', 'a', 'a', 'n' };
+static const symbol s_0_3[3] = { 'h', 'a', 'n' };
+static const symbol s_0_4[3] = { 'k', 'i', 'n' };
+static const symbol s_0_5[4] = { 'h', 0xC3, 0xA4, 'n' };
+static const symbol s_0_6[6] = { 'k', 0xC3, 0xA4, 0xC3, 0xA4, 'n' };
+static const symbol s_0_7[2] = { 'k', 'o' };
+static const symbol s_0_8[3] = { 'p', 0xC3, 0xA4 };
+static const symbol s_0_9[3] = { 'k', 0xC3, 0xB6 };
+
+static const struct among a_0[10] =
+{
+/* 0 */ { 2, s_0_0, -1, 1, 0},
+/* 1 */ { 3, s_0_1, -1, 2, 0},
+/* 2 */ { 4, s_0_2, -1, 1, 0},
+/* 3 */ { 3, s_0_3, -1, 1, 0},
+/* 4 */ { 3, s_0_4, -1, 1, 0},
+/* 5 */ { 4, s_0_5, -1, 1, 0},
+/* 6 */ { 6, s_0_6, -1, 1, 0},
+/* 7 */ { 2, s_0_7, -1, 1, 0},
+/* 8 */ { 3, s_0_8, -1, 1, 0},
+/* 9 */ { 3, s_0_9, -1, 1, 0}
+};
+
+static const symbol s_1_0[3] = { 'l', 'l', 'a' };
+static const symbol s_1_1[2] = { 'n', 'a' };
+static const symbol s_1_2[3] = { 's', 's', 'a' };
+static const symbol s_1_3[2] = { 't', 'a' };
+static const symbol s_1_4[3] = { 'l', 't', 'a' };
+static const symbol s_1_5[3] = { 's', 't', 'a' };
+
+static const struct among a_1[6] =
+{
+/* 0 */ { 3, s_1_0, -1, -1, 0},
+/* 1 */ { 2, s_1_1, -1, -1, 0},
+/* 2 */ { 3, s_1_2, -1, -1, 0},
+/* 3 */ { 2, s_1_3, -1, -1, 0},
+/* 4 */ { 3, s_1_4, 3, -1, 0},
+/* 5 */ { 3, s_1_5, 3, -1, 0}
+};
+
+static const symbol s_2_0[4] = { 'l', 'l', 0xC3, 0xA4 };
+static const symbol s_2_1[3] = { 'n', 0xC3, 0xA4 };
+static const symbol s_2_2[4] = { 's', 's', 0xC3, 0xA4 };
+static const symbol s_2_3[3] = { 't', 0xC3, 0xA4 };
+static const symbol s_2_4[4] = { 'l', 't', 0xC3, 0xA4 };
+static const symbol s_2_5[4] = { 's', 't', 0xC3, 0xA4 };
+
+static const struct among a_2[6] =
+{
+/* 0 */ { 4, s_2_0, -1, -1, 0},
+/* 1 */ { 3, s_2_1, -1, -1, 0},
+/* 2 */ { 4, s_2_2, -1, -1, 0},
+/* 3 */ { 3, s_2_3, -1, -1, 0},
+/* 4 */ { 4, s_2_4, 3, -1, 0},
+/* 5 */ { 4, s_2_5, 3, -1, 0}
+};
+
+static const symbol s_3_0[3] = { 'l', 'l', 'e' };
+static const symbol s_3_1[3] = { 'i', 'n', 'e' };
+
+static const struct among a_3[2] =
+{
+/* 0 */ { 3, s_3_0, -1, -1, 0},
+/* 1 */ { 3, s_3_1, -1, -1, 0}
+};
+
+static const symbol s_4_0[3] = { 'n', 's', 'a' };
+static const symbol s_4_1[3] = { 'm', 'm', 'e' };
+static const symbol s_4_2[3] = { 'n', 'n', 'e' };
+static const symbol s_4_3[2] = { 'n', 'i' };
+static const symbol s_4_4[2] = { 's', 'i' };
+static const symbol s_4_5[2] = { 'a', 'n' };
+static const symbol s_4_6[2] = { 'e', 'n' };
+static const symbol s_4_7[3] = { 0xC3, 0xA4, 'n' };
+static const symbol s_4_8[4] = { 'n', 's', 0xC3, 0xA4 };
+
+static const struct among a_4[9] =
+{
+/* 0 */ { 3, s_4_0, -1, 3, 0},
+/* 1 */ { 3, s_4_1, -1, 3, 0},
+/* 2 */ { 3, s_4_2, -1, 3, 0},
+/* 3 */ { 2, s_4_3, -1, 2, 0},
+/* 4 */ { 2, s_4_4, -1, 1, 0},
+/* 5 */ { 2, s_4_5, -1, 4, 0},
+/* 6 */ { 2, s_4_6, -1, 6, 0},
+/* 7 */ { 3, s_4_7, -1, 5, 0},
+/* 8 */ { 4, s_4_8, -1, 3, 0}
+};
+
+static const symbol s_5_0[2] = { 'a', 'a' };
+static const symbol s_5_1[2] = { 'e', 'e' };
+static const symbol s_5_2[2] = { 'i', 'i' };
+static const symbol s_5_3[2] = { 'o', 'o' };
+static const symbol s_5_4[2] = { 'u', 'u' };
+static const symbol s_5_5[4] = { 0xC3, 0xA4, 0xC3, 0xA4 };
+static const symbol s_5_6[4] = { 0xC3, 0xB6, 0xC3, 0xB6 };
+
+static const struct among a_5[7] =
+{
+/* 0 */ { 2, s_5_0, -1, -1, 0},
+/* 1 */ { 2, s_5_1, -1, -1, 0},
+/* 2 */ { 2, s_5_2, -1, -1, 0},
+/* 3 */ { 2, s_5_3, -1, -1, 0},
+/* 4 */ { 2, s_5_4, -1, -1, 0},
+/* 5 */ { 4, s_5_5, -1, -1, 0},
+/* 6 */ { 4, s_5_6, -1, -1, 0}
+};
+
+static const symbol s_6_0[1] = { 'a' };
+static const symbol s_6_1[3] = { 'l', 'l', 'a' };
+static const symbol s_6_2[2] = { 'n', 'a' };
+static const symbol s_6_3[3] = { 's', 's', 'a' };
+static const symbol s_6_4[2] = { 't', 'a' };
+static const symbol s_6_5[3] = { 'l', 't', 'a' };
+static const symbol s_6_6[3] = { 's', 't', 'a' };
+static const symbol s_6_7[3] = { 't', 't', 'a' };
+static const symbol s_6_8[3] = { 'l', 'l', 'e' };
+static const symbol s_6_9[3] = { 'i', 'n', 'e' };
+static const symbol s_6_10[3] = { 'k', 's', 'i' };
+static const symbol s_6_11[1] = { 'n' };
+static const symbol s_6_12[3] = { 'h', 'a', 'n' };
+static const symbol s_6_13[3] = { 'd', 'e', 'n' };
+static const symbol s_6_14[4] = { 's', 'e', 'e', 'n' };
+static const symbol s_6_15[3] = { 'h', 'e', 'n' };
+static const symbol s_6_16[4] = { 't', 't', 'e', 'n' };
+static const symbol s_6_17[3] = { 'h', 'i', 'n' };
+static const symbol s_6_18[4] = { 's', 'i', 'i', 'n' };
+static const symbol s_6_19[3] = { 'h', 'o', 'n' };
+static const symbol s_6_20[4] = { 'h', 0xC3, 0xA4, 'n' };
+static const symbol s_6_21[4] = { 'h', 0xC3, 0xB6, 'n' };
+static const symbol s_6_22[2] = { 0xC3, 0xA4 };
+static const symbol s_6_23[4] = { 'l', 'l', 0xC3, 0xA4 };
+static const symbol s_6_24[3] = { 'n', 0xC3, 0xA4 };
+static const symbol s_6_25[4] = { 's', 's', 0xC3, 0xA4 };
+static const symbol s_6_26[3] = { 't', 0xC3, 0xA4 };
+static const symbol s_6_27[4] = { 'l', 't', 0xC3, 0xA4 };
+static const symbol s_6_28[4] = { 's', 't', 0xC3, 0xA4 };
+static const symbol s_6_29[4] = { 't', 't', 0xC3, 0xA4 };
+
+static const struct among a_6[30] =
+{
+/* 0 */ { 1, s_6_0, -1, 8, 0},
+/* 1 */ { 3, s_6_1, 0, -1, 0},
+/* 2 */ { 2, s_6_2, 0, -1, 0},
+/* 3 */ { 3, s_6_3, 0, -1, 0},
+/* 4 */ { 2, s_6_4, 0, -1, 0},
+/* 5 */ { 3, s_6_5, 4, -1, 0},
+/* 6 */ { 3, s_6_6, 4, -1, 0},
+/* 7 */ { 3, s_6_7, 4, 9, 0},
+/* 8 */ { 3, s_6_8, -1, -1, 0},
+/* 9 */ { 3, s_6_9, -1, -1, 0},
+/* 10 */ { 3, s_6_10, -1, -1, 0},
+/* 11 */ { 1, s_6_11, -1, 7, 0},
+/* 12 */ { 3, s_6_12, 11, 1, 0},
+/* 13 */ { 3, s_6_13, 11, -1, r_VI},
+/* 14 */ { 4, s_6_14, 11, -1, r_LONG},
+/* 15 */ { 3, s_6_15, 11, 2, 0},
+/* 16 */ { 4, s_6_16, 11, -1, r_VI},
+/* 17 */ { 3, s_6_17, 11, 3, 0},
+/* 18 */ { 4, s_6_18, 11, -1, r_VI},
+/* 19 */ { 3, s_6_19, 11, 4, 0},
+/* 20 */ { 4, s_6_20, 11, 5, 0},
+/* 21 */ { 4, s_6_21, 11, 6, 0},
+/* 22 */ { 2, s_6_22, -1, 8, 0},
+/* 23 */ { 4, s_6_23, 22, -1, 0},
+/* 24 */ { 3, s_6_24, 22, -1, 0},
+/* 25 */ { 4, s_6_25, 22, -1, 0},
+/* 26 */ { 3, s_6_26, 22, -1, 0},
+/* 27 */ { 4, s_6_27, 26, -1, 0},
+/* 28 */ { 4, s_6_28, 26, -1, 0},
+/* 29 */ { 4, s_6_29, 26, 9, 0}
+};
+
+static const symbol s_7_0[3] = { 'e', 'j', 'a' };
+static const symbol s_7_1[3] = { 'm', 'm', 'a' };
+static const symbol s_7_2[4] = { 'i', 'm', 'm', 'a' };
+static const symbol s_7_3[3] = { 'm', 'p', 'a' };
+static const symbol s_7_4[4] = { 'i', 'm', 'p', 'a' };
+static const symbol s_7_5[3] = { 'm', 'm', 'i' };
+static const symbol s_7_6[4] = { 'i', 'm', 'm', 'i' };
+static const symbol s_7_7[3] = { 'm', 'p', 'i' };
+static const symbol s_7_8[4] = { 'i', 'm', 'p', 'i' };
+static const symbol s_7_9[4] = { 'e', 'j', 0xC3, 0xA4 };
+static const symbol s_7_10[4] = { 'm', 'm', 0xC3, 0xA4 };
+static const symbol s_7_11[5] = { 'i', 'm', 'm', 0xC3, 0xA4 };
+static const symbol s_7_12[4] = { 'm', 'p', 0xC3, 0xA4 };
+static const symbol s_7_13[5] = { 'i', 'm', 'p', 0xC3, 0xA4 };
+
+static const struct among a_7[14] =
+{
+/* 0 */ { 3, s_7_0, -1, -1, 0},
+/* 1 */ { 3, s_7_1, -1, 1, 0},
+/* 2 */ { 4, s_7_2, 1, -1, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0},
+/* 4 */ { 4, s_7_4, 3, -1, 0},
+/* 5 */ { 3, s_7_5, -1, 1, 0},
+/* 6 */ { 4, s_7_6, 5, -1, 0},
+/* 7 */ { 3, s_7_7, -1, 1, 0},
+/* 8 */ { 4, s_7_8, 7, -1, 0},
+/* 9 */ { 4, s_7_9, -1, -1, 0},
+/* 10 */ { 4, s_7_10, -1, 1, 0},
+/* 11 */ { 5, s_7_11, 10, -1, 0},
+/* 12 */ { 4, s_7_12, -1, 1, 0},
+/* 13 */ { 5, s_7_13, 12, -1, 0}
+};
+
+static const symbol s_8_0[1] = { 'i' };
+static const symbol s_8_1[1] = { 'j' };
+
+static const struct among a_8[2] =
+{
+/* 0 */ { 1, s_8_0, -1, -1, 0},
+/* 1 */ { 1, s_8_1, -1, -1, 0}
+};
+
+static const symbol s_9_0[3] = { 'm', 'm', 'a' };
+static const symbol s_9_1[4] = { 'i', 'm', 'm', 'a' };
+
+static const struct among a_9[2] =
+{
+/* 0 */ { 3, s_9_0, -1, 1, 0},
+/* 1 */ { 4, s_9_1, 0, -1, 0}
+};
+
+static const unsigned char g_AEI[] = { 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 };
+
+static const unsigned char g_V1[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 };
+
+static const unsigned char g_V2[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 };
+
+static const unsigned char g_particle_end[] = { 17, 97, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 };
+
+static const symbol s_0[] = { 'k' };
+static const symbol s_1[] = { 'k', 's', 'e' };
+static const symbol s_2[] = { 'k', 's', 'i' };
+static const symbol s_3[] = { 'i' };
+static const symbol s_4[] = { 'a' };
+static const symbol s_5[] = { 'e' };
+static const symbol s_6[] = { 'i' };
+static const symbol s_7[] = { 'o' };
+static const symbol s_8[] = { 0xC3, 0xA4 };
+static const symbol s_9[] = { 0xC3, 0xB6 };
+static const symbol s_10[] = { 'i', 'e' };
+static const symbol s_11[] = { 'e' };
+static const symbol s_12[] = { 'p', 'o' };
+static const symbol s_13[] = { 't' };
+static const symbol s_14[] = { 'p', 'o' };
+static const symbol s_15[] = { 'j' };
+static const symbol s_16[] = { 'o' };
+static const symbol s_17[] = { 'u' };
+static const symbol s_18[] = { 'o' };
+static const symbol s_19[] = { 'j' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 46 */
+ { /* gopast */ /* non V1, line 46 */
+ int ret = in_grouping_U(z, g_V1, 97, 246, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 46 */
+ if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 47 */
+ { /* gopast */ /* non V1, line 47 */
+ int ret = in_grouping_U(z, g_V1, 97, 246, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 47 */
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_particle_etc(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 55 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 55 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 55 */
+ among_var = find_among_b(z, a_0, 10); /* substring, line 55 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 55 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ if (in_grouping_b_U(z, g_particle_end, 97, 246, 0)) return 0;
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 64 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 66 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_possessive(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 69 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 69 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 69 */
+ among_var = find_among_b(z, a_4, 9); /* substring, line 69 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 69 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m2 = z->l - z->c; (void)m2; /* not, line 72 */
+ if (!(eq_s_b(z, 1, s_0))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m2;
+ }
+ { int ret = slice_del(z); /* delete, line 72 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 74 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 74 */
+ if (!(eq_s_b(z, 3, s_1))) return 0;
+ z->bra = z->c; /* ], line 74 */
+ { int ret = slice_from_s(z, 3, s_2); /* <-, line 74 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0;
+ if (!(find_among_b(z, a_1, 6))) return 0; /* among, line 81 */
+ { int ret = slice_del(z); /* delete, line 81 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 164) return 0;
+ if (!(find_among_b(z, a_2, 6))) return 0; /* among, line 83 */
+ { int ret = slice_del(z); /* delete, line 84 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0;
+ if (!(find_among_b(z, a_3, 2))) return 0; /* among, line 86 */
+ { int ret = slice_del(z); /* delete, line 86 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_LONG(struct SN_env * z) {
+ if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 91 */
+ return 1;
+}
+
+static int r_VI(struct SN_env * z) {
+ if (!(eq_s_b(z, 1, s_3))) return 0;
+ if (in_grouping_b_U(z, g_V2, 97, 246, 0)) return 0;
+ return 1;
+}
+
+static int r_case_ending(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 96 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 96 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 96 */
+ among_var = find_among_b(z, a_6, 30); /* substring, line 96 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 96 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ if (!(eq_s_b(z, 1, s_4))) return 0;
+ break;
+ case 2:
+ if (!(eq_s_b(z, 1, s_5))) return 0;
+ break;
+ case 3:
+ if (!(eq_s_b(z, 1, s_6))) return 0;
+ break;
+ case 4:
+ if (!(eq_s_b(z, 1, s_7))) return 0;
+ break;
+ case 5:
+ if (!(eq_s_b(z, 2, s_8))) return 0;
+ break;
+ case 6:
+ if (!(eq_s_b(z, 2, s_9))) return 0;
+ break;
+ case 7:
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */
+ { int m2 = z->l - z->c; (void)m2; /* and, line 113 */
+ { int m3 = z->l - z->c; (void)m3; /* or, line 112 */
+ { int ret = r_LONG(z);
+ if (ret == 0) goto lab2; /* call LONG, line 111 */
+ if (ret < 0) return ret;
+ }
+ goto lab1;
+ lab2:
+ z->c = z->l - m3;
+ if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m_keep; goto lab0; }
+ }
+ lab1:
+ z->c = z->l - m2;
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) { z->c = z->l - m_keep; goto lab0; }
+ z->c = ret; /* next, line 113 */
+ }
+ }
+ z->bra = z->c; /* ], line 113 */
+ lab0:
+ ;
+ }
+ break;
+ case 8:
+ if (in_grouping_b_U(z, g_V1, 97, 246, 0)) return 0;
+ if (out_grouping_b_U(z, g_V1, 97, 246, 0)) return 0;
+ break;
+ case 9:
+ if (!(eq_s_b(z, 1, s_11))) return 0;
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 138 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set ending_removed, line 139 */
+ return 1;
+}
+
+static int r_other_endings(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 142 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[1]) return 0;
+ z->c = z->I[1]; /* tomark, line 142 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 142 */
+ among_var = find_among_b(z, a_7, 14); /* substring, line 142 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 142 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m2 = z->l - z->c; (void)m2; /* not, line 146 */
+ if (!(eq_s_b(z, 2, s_12))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m2;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 151 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_i_plural(struct SN_env * z) {
+ { int mlimit; /* setlimit, line 154 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 154 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 154 */
+ if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit; return 0; }
+ if (!(find_among_b(z, a_8, 2))) { z->lb = mlimit; return 0; } /* substring, line 154 */
+ z->bra = z->c; /* ], line 154 */
+ z->lb = mlimit;
+ }
+ { int ret = slice_del(z); /* delete, line 158 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_t_plural(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 161 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 161 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 162 */
+ if (!(eq_s_b(z, 1, s_13))) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 162 */
+ { int m_test = z->l - z->c; /* test, line 162 */
+ if (in_grouping_b_U(z, g_V1, 97, 246, 0)) { z->lb = mlimit; return 0; }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 163 */
+ if (ret < 0) return ret;
+ }
+ z->lb = mlimit;
+ }
+ { int mlimit; /* setlimit, line 165 */
+ int m2 = z->l - z->c; (void)m2;
+ if (z->c < z->I[1]) return 0;
+ z->c = z->I[1]; /* tomark, line 165 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m2;
+ z->ket = z->c; /* [, line 165 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_9, 2); /* substring, line 165 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 165 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m3 = z->l - z->c; (void)m3; /* not, line 167 */
+ if (!(eq_s_b(z, 2, s_14))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m3;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 170 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_tidy(struct SN_env * z) {
+ { int mlimit; /* setlimit, line 173 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 173 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* do, line 174 */
+ { int m3 = z->l - z->c; (void)m3; /* and, line 174 */
+ { int ret = r_LONG(z);
+ if (ret == 0) goto lab0; /* call LONG, line 174 */
+ if (ret < 0) return ret;
+ }
+ z->c = z->l - m3;
+ z->ket = z->c; /* [, line 174 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 174 */
+ }
+ z->bra = z->c; /* ], line 174 */
+ { int ret = slice_del(z); /* delete, line 174 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab0:
+ z->c = z->l - m2;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 175 */
+ z->ket = z->c; /* [, line 175 */
+ if (in_grouping_b_U(z, g_AEI, 97, 228, 0)) goto lab1;
+ z->bra = z->c; /* ], line 175 */
+ if (out_grouping_b_U(z, g_V1, 97, 246, 0)) goto lab1;
+ { int ret = slice_del(z); /* delete, line 175 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 176 */
+ z->ket = z->c; /* [, line 176 */
+ if (!(eq_s_b(z, 1, s_15))) goto lab2;
+ z->bra = z->c; /* ], line 176 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 176 */
+ if (!(eq_s_b(z, 1, s_16))) goto lab4;
+ goto lab3;
+ lab4:
+ z->c = z->l - m6;
+ if (!(eq_s_b(z, 1, s_17))) goto lab2;
+ }
+ lab3:
+ { int ret = slice_del(z); /* delete, line 176 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m5;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 177 */
+ z->ket = z->c; /* [, line 177 */
+ if (!(eq_s_b(z, 1, s_18))) goto lab5;
+ z->bra = z->c; /* ], line 177 */
+ if (!(eq_s_b(z, 1, s_19))) goto lab5;
+ { int ret = slice_del(z); /* delete, line 177 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ z->c = z->l - m7;
+ }
+ z->lb = mlimit;
+ }
+ if (in_grouping_b_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* non V1, line 179 */
+ z->ket = z->c; /* [, line 179 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 179 */
+ }
+ z->bra = z->c; /* ], line 179 */
+ z->S[0] = slice_to(z, z->S[0]); /* -> x, line 179 */
+ if (z->S[0] == 0) return -1; /* -> x, line 179 */
+ if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 179 */
+ { int ret = slice_del(z); /* delete, line 179 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern int finnish_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 185 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 185 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->B[0] = 0; /* unset ending_removed, line 186 */
+ z->lb = z->c; z->c = z->l; /* backwards, line 187 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 188 */
+ { int ret = r_particle_etc(z);
+ if (ret == 0) goto lab1; /* call particle_etc, line 188 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 189 */
+ { int ret = r_possessive(z);
+ if (ret == 0) goto lab2; /* call possessive, line 189 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 190 */
+ { int ret = r_case_ending(z);
+ if (ret == 0) goto lab3; /* call case_ending, line 190 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 191 */
+ { int ret = r_other_endings(z);
+ if (ret == 0) goto lab4; /* call other_endings, line 191 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ z->c = z->l - m5;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* or, line 192 */
+ if (!(z->B[0])) goto lab6; /* Boolean test ending_removed, line 192 */
+ { int m7 = z->l - z->c; (void)m7; /* do, line 192 */
+ { int ret = r_i_plural(z);
+ if (ret == 0) goto lab7; /* call i_plural, line 192 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m7;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int m8 = z->l - z->c; (void)m8; /* do, line 192 */
+ { int ret = r_t_plural(z);
+ if (ret == 0) goto lab8; /* call t_plural, line 192 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = z->l - m8;
+ }
+ }
+lab5:
+ { int m9 = z->l - z->c; (void)m9; /* do, line 193 */
+ { int ret = r_tidy(z);
+ if (ret == 0) goto lab9; /* call tidy, line 193 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m9;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * finnish_UTF_8_create_env(void) { return SN_create_env(1, 2, 1); }
+
+extern void finnish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 1); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_french.c b/src/backend/snowball/libstemmer/stem_UTF_8_french.c
new file mode 100644
index 00000000000..fa1507f2c63
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_french.c
@@ -0,0 +1,1256 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int french_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_un_accent(struct SN_env * z);
+static int r_un_double(struct SN_env * z);
+static int r_residual_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_i_verb_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * french_UTF_8_create_env(void);
+extern void french_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[3] = { 'c', 'o', 'l' };
+static const symbol s_0_1[3] = { 'p', 'a', 'r' };
+static const symbol s_0_2[3] = { 't', 'a', 'p' };
+
+static const struct among a_0[3] =
+{
+/* 0 */ { 3, s_0_0, -1, -1, 0},
+/* 1 */ { 3, s_0_1, -1, -1, 0},
+/* 2 */ { 3, s_0_2, -1, -1, 0}
+};
+
+static const symbol s_1_1[1] = { 'I' };
+static const symbol s_1_2[1] = { 'U' };
+static const symbol s_1_3[1] = { 'Y' };
+
+static const struct among a_1[4] =
+{
+/* 0 */ { 0, 0, -1, 4, 0},
+/* 1 */ { 1, s_1_1, 0, 1, 0},
+/* 2 */ { 1, s_1_2, 0, 2, 0},
+/* 3 */ { 1, s_1_3, 0, 3, 0}
+};
+
+static const symbol s_2_0[3] = { 'i', 'q', 'U' };
+static const symbol s_2_1[3] = { 'a', 'b', 'l' };
+static const symbol s_2_2[4] = { 'I', 0xC3, 0xA8, 'r' };
+static const symbol s_2_3[4] = { 'i', 0xC3, 0xA8, 'r' };
+static const symbol s_2_4[3] = { 'e', 'u', 's' };
+static const symbol s_2_5[2] = { 'i', 'v' };
+
+static const struct among a_2[6] =
+{
+/* 0 */ { 3, s_2_0, -1, 3, 0},
+/* 1 */ { 3, s_2_1, -1, 3, 0},
+/* 2 */ { 4, s_2_2, -1, 4, 0},
+/* 3 */ { 4, s_2_3, -1, 4, 0},
+/* 4 */ { 3, s_2_4, -1, 2, 0},
+/* 5 */ { 2, s_2_5, -1, 1, 0}
+};
+
+static const symbol s_3_0[2] = { 'i', 'c' };
+static const symbol s_3_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_3_2[2] = { 'i', 'v' };
+
+static const struct among a_3[3] =
+{
+/* 0 */ { 2, s_3_0, -1, 2, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0},
+/* 2 */ { 2, s_3_2, -1, 3, 0}
+};
+
+static const symbol s_4_0[4] = { 'i', 'q', 'U', 'e' };
+static const symbol s_4_1[6] = { 'a', 't', 'r', 'i', 'c', 'e' };
+static const symbol s_4_2[4] = { 'a', 'n', 'c', 'e' };
+static const symbol s_4_3[4] = { 'e', 'n', 'c', 'e' };
+static const symbol s_4_4[5] = { 'l', 'o', 'g', 'i', 'e' };
+static const symbol s_4_5[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_4_6[4] = { 'i', 's', 'm', 'e' };
+static const symbol s_4_7[4] = { 'e', 'u', 's', 'e' };
+static const symbol s_4_8[4] = { 'i', 's', 't', 'e' };
+static const symbol s_4_9[3] = { 'i', 'v', 'e' };
+static const symbol s_4_10[2] = { 'i', 'f' };
+static const symbol s_4_11[5] = { 'u', 's', 'i', 'o', 'n' };
+static const symbol s_4_12[5] = { 'a', 't', 'i', 'o', 'n' };
+static const symbol s_4_13[5] = { 'u', 't', 'i', 'o', 'n' };
+static const symbol s_4_14[5] = { 'a', 't', 'e', 'u', 'r' };
+static const symbol s_4_15[5] = { 'i', 'q', 'U', 'e', 's' };
+static const symbol s_4_16[7] = { 'a', 't', 'r', 'i', 'c', 'e', 's' };
+static const symbol s_4_17[5] = { 'a', 'n', 'c', 'e', 's' };
+static const symbol s_4_18[5] = { 'e', 'n', 'c', 'e', 's' };
+static const symbol s_4_19[6] = { 'l', 'o', 'g', 'i', 'e', 's' };
+static const symbol s_4_20[5] = { 'a', 'b', 'l', 'e', 's' };
+static const symbol s_4_21[5] = { 'i', 's', 'm', 'e', 's' };
+static const symbol s_4_22[5] = { 'e', 'u', 's', 'e', 's' };
+static const symbol s_4_23[5] = { 'i', 's', 't', 'e', 's' };
+static const symbol s_4_24[4] = { 'i', 'v', 'e', 's' };
+static const symbol s_4_25[3] = { 'i', 'f', 's' };
+static const symbol s_4_26[6] = { 'u', 's', 'i', 'o', 'n', 's' };
+static const symbol s_4_27[6] = { 'a', 't', 'i', 'o', 'n', 's' };
+static const symbol s_4_28[6] = { 'u', 't', 'i', 'o', 'n', 's' };
+static const symbol s_4_29[6] = { 'a', 't', 'e', 'u', 'r', 's' };
+static const symbol s_4_30[5] = { 'm', 'e', 'n', 't', 's' };
+static const symbol s_4_31[6] = { 'e', 'm', 'e', 'n', 't', 's' };
+static const symbol s_4_32[9] = { 'i', 's', 's', 'e', 'm', 'e', 'n', 't', 's' };
+static const symbol s_4_33[5] = { 'i', 't', 0xC3, 0xA9, 's' };
+static const symbol s_4_34[4] = { 'm', 'e', 'n', 't' };
+static const symbol s_4_35[5] = { 'e', 'm', 'e', 'n', 't' };
+static const symbol s_4_36[8] = { 'i', 's', 's', 'e', 'm', 'e', 'n', 't' };
+static const symbol s_4_37[6] = { 'a', 'm', 'm', 'e', 'n', 't' };
+static const symbol s_4_38[6] = { 'e', 'm', 'm', 'e', 'n', 't' };
+static const symbol s_4_39[3] = { 'a', 'u', 'x' };
+static const symbol s_4_40[4] = { 'e', 'a', 'u', 'x' };
+static const symbol s_4_41[3] = { 'e', 'u', 'x' };
+static const symbol s_4_42[4] = { 'i', 't', 0xC3, 0xA9 };
+
+static const struct among a_4[43] =
+{
+/* 0 */ { 4, s_4_0, -1, 1, 0},
+/* 1 */ { 6, s_4_1, -1, 2, 0},
+/* 2 */ { 4, s_4_2, -1, 1, 0},
+/* 3 */ { 4, s_4_3, -1, 5, 0},
+/* 4 */ { 5, s_4_4, -1, 3, 0},
+/* 5 */ { 4, s_4_5, -1, 1, 0},
+/* 6 */ { 4, s_4_6, -1, 1, 0},
+/* 7 */ { 4, s_4_7, -1, 11, 0},
+/* 8 */ { 4, s_4_8, -1, 1, 0},
+/* 9 */ { 3, s_4_9, -1, 8, 0},
+/* 10 */ { 2, s_4_10, -1, 8, 0},
+/* 11 */ { 5, s_4_11, -1, 4, 0},
+/* 12 */ { 5, s_4_12, -1, 2, 0},
+/* 13 */ { 5, s_4_13, -1, 4, 0},
+/* 14 */ { 5, s_4_14, -1, 2, 0},
+/* 15 */ { 5, s_4_15, -1, 1, 0},
+/* 16 */ { 7, s_4_16, -1, 2, 0},
+/* 17 */ { 5, s_4_17, -1, 1, 0},
+/* 18 */ { 5, s_4_18, -1, 5, 0},
+/* 19 */ { 6, s_4_19, -1, 3, 0},
+/* 20 */ { 5, s_4_20, -1, 1, 0},
+/* 21 */ { 5, s_4_21, -1, 1, 0},
+/* 22 */ { 5, s_4_22, -1, 11, 0},
+/* 23 */ { 5, s_4_23, -1, 1, 0},
+/* 24 */ { 4, s_4_24, -1, 8, 0},
+/* 25 */ { 3, s_4_25, -1, 8, 0},
+/* 26 */ { 6, s_4_26, -1, 4, 0},
+/* 27 */ { 6, s_4_27, -1, 2, 0},
+/* 28 */ { 6, s_4_28, -1, 4, 0},
+/* 29 */ { 6, s_4_29, -1, 2, 0},
+/* 30 */ { 5, s_4_30, -1, 15, 0},
+/* 31 */ { 6, s_4_31, 30, 6, 0},
+/* 32 */ { 9, s_4_32, 31, 12, 0},
+/* 33 */ { 5, s_4_33, -1, 7, 0},
+/* 34 */ { 4, s_4_34, -1, 15, 0},
+/* 35 */ { 5, s_4_35, 34, 6, 0},
+/* 36 */ { 8, s_4_36, 35, 12, 0},
+/* 37 */ { 6, s_4_37, 34, 13, 0},
+/* 38 */ { 6, s_4_38, 34, 14, 0},
+/* 39 */ { 3, s_4_39, -1, 10, 0},
+/* 40 */ { 4, s_4_40, 39, 9, 0},
+/* 41 */ { 3, s_4_41, -1, 1, 0},
+/* 42 */ { 4, s_4_42, -1, 7, 0}
+};
+
+static const symbol s_5_0[3] = { 'i', 'r', 'a' };
+static const symbol s_5_1[2] = { 'i', 'e' };
+static const symbol s_5_2[4] = { 'i', 's', 's', 'e' };
+static const symbol s_5_3[7] = { 'i', 's', 's', 'a', 'n', 't', 'e' };
+static const symbol s_5_4[1] = { 'i' };
+static const symbol s_5_5[4] = { 'i', 'r', 'a', 'i' };
+static const symbol s_5_6[2] = { 'i', 'r' };
+static const symbol s_5_7[4] = { 'i', 'r', 'a', 's' };
+static const symbol s_5_8[3] = { 'i', 'e', 's' };
+static const symbol s_5_9[5] = { 0xC3, 0xAE, 'm', 'e', 's' };
+static const symbol s_5_10[5] = { 'i', 's', 's', 'e', 's' };
+static const symbol s_5_11[8] = { 'i', 's', 's', 'a', 'n', 't', 'e', 's' };
+static const symbol s_5_12[5] = { 0xC3, 0xAE, 't', 'e', 's' };
+static const symbol s_5_13[2] = { 'i', 's' };
+static const symbol s_5_14[5] = { 'i', 'r', 'a', 'i', 's' };
+static const symbol s_5_15[6] = { 'i', 's', 's', 'a', 'i', 's' };
+static const symbol s_5_16[6] = { 'i', 'r', 'i', 'o', 'n', 's' };
+static const symbol s_5_17[7] = { 'i', 's', 's', 'i', 'o', 'n', 's' };
+static const symbol s_5_18[5] = { 'i', 'r', 'o', 'n', 's' };
+static const symbol s_5_19[6] = { 'i', 's', 's', 'o', 'n', 's' };
+static const symbol s_5_20[7] = { 'i', 's', 's', 'a', 'n', 't', 's' };
+static const symbol s_5_21[2] = { 'i', 't' };
+static const symbol s_5_22[5] = { 'i', 'r', 'a', 'i', 't' };
+static const symbol s_5_23[6] = { 'i', 's', 's', 'a', 'i', 't' };
+static const symbol s_5_24[6] = { 'i', 's', 's', 'a', 'n', 't' };
+static const symbol s_5_25[7] = { 'i', 'r', 'a', 'I', 'e', 'n', 't' };
+static const symbol s_5_26[8] = { 'i', 's', 's', 'a', 'I', 'e', 'n', 't' };
+static const symbol s_5_27[5] = { 'i', 'r', 'e', 'n', 't' };
+static const symbol s_5_28[6] = { 'i', 's', 's', 'e', 'n', 't' };
+static const symbol s_5_29[5] = { 'i', 'r', 'o', 'n', 't' };
+static const symbol s_5_30[3] = { 0xC3, 0xAE, 't' };
+static const symbol s_5_31[5] = { 'i', 'r', 'i', 'e', 'z' };
+static const symbol s_5_32[6] = { 'i', 's', 's', 'i', 'e', 'z' };
+static const symbol s_5_33[4] = { 'i', 'r', 'e', 'z' };
+static const symbol s_5_34[5] = { 'i', 's', 's', 'e', 'z' };
+
+static const struct among a_5[35] =
+{
+/* 0 */ { 3, s_5_0, -1, 1, 0},
+/* 1 */ { 2, s_5_1, -1, 1, 0},
+/* 2 */ { 4, s_5_2, -1, 1, 0},
+/* 3 */ { 7, s_5_3, -1, 1, 0},
+/* 4 */ { 1, s_5_4, -1, 1, 0},
+/* 5 */ { 4, s_5_5, 4, 1, 0},
+/* 6 */ { 2, s_5_6, -1, 1, 0},
+/* 7 */ { 4, s_5_7, -1, 1, 0},
+/* 8 */ { 3, s_5_8, -1, 1, 0},
+/* 9 */ { 5, s_5_9, -1, 1, 0},
+/* 10 */ { 5, s_5_10, -1, 1, 0},
+/* 11 */ { 8, s_5_11, -1, 1, 0},
+/* 12 */ { 5, s_5_12, -1, 1, 0},
+/* 13 */ { 2, s_5_13, -1, 1, 0},
+/* 14 */ { 5, s_5_14, 13, 1, 0},
+/* 15 */ { 6, s_5_15, 13, 1, 0},
+/* 16 */ { 6, s_5_16, -1, 1, 0},
+/* 17 */ { 7, s_5_17, -1, 1, 0},
+/* 18 */ { 5, s_5_18, -1, 1, 0},
+/* 19 */ { 6, s_5_19, -1, 1, 0},
+/* 20 */ { 7, s_5_20, -1, 1, 0},
+/* 21 */ { 2, s_5_21, -1, 1, 0},
+/* 22 */ { 5, s_5_22, 21, 1, 0},
+/* 23 */ { 6, s_5_23, 21, 1, 0},
+/* 24 */ { 6, s_5_24, -1, 1, 0},
+/* 25 */ { 7, s_5_25, -1, 1, 0},
+/* 26 */ { 8, s_5_26, -1, 1, 0},
+/* 27 */ { 5, s_5_27, -1, 1, 0},
+/* 28 */ { 6, s_5_28, -1, 1, 0},
+/* 29 */ { 5, s_5_29, -1, 1, 0},
+/* 30 */ { 3, s_5_30, -1, 1, 0},
+/* 31 */ { 5, s_5_31, -1, 1, 0},
+/* 32 */ { 6, s_5_32, -1, 1, 0},
+/* 33 */ { 4, s_5_33, -1, 1, 0},
+/* 34 */ { 5, s_5_34, -1, 1, 0}
+};
+
+static const symbol s_6_0[1] = { 'a' };
+static const symbol s_6_1[3] = { 'e', 'r', 'a' };
+static const symbol s_6_2[4] = { 'a', 's', 's', 'e' };
+static const symbol s_6_3[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_6_4[3] = { 0xC3, 0xA9, 'e' };
+static const symbol s_6_5[2] = { 'a', 'i' };
+static const symbol s_6_6[4] = { 'e', 'r', 'a', 'i' };
+static const symbol s_6_7[2] = { 'e', 'r' };
+static const symbol s_6_8[2] = { 'a', 's' };
+static const symbol s_6_9[4] = { 'e', 'r', 'a', 's' };
+static const symbol s_6_10[5] = { 0xC3, 0xA2, 'm', 'e', 's' };
+static const symbol s_6_11[5] = { 'a', 's', 's', 'e', 's' };
+static const symbol s_6_12[5] = { 'a', 'n', 't', 'e', 's' };
+static const symbol s_6_13[5] = { 0xC3, 0xA2, 't', 'e', 's' };
+static const symbol s_6_14[4] = { 0xC3, 0xA9, 'e', 's' };
+static const symbol s_6_15[3] = { 'a', 'i', 's' };
+static const symbol s_6_16[5] = { 'e', 'r', 'a', 'i', 's' };
+static const symbol s_6_17[4] = { 'i', 'o', 'n', 's' };
+static const symbol s_6_18[6] = { 'e', 'r', 'i', 'o', 'n', 's' };
+static const symbol s_6_19[7] = { 'a', 's', 's', 'i', 'o', 'n', 's' };
+static const symbol s_6_20[5] = { 'e', 'r', 'o', 'n', 's' };
+static const symbol s_6_21[4] = { 'a', 'n', 't', 's' };
+static const symbol s_6_22[3] = { 0xC3, 0xA9, 's' };
+static const symbol s_6_23[3] = { 'a', 'i', 't' };
+static const symbol s_6_24[5] = { 'e', 'r', 'a', 'i', 't' };
+static const symbol s_6_25[3] = { 'a', 'n', 't' };
+static const symbol s_6_26[5] = { 'a', 'I', 'e', 'n', 't' };
+static const symbol s_6_27[7] = { 'e', 'r', 'a', 'I', 'e', 'n', 't' };
+static const symbol s_6_28[6] = { 0xC3, 0xA8, 'r', 'e', 'n', 't' };
+static const symbol s_6_29[6] = { 'a', 's', 's', 'e', 'n', 't' };
+static const symbol s_6_30[5] = { 'e', 'r', 'o', 'n', 't' };
+static const symbol s_6_31[3] = { 0xC3, 0xA2, 't' };
+static const symbol s_6_32[2] = { 'e', 'z' };
+static const symbol s_6_33[3] = { 'i', 'e', 'z' };
+static const symbol s_6_34[5] = { 'e', 'r', 'i', 'e', 'z' };
+static const symbol s_6_35[6] = { 'a', 's', 's', 'i', 'e', 'z' };
+static const symbol s_6_36[4] = { 'e', 'r', 'e', 'z' };
+static const symbol s_6_37[2] = { 0xC3, 0xA9 };
+
+static const struct among a_6[38] =
+{
+/* 0 */ { 1, s_6_0, -1, 3, 0},
+/* 1 */ { 3, s_6_1, 0, 2, 0},
+/* 2 */ { 4, s_6_2, -1, 3, 0},
+/* 3 */ { 4, s_6_3, -1, 3, 0},
+/* 4 */ { 3, s_6_4, -1, 2, 0},
+/* 5 */ { 2, s_6_5, -1, 3, 0},
+/* 6 */ { 4, s_6_6, 5, 2, 0},
+/* 7 */ { 2, s_6_7, -1, 2, 0},
+/* 8 */ { 2, s_6_8, -1, 3, 0},
+/* 9 */ { 4, s_6_9, 8, 2, 0},
+/* 10 */ { 5, s_6_10, -1, 3, 0},
+/* 11 */ { 5, s_6_11, -1, 3, 0},
+/* 12 */ { 5, s_6_12, -1, 3, 0},
+/* 13 */ { 5, s_6_13, -1, 3, 0},
+/* 14 */ { 4, s_6_14, -1, 2, 0},
+/* 15 */ { 3, s_6_15, -1, 3, 0},
+/* 16 */ { 5, s_6_16, 15, 2, 0},
+/* 17 */ { 4, s_6_17, -1, 1, 0},
+/* 18 */ { 6, s_6_18, 17, 2, 0},
+/* 19 */ { 7, s_6_19, 17, 3, 0},
+/* 20 */ { 5, s_6_20, -1, 2, 0},
+/* 21 */ { 4, s_6_21, -1, 3, 0},
+/* 22 */ { 3, s_6_22, -1, 2, 0},
+/* 23 */ { 3, s_6_23, -1, 3, 0},
+/* 24 */ { 5, s_6_24, 23, 2, 0},
+/* 25 */ { 3, s_6_25, -1, 3, 0},
+/* 26 */ { 5, s_6_26, -1, 3, 0},
+/* 27 */ { 7, s_6_27, 26, 2, 0},
+/* 28 */ { 6, s_6_28, -1, 2, 0},
+/* 29 */ { 6, s_6_29, -1, 3, 0},
+/* 30 */ { 5, s_6_30, -1, 2, 0},
+/* 31 */ { 3, s_6_31, -1, 3, 0},
+/* 32 */ { 2, s_6_32, -1, 2, 0},
+/* 33 */ { 3, s_6_33, 32, 2, 0},
+/* 34 */ { 5, s_6_34, 33, 2, 0},
+/* 35 */ { 6, s_6_35, 33, 3, 0},
+/* 36 */ { 4, s_6_36, 32, 2, 0},
+/* 37 */ { 2, s_6_37, -1, 2, 0}
+};
+
+static const symbol s_7_0[1] = { 'e' };
+static const symbol s_7_1[5] = { 'I', 0xC3, 0xA8, 'r', 'e' };
+static const symbol s_7_2[5] = { 'i', 0xC3, 0xA8, 'r', 'e' };
+static const symbol s_7_3[3] = { 'i', 'o', 'n' };
+static const symbol s_7_4[3] = { 'I', 'e', 'r' };
+static const symbol s_7_5[3] = { 'i', 'e', 'r' };
+static const symbol s_7_6[2] = { 0xC3, 0xAB };
+
+static const struct among a_7[7] =
+{
+/* 0 */ { 1, s_7_0, -1, 3, 0},
+/* 1 */ { 5, s_7_1, 0, 2, 0},
+/* 2 */ { 5, s_7_2, 0, 2, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0},
+/* 4 */ { 3, s_7_4, -1, 2, 0},
+/* 5 */ { 3, s_7_5, -1, 2, 0},
+/* 6 */ { 2, s_7_6, -1, 4, 0}
+};
+
+static const symbol s_8_0[3] = { 'e', 'l', 'l' };
+static const symbol s_8_1[4] = { 'e', 'i', 'l', 'l' };
+static const symbol s_8_2[3] = { 'e', 'n', 'n' };
+static const symbol s_8_3[3] = { 'o', 'n', 'n' };
+static const symbol s_8_4[3] = { 'e', 't', 't' };
+
+static const struct among a_8[5] =
+{
+/* 0 */ { 3, s_8_0, -1, -1, 0},
+/* 1 */ { 4, s_8_1, -1, -1, 0},
+/* 2 */ { 3, s_8_2, -1, -1, 0},
+/* 3 */ { 3, s_8_3, -1, -1, 0},
+/* 4 */ { 3, s_8_4, -1, -1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 130, 103, 8, 5 };
+
+static const unsigned char g_keep_with_s[] = { 1, 65, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 };
+
+static const symbol s_0[] = { 'u' };
+static const symbol s_1[] = { 'U' };
+static const symbol s_2[] = { 'i' };
+static const symbol s_3[] = { 'I' };
+static const symbol s_4[] = { 'y' };
+static const symbol s_5[] = { 'Y' };
+static const symbol s_6[] = { 'y' };
+static const symbol s_7[] = { 'Y' };
+static const symbol s_8[] = { 'q' };
+static const symbol s_9[] = { 'u' };
+static const symbol s_10[] = { 'U' };
+static const symbol s_11[] = { 'i' };
+static const symbol s_12[] = { 'u' };
+static const symbol s_13[] = { 'y' };
+static const symbol s_14[] = { 'i', 'c' };
+static const symbol s_15[] = { 'i', 'q', 'U' };
+static const symbol s_16[] = { 'l', 'o', 'g' };
+static const symbol s_17[] = { 'u' };
+static const symbol s_18[] = { 'e', 'n', 't' };
+static const symbol s_19[] = { 'a', 't' };
+static const symbol s_20[] = { 'e', 'u', 'x' };
+static const symbol s_21[] = { 'i' };
+static const symbol s_22[] = { 'a', 'b', 'l' };
+static const symbol s_23[] = { 'i', 'q', 'U' };
+static const symbol s_24[] = { 'a', 't' };
+static const symbol s_25[] = { 'i', 'c' };
+static const symbol s_26[] = { 'i', 'q', 'U' };
+static const symbol s_27[] = { 'e', 'a', 'u' };
+static const symbol s_28[] = { 'a', 'l' };
+static const symbol s_29[] = { 'e', 'u', 'x' };
+static const symbol s_30[] = { 'a', 'n', 't' };
+static const symbol s_31[] = { 'e', 'n', 't' };
+static const symbol s_32[] = { 'e' };
+static const symbol s_33[] = { 's' };
+static const symbol s_34[] = { 's' };
+static const symbol s_35[] = { 't' };
+static const symbol s_36[] = { 'i' };
+static const symbol s_37[] = { 'g', 'u' };
+static const symbol s_38[] = { 0xC3, 0xA9 };
+static const symbol s_39[] = { 0xC3, 0xA8 };
+static const symbol s_40[] = { 'e' };
+static const symbol s_41[] = { 'Y' };
+static const symbol s_42[] = { 'i' };
+static const symbol s_43[] = { 0xC3, 0xA7 };
+static const symbol s_44[] = { 'c' };
+
+static int r_prelude(struct SN_env * z) {
+ while(1) { /* repeat, line 38 */
+ int c1 = z->c;
+ while(1) { /* goto, line 38 */
+ int c2 = z->c;
+ { int c3 = z->c; /* or, line 44 */
+ if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab3;
+ z->bra = z->c; /* [, line 40 */
+ { int c4 = z->c; /* or, line 40 */
+ if (!(eq_s(z, 1, s_0))) goto lab5;
+ z->ket = z->c; /* ], line 40 */
+ if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab5;
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 40 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab5:
+ z->c = c4;
+ if (!(eq_s(z, 1, s_2))) goto lab6;
+ z->ket = z->c; /* ], line 41 */
+ if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab6;
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 41 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab6:
+ z->c = c4;
+ if (!(eq_s(z, 1, s_4))) goto lab3;
+ z->ket = z->c; /* ], line 42 */
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 42 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab4:
+ goto lab2;
+ lab3:
+ z->c = c3;
+ z->bra = z->c; /* [, line 45 */
+ if (!(eq_s(z, 1, s_6))) goto lab7;
+ z->ket = z->c; /* ], line 45 */
+ if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab7;
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 45 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab7:
+ z->c = c3;
+ if (!(eq_s(z, 1, s_8))) goto lab1;
+ z->bra = z->c; /* [, line 47 */
+ if (!(eq_s(z, 1, s_9))) goto lab1;
+ z->ket = z->c; /* ], line 47 */
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 47 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab2:
+ z->c = c2;
+ break;
+ lab1:
+ z->c = c2;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* goto, line 38 */
+ }
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 56 */
+ { int c2 = z->c; /* or, line 58 */
+ if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2;
+ if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab2;
+ z->c = ret; /* next, line 57 */
+ }
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3;
+ if (!(find_among(z, a_0, 3))) goto lab3; /* among, line 59 */
+ goto lab1;
+ lab3:
+ z->c = c2;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 66 */
+ }
+ { /* gopast */ /* grouping v, line 66 */
+ int ret = out_grouping_U(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 67 */
+ lab0:
+ z->c = c1;
+ }
+ { int c3 = z->c; /* do, line 69 */
+ { /* gopast */ /* grouping v, line 70 */
+ int ret = out_grouping_U(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 70 */
+ int ret = in_grouping_U(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 70 */
+ { /* gopast */ /* grouping v, line 71 */
+ int ret = out_grouping_U(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 71 */
+ int ret = in_grouping_U(z, g_v, 97, 251, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 71 */
+ lab4:
+ z->c = c3;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 75 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 77 */
+ if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652096 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 4; else
+ among_var = find_among(z, a_1, 4); /* substring, line 77 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 77 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_11); /* <-, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_12); /* <-, line 79 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 80 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 81 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 92 */
+ among_var = find_among_b(z, a_4, 43); /* substring, line 92 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 92 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 96 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 96 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 99 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 99 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 100 */
+ z->ket = z->c; /* [, line 100 */
+ if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 100 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 100 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab2; /* call R2, line 100 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 100 */
+ if (ret < 0) return ret;
+ }
+ goto lab1;
+ lab2:
+ z->c = z->l - m1;
+ { int ret = slice_from_s(z, 3, s_15); /* <-, line 100 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab1:
+ lab0:
+ ;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 104 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_16); /* <-, line 104 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 107 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_17); /* <-, line 107 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_18); /* <-, line 110 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 114 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 114 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 115 */
+ z->ket = z->c; /* [, line 116 */
+ among_var = find_among_b(z, a_2, 6); /* substring, line 116 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 116 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab3; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 117 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 117 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 117 */
+ if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 117 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 117 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 117 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m2 = z->l - z->c; (void)m2; /* or, line 118 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab5; /* call R2, line 118 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 118 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab5:
+ z->c = z->l - m2;
+ { int ret = r_R1(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R1, line 118 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_20); /* <-, line 118 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab4:
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 120 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 120 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call RV, line 122 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_21); /* <-, line 122 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab3:
+ ;
+ }
+ break;
+ case 7:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 129 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 129 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 130 */
+ z->ket = z->c; /* [, line 131 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab6; }
+ among_var = find_among_b(z, a_3, 3); /* substring, line 131 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab6; }
+ z->bra = z->c; /* ], line 131 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab6; }
+ case 1:
+ { int m3 = z->l - z->c; (void)m3; /* or, line 132 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab8; /* call R2, line 132 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 132 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab8:
+ z->c = z->l - m3;
+ { int ret = slice_from_s(z, 3, s_22); /* <-, line 132 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab7:
+ break;
+ case 2:
+ { int m4 = z->l - z->c; (void)m4; /* or, line 133 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab10; /* call R2, line 133 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 133 */
+ if (ret < 0) return ret;
+ }
+ goto lab9;
+ lab10:
+ z->c = z->l - m4;
+ { int ret = slice_from_s(z, 3, s_23); /* <-, line 133 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab9:
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call R2, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab6:
+ ;
+ }
+ break;
+ case 8:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 141 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 141 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 142 */
+ z->ket = z->c; /* [, line 142 */
+ if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m_keep; goto lab11; }
+ z->bra = z->c; /* ], line 142 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab11; } /* call R2, line 142 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 142 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 142 */
+ if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m_keep; goto lab11; }
+ z->bra = z->c; /* ], line 142 */
+ { int m5 = z->l - z->c; (void)m5; /* or, line 142 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab13; /* call R2, line 142 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 142 */
+ if (ret < 0) return ret;
+ }
+ goto lab12;
+ lab13:
+ z->c = z->l - m5;
+ { int ret = slice_from_s(z, 3, s_26); /* <-, line 142 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab12:
+ lab11:
+ ;
+ }
+ break;
+ case 9:
+ { int ret = slice_from_s(z, 3, s_27); /* <-, line 144 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 145 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 2, s_28); /* <-, line 145 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int m6 = z->l - z->c; (void)m6; /* or, line 147 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab15; /* call R2, line 147 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 147 */
+ if (ret < 0) return ret;
+ }
+ goto lab14;
+ lab15:
+ z->c = z->l - m6;
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 147 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_29); /* <-, line 147 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab14:
+ break;
+ case 12:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 150 */
+ if (ret < 0) return ret;
+ }
+ if (out_grouping_b_U(z, g_v, 97, 251, 0)) return 0;
+ { int ret = slice_del(z); /* delete, line 150 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 155 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_30); /* <-, line 155 */
+ if (ret < 0) return ret;
+ }
+ return 0; /* fail, line 155 */
+ break;
+ case 14:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 156 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_31); /* <-, line 156 */
+ if (ret < 0) return ret;
+ }
+ return 0; /* fail, line 156 */
+ break;
+ case 15:
+ { int m_test = z->l - z->c; /* test, line 158 */
+ if (in_grouping_b_U(z, g_v, 97, 251, 0)) return 0;
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 158 */
+ if (ret < 0) return ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 158 */
+ if (ret < 0) return ret;
+ }
+ return 0; /* fail, line 158 */
+ break;
+ }
+ return 1;
+}
+
+static int r_i_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 163 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 163 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 164 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_5, 35); /* substring, line 164 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 164 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ if (out_grouping_b_U(z, g_v, 97, 251, 0)) { z->lb = mlimit; return 0; }
+ { int ret = slice_del(z); /* delete, line 170 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 174 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 174 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 175 */
+ among_var = find_among_b(z, a_6, 38); /* substring, line 175 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 175 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->lb = mlimit; return 0; } /* call R2, line 177 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 177 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 185 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 190 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 191 */
+ z->ket = z->c; /* [, line 191 */
+ if (!(eq_s_b(z, 1, s_32))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 191 */
+ { int ret = slice_del(z); /* delete, line 191 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_residual_suffix(struct SN_env * z) {
+ int among_var;
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 199 */
+ z->ket = z->c; /* [, line 199 */
+ if (!(eq_s_b(z, 1, s_33))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 199 */
+ { int m_test = z->l - z->c; /* test, line 199 */
+ if (out_grouping_b_U(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m_keep; goto lab0; }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 199 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ { int mlimit; /* setlimit, line 200 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 200 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 201 */
+ among_var = find_among_b(z, a_7, 7); /* substring, line 201 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 201 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->lb = mlimit; return 0; } /* call R2, line 202 */
+ if (ret < 0) return ret;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* or, line 202 */
+ if (!(eq_s_b(z, 1, s_34))) goto lab2;
+ goto lab1;
+ lab2:
+ z->c = z->l - m2;
+ if (!(eq_s_b(z, 1, s_35))) { z->lb = mlimit; return 0; }
+ }
+ lab1:
+ { int ret = slice_del(z); /* delete, line 202 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_36); /* <-, line 204 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 205 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ if (!(eq_s_b(z, 2, s_37))) { z->lb = mlimit; return 0; }
+ { int ret = slice_del(z); /* delete, line 206 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_un_double(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 212 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_8, 5))) return 0; /* among, line 212 */
+ z->c = z->l - m_test;
+ }
+ z->ket = z->c; /* [, line 212 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 212 */
+ }
+ z->bra = z->c; /* ], line 212 */
+ { int ret = slice_del(z); /* delete, line 212 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_un_accent(struct SN_env * z) {
+ { int i = 1;
+ while(1) { /* atleast, line 216 */
+ if (out_grouping_b_U(z, g_v, 97, 251, 0)) goto lab0;
+ i--;
+ continue;
+ lab0:
+ break;
+ }
+ if (i > 0) return 0;
+ }
+ z->ket = z->c; /* [, line 217 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 217 */
+ if (!(eq_s_b(z, 2, s_38))) goto lab2;
+ goto lab1;
+ lab2:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 2, s_39))) return 0;
+ }
+lab1:
+ z->bra = z->c; /* ], line 217 */
+ { int ret = slice_from_s(z, 1, s_40); /* <-, line 217 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern int french_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 223 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 223 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 224 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 224 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 225 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 227 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 237 */
+ { int m5 = z->l - z->c; (void)m5; /* and, line 233 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 229 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab6; /* call standard_suffix, line 229 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int ret = r_i_verb_suffix(z);
+ if (ret == 0) goto lab7; /* call i_verb_suffix, line 230 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab7:
+ z->c = z->l - m6;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab4; /* call verb_suffix, line 231 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ z->c = z->l - m5;
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 234 */
+ z->ket = z->c; /* [, line 234 */
+ { int m7 = z->l - z->c; (void)m7; /* or, line 234 */
+ if (!(eq_s_b(z, 1, s_41))) goto lab10;
+ z->bra = z->c; /* ], line 234 */
+ { int ret = slice_from_s(z, 1, s_42); /* <-, line 234 */
+ if (ret < 0) return ret;
+ }
+ goto lab9;
+ lab10:
+ z->c = z->l - m7;
+ if (!(eq_s_b(z, 2, s_43))) { z->c = z->l - m_keep; goto lab8; }
+ z->bra = z->c; /* ], line 235 */
+ { int ret = slice_from_s(z, 1, s_44); /* <-, line 235 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab9:
+ lab8:
+ ;
+ }
+ }
+ goto lab3;
+ lab4:
+ z->c = z->l - m4;
+ { int ret = r_residual_suffix(z);
+ if (ret == 0) goto lab2; /* call residual_suffix, line 238 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab3:
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 243 */
+ { int ret = r_un_double(z);
+ if (ret == 0) goto lab11; /* call un_double, line 243 */
+ if (ret < 0) return ret;
+ }
+ lab11:
+ z->c = z->l - m8;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 244 */
+ { int ret = r_un_accent(z);
+ if (ret == 0) goto lab12; /* call un_accent, line 244 */
+ if (ret < 0) return ret;
+ }
+ lab12:
+ z->c = z->l - m9;
+ }
+ z->c = z->lb;
+ { int c10 = z->c; /* do, line 246 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab13; /* call postlude, line 246 */
+ if (ret < 0) return ret;
+ }
+ lab13:
+ z->c = c10;
+ }
+ return 1;
+}
+
+extern struct SN_env * french_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void french_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_german.c b/src/backend/snowball/libstemmer/stem_UTF_8_german.c
new file mode 100644
index 00000000000..5d406e50921
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_german.c
@@ -0,0 +1,509 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int german_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_standard_suffix(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * german_UTF_8_create_env(void);
+extern void german_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[1] = { 'U' };
+static const symbol s_0_2[1] = { 'Y' };
+static const symbol s_0_3[2] = { 0xC3, 0xA4 };
+static const symbol s_0_4[2] = { 0xC3, 0xB6 };
+static const symbol s_0_5[2] = { 0xC3, 0xBC };
+
+static const struct among a_0[6] =
+{
+/* 0 */ { 0, 0, -1, 6, 0},
+/* 1 */ { 1, s_0_1, 0, 2, 0},
+/* 2 */ { 1, s_0_2, 0, 1, 0},
+/* 3 */ { 2, s_0_3, 0, 3, 0},
+/* 4 */ { 2, s_0_4, 0, 4, 0},
+/* 5 */ { 2, s_0_5, 0, 5, 0}
+};
+
+static const symbol s_1_0[1] = { 'e' };
+static const symbol s_1_1[2] = { 'e', 'm' };
+static const symbol s_1_2[2] = { 'e', 'n' };
+static const symbol s_1_3[3] = { 'e', 'r', 'n' };
+static const symbol s_1_4[2] = { 'e', 'r' };
+static const symbol s_1_5[1] = { 's' };
+static const symbol s_1_6[2] = { 'e', 's' };
+
+static const struct among a_1[7] =
+{
+/* 0 */ { 1, s_1_0, -1, 1, 0},
+/* 1 */ { 2, s_1_1, -1, 1, 0},
+/* 2 */ { 2, s_1_2, -1, 1, 0},
+/* 3 */ { 3, s_1_3, -1, 1, 0},
+/* 4 */ { 2, s_1_4, -1, 1, 0},
+/* 5 */ { 1, s_1_5, -1, 2, 0},
+/* 6 */ { 2, s_1_6, 5, 1, 0}
+};
+
+static const symbol s_2_0[2] = { 'e', 'n' };
+static const symbol s_2_1[2] = { 'e', 'r' };
+static const symbol s_2_2[2] = { 's', 't' };
+static const symbol s_2_3[3] = { 'e', 's', 't' };
+
+static const struct among a_2[4] =
+{
+/* 0 */ { 2, s_2_0, -1, 1, 0},
+/* 1 */ { 2, s_2_1, -1, 1, 0},
+/* 2 */ { 2, s_2_2, -1, 2, 0},
+/* 3 */ { 3, s_2_3, 2, 1, 0}
+};
+
+static const symbol s_3_0[2] = { 'i', 'g' };
+static const symbol s_3_1[4] = { 'l', 'i', 'c', 'h' };
+
+static const struct among a_3[2] =
+{
+/* 0 */ { 2, s_3_0, -1, 1, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0}
+};
+
+static const symbol s_4_0[3] = { 'e', 'n', 'd' };
+static const symbol s_4_1[2] = { 'i', 'g' };
+static const symbol s_4_2[3] = { 'u', 'n', 'g' };
+static const symbol s_4_3[4] = { 'l', 'i', 'c', 'h' };
+static const symbol s_4_4[4] = { 'i', 's', 'c', 'h' };
+static const symbol s_4_5[2] = { 'i', 'k' };
+static const symbol s_4_6[4] = { 'h', 'e', 'i', 't' };
+static const symbol s_4_7[4] = { 'k', 'e', 'i', 't' };
+
+static const struct among a_4[8] =
+{
+/* 0 */ { 3, s_4_0, -1, 1, 0},
+/* 1 */ { 2, s_4_1, -1, 2, 0},
+/* 2 */ { 3, s_4_2, -1, 1, 0},
+/* 3 */ { 4, s_4_3, -1, 3, 0},
+/* 4 */ { 4, s_4_4, -1, 2, 0},
+/* 5 */ { 2, s_4_5, -1, 2, 0},
+/* 6 */ { 4, s_4_6, -1, 3, 0},
+/* 7 */ { 4, s_4_7, -1, 4, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8 };
+
+static const unsigned char g_s_ending[] = { 117, 30, 5 };
+
+static const unsigned char g_st_ending[] = { 117, 30, 4 };
+
+static const symbol s_0[] = { 0xC3, 0x9F };
+static const symbol s_1[] = { 's', 's' };
+static const symbol s_2[] = { 'u' };
+static const symbol s_3[] = { 'U' };
+static const symbol s_4[] = { 'y' };
+static const symbol s_5[] = { 'Y' };
+static const symbol s_6[] = { 'y' };
+static const symbol s_7[] = { 'u' };
+static const symbol s_8[] = { 'a' };
+static const symbol s_9[] = { 'o' };
+static const symbol s_10[] = { 'u' };
+static const symbol s_11[] = { 'i', 'g' };
+static const symbol s_12[] = { 'e' };
+static const symbol s_13[] = { 'e' };
+static const symbol s_14[] = { 'e', 'r' };
+static const symbol s_15[] = { 'e', 'n' };
+
+static int r_prelude(struct SN_env * z) {
+ { int c_test = z->c; /* test, line 30 */
+ while(1) { /* repeat, line 30 */
+ int c1 = z->c;
+ { int c2 = z->c; /* or, line 33 */
+ z->bra = z->c; /* [, line 32 */
+ if (!(eq_s(z, 2, s_0))) goto lab2;
+ z->ket = z->c; /* ], line 32 */
+ { int ret = slice_from_s(z, 2, s_1); /* <-, line 32 */
+ if (ret < 0) return ret;
+ }
+ goto lab1;
+ lab2:
+ z->c = c2;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 33 */
+ }
+ }
+ lab1:
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ z->c = c_test;
+ }
+ while(1) { /* repeat, line 36 */
+ int c3 = z->c;
+ while(1) { /* goto, line 36 */
+ int c4 = z->c;
+ if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4;
+ z->bra = z->c; /* [, line 37 */
+ { int c5 = z->c; /* or, line 37 */
+ if (!(eq_s(z, 1, s_2))) goto lab6;
+ z->ket = z->c; /* ], line 37 */
+ if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab6;
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 37 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c5;
+ if (!(eq_s(z, 1, s_4))) goto lab4;
+ z->ket = z->c; /* ], line 38 */
+ if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4;
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 38 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ z->c = c4;
+ break;
+ lab4:
+ z->c = c4;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab3;
+ z->c = ret; /* goto, line 36 */
+ }
+ }
+ continue;
+ lab3:
+ z->c = c3;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { int c_test = z->c; /* test, line 47 */
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3);
+ if (ret < 0) return 0;
+ z->c = ret; /* hop, line 47 */
+ }
+ z->I[2] = z->c; /* setmark x, line 47 */
+ z->c = c_test;
+ }
+ { /* gopast */ /* grouping v, line 49 */
+ int ret = out_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 49 */
+ int ret = in_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 49 */
+ /* try, line 50 */
+ if (!(z->I[0] < z->I[2])) goto lab0;
+ z->I[0] = z->I[2];
+lab0:
+ { /* gopast */ /* grouping v, line 51 */
+ int ret = out_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 51 */
+ int ret = in_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 51 */
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 55 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 57 */
+ among_var = find_among(z, a_0, 6); /* substring, line 57 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 57 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 58 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_8); /* <-, line 60 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_9); /* <-, line 61 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 62 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 63 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ { int m1 = z->l - z->c; (void)m1; /* do, line 74 */
+ z->ket = z->c; /* [, line 75 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0;
+ among_var = find_among_b(z, a_1, 7); /* substring, line 75 */
+ if (!(among_var)) goto lab0;
+ z->bra = z->c; /* ], line 75 */
+ { int ret = r_R1(z);
+ if (ret == 0) goto lab0; /* call R1, line 75 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (in_grouping_b_U(z, g_s_ending, 98, 116, 0)) goto lab0;
+ { int ret = slice_del(z); /* delete, line 80 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ z->c = z->l - m1;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* do, line 84 */
+ z->ket = z->c; /* [, line 85 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab1;
+ among_var = find_among_b(z, a_2, 4); /* substring, line 85 */
+ if (!(among_var)) goto lab1;
+ z->bra = z->c; /* ], line 85 */
+ { int ret = r_R1(z);
+ if (ret == 0) goto lab1; /* call R1, line 85 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: goto lab1;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 87 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (in_grouping_b_U(z, g_st_ending, 98, 116, 0)) goto lab1;
+ { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 3);
+ if (ret < 0) goto lab1;
+ z->c = ret; /* hop, line 90 */
+ }
+ { int ret = slice_del(z); /* delete, line 90 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 94 */
+ z->ket = z->c; /* [, line 95 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2;
+ among_var = find_among_b(z, a_4, 8); /* substring, line 95 */
+ if (!(among_var)) goto lab2;
+ z->bra = z->c; /* ], line 95 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab2; /* call R2, line 95 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: goto lab2;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 97 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 98 */
+ z->ket = z->c; /* [, line 98 */
+ if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 98 */
+ { int m4 = z->l - z->c; (void)m4; /* not, line 98 */
+ if (!(eq_s_b(z, 1, s_12))) goto lab4;
+ { z->c = z->l - m_keep; goto lab3; }
+ lab4:
+ z->c = z->l - m4;
+ }
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 98 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 98 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ ;
+ }
+ break;
+ case 2:
+ { int m5 = z->l - z->c; (void)m5; /* not, line 101 */
+ if (!(eq_s_b(z, 1, s_13))) goto lab5;
+ goto lab2;
+ lab5:
+ z->c = z->l - m5;
+ }
+ { int ret = slice_del(z); /* delete, line 101 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 104 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 105 */
+ z->ket = z->c; /* [, line 106 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 106 */
+ if (!(eq_s_b(z, 2, s_14))) goto lab8;
+ goto lab7;
+ lab8:
+ z->c = z->l - m6;
+ if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m_keep; goto lab6; }
+ }
+ lab7:
+ z->bra = z->c; /* ], line 106 */
+ { int ret = r_R1(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call R1, line 106 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 106 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ ;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */
+ z->ket = z->c; /* [, line 112 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m_keep; goto lab9; }
+ among_var = find_among_b(z, a_3, 2); /* substring, line 112 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab9; }
+ z->bra = z->c; /* ], line 112 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab9; } /* call R2, line 112 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab9; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 114 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab9:
+ ;
+ }
+ break;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ return 1;
+}
+
+extern int german_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 125 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 125 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 126 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 126 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 127 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 128 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab2; /* call standard_suffix, line 128 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ z->c = z->lb;
+ { int c4 = z->c; /* do, line 129 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab3; /* call postlude, line 129 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = c4;
+ }
+ return 1;
+}
+
+extern struct SN_env * german_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void german_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c b/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c
new file mode 100644
index 00000000000..e40df8e6c18
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c
@@ -0,0 +1,1234 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int hungarian_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_double(struct SN_env * z);
+static int r_undouble(struct SN_env * z);
+static int r_factive(struct SN_env * z);
+static int r_instrum(struct SN_env * z);
+static int r_plur_owner(struct SN_env * z);
+static int r_sing_owner(struct SN_env * z);
+static int r_owned(struct SN_env * z);
+static int r_plural(struct SN_env * z);
+static int r_case_other(struct SN_env * z);
+static int r_case_special(struct SN_env * z);
+static int r_case(struct SN_env * z);
+static int r_v_ending(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * hungarian_UTF_8_create_env(void);
+extern void hungarian_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[2] = { 'c', 's' };
+static const symbol s_0_1[3] = { 'd', 'z', 's' };
+static const symbol s_0_2[2] = { 'g', 'y' };
+static const symbol s_0_3[2] = { 'l', 'y' };
+static const symbol s_0_4[2] = { 'n', 'y' };
+static const symbol s_0_5[2] = { 's', 'z' };
+static const symbol s_0_6[2] = { 't', 'y' };
+static const symbol s_0_7[2] = { 'z', 's' };
+
+static const struct among a_0[8] =
+{
+/* 0 */ { 2, s_0_0, -1, -1, 0},
+/* 1 */ { 3, s_0_1, -1, -1, 0},
+/* 2 */ { 2, s_0_2, -1, -1, 0},
+/* 3 */ { 2, s_0_3, -1, -1, 0},
+/* 4 */ { 2, s_0_4, -1, -1, 0},
+/* 5 */ { 2, s_0_5, -1, -1, 0},
+/* 6 */ { 2, s_0_6, -1, -1, 0},
+/* 7 */ { 2, s_0_7, -1, -1, 0}
+};
+
+static const symbol s_1_0[2] = { 0xC3, 0xA1 };
+static const symbol s_1_1[2] = { 0xC3, 0xA9 };
+
+static const struct among a_1[2] =
+{
+/* 0 */ { 2, s_1_0, -1, 1, 0},
+/* 1 */ { 2, s_1_1, -1, 2, 0}
+};
+
+static const symbol s_2_0[2] = { 'b', 'b' };
+static const symbol s_2_1[2] = { 'c', 'c' };
+static const symbol s_2_2[2] = { 'd', 'd' };
+static const symbol s_2_3[2] = { 'f', 'f' };
+static const symbol s_2_4[2] = { 'g', 'g' };
+static const symbol s_2_5[2] = { 'j', 'j' };
+static const symbol s_2_6[2] = { 'k', 'k' };
+static const symbol s_2_7[2] = { 'l', 'l' };
+static const symbol s_2_8[2] = { 'm', 'm' };
+static const symbol s_2_9[2] = { 'n', 'n' };
+static const symbol s_2_10[2] = { 'p', 'p' };
+static const symbol s_2_11[2] = { 'r', 'r' };
+static const symbol s_2_12[3] = { 'c', 'c', 's' };
+static const symbol s_2_13[2] = { 's', 's' };
+static const symbol s_2_14[3] = { 'z', 'z', 's' };
+static const symbol s_2_15[2] = { 't', 't' };
+static const symbol s_2_16[2] = { 'v', 'v' };
+static const symbol s_2_17[3] = { 'g', 'g', 'y' };
+static const symbol s_2_18[3] = { 'l', 'l', 'y' };
+static const symbol s_2_19[3] = { 'n', 'n', 'y' };
+static const symbol s_2_20[3] = { 't', 't', 'y' };
+static const symbol s_2_21[3] = { 's', 's', 'z' };
+static const symbol s_2_22[2] = { 'z', 'z' };
+
+static const struct among a_2[23] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 2, s_2_1, -1, -1, 0},
+/* 2 */ { 2, s_2_2, -1, -1, 0},
+/* 3 */ { 2, s_2_3, -1, -1, 0},
+/* 4 */ { 2, s_2_4, -1, -1, 0},
+/* 5 */ { 2, s_2_5, -1, -1, 0},
+/* 6 */ { 2, s_2_6, -1, -1, 0},
+/* 7 */ { 2, s_2_7, -1, -1, 0},
+/* 8 */ { 2, s_2_8, -1, -1, 0},
+/* 9 */ { 2, s_2_9, -1, -1, 0},
+/* 10 */ { 2, s_2_10, -1, -1, 0},
+/* 11 */ { 2, s_2_11, -1, -1, 0},
+/* 12 */ { 3, s_2_12, -1, -1, 0},
+/* 13 */ { 2, s_2_13, -1, -1, 0},
+/* 14 */ { 3, s_2_14, -1, -1, 0},
+/* 15 */ { 2, s_2_15, -1, -1, 0},
+/* 16 */ { 2, s_2_16, -1, -1, 0},
+/* 17 */ { 3, s_2_17, -1, -1, 0},
+/* 18 */ { 3, s_2_18, -1, -1, 0},
+/* 19 */ { 3, s_2_19, -1, -1, 0},
+/* 20 */ { 3, s_2_20, -1, -1, 0},
+/* 21 */ { 3, s_2_21, -1, -1, 0},
+/* 22 */ { 2, s_2_22, -1, -1, 0}
+};
+
+static const symbol s_3_0[2] = { 'a', 'l' };
+static const symbol s_3_1[2] = { 'e', 'l' };
+
+static const struct among a_3[2] =
+{
+/* 0 */ { 2, s_3_0, -1, 1, 0},
+/* 1 */ { 2, s_3_1, -1, 2, 0}
+};
+
+static const symbol s_4_0[2] = { 'b', 'a' };
+static const symbol s_4_1[2] = { 'r', 'a' };
+static const symbol s_4_2[2] = { 'b', 'e' };
+static const symbol s_4_3[2] = { 'r', 'e' };
+static const symbol s_4_4[2] = { 'i', 'g' };
+static const symbol s_4_5[3] = { 'n', 'a', 'k' };
+static const symbol s_4_6[3] = { 'n', 'e', 'k' };
+static const symbol s_4_7[3] = { 'v', 'a', 'l' };
+static const symbol s_4_8[3] = { 'v', 'e', 'l' };
+static const symbol s_4_9[2] = { 'u', 'l' };
+static const symbol s_4_10[4] = { 'n', 0xC3, 0xA1, 'l' };
+static const symbol s_4_11[4] = { 'n', 0xC3, 0xA9, 'l' };
+static const symbol s_4_12[4] = { 'b', 0xC3, 0xB3, 'l' };
+static const symbol s_4_13[4] = { 'r', 0xC3, 0xB3, 'l' };
+static const symbol s_4_14[4] = { 't', 0xC3, 0xB3, 'l' };
+static const symbol s_4_15[4] = { 'b', 0xC3, 0xB5, 'l' };
+static const symbol s_4_16[4] = { 'r', 0xC3, 0xB5, 'l' };
+static const symbol s_4_17[4] = { 't', 0xC3, 0xB5, 'l' };
+static const symbol s_4_18[3] = { 0xC3, 0xBC, 'l' };
+static const symbol s_4_19[1] = { 'n' };
+static const symbol s_4_20[2] = { 'a', 'n' };
+static const symbol s_4_21[3] = { 'b', 'a', 'n' };
+static const symbol s_4_22[2] = { 'e', 'n' };
+static const symbol s_4_23[3] = { 'b', 'e', 'n' };
+static const symbol s_4_24[7] = { 'k', 0xC3, 0xA9, 'p', 'p', 'e', 'n' };
+static const symbol s_4_25[2] = { 'o', 'n' };
+static const symbol s_4_26[3] = { 0xC3, 0xB6, 'n' };
+static const symbol s_4_27[5] = { 'k', 0xC3, 0xA9, 'p', 'p' };
+static const symbol s_4_28[3] = { 'k', 'o', 'r' };
+static const symbol s_4_29[1] = { 't' };
+static const symbol s_4_30[2] = { 'a', 't' };
+static const symbol s_4_31[2] = { 'e', 't' };
+static const symbol s_4_32[5] = { 'k', 0xC3, 0xA9, 'n', 't' };
+static const symbol s_4_33[7] = { 'a', 'n', 'k', 0xC3, 0xA9, 'n', 't' };
+static const symbol s_4_34[7] = { 'e', 'n', 'k', 0xC3, 0xA9, 'n', 't' };
+static const symbol s_4_35[7] = { 'o', 'n', 'k', 0xC3, 0xA9, 'n', 't' };
+static const symbol s_4_36[2] = { 'o', 't' };
+static const symbol s_4_37[4] = { 0xC3, 0xA9, 'r', 't' };
+static const symbol s_4_38[3] = { 0xC3, 0xB6, 't' };
+static const symbol s_4_39[3] = { 'h', 'e', 'z' };
+static const symbol s_4_40[3] = { 'h', 'o', 'z' };
+static const symbol s_4_41[4] = { 'h', 0xC3, 0xB6, 'z' };
+static const symbol s_4_42[3] = { 'v', 0xC3, 0xA1 };
+static const symbol s_4_43[3] = { 'v', 0xC3, 0xA9 };
+
+static const struct among a_4[44] =
+{
+/* 0 */ { 2, s_4_0, -1, -1, 0},
+/* 1 */ { 2, s_4_1, -1, -1, 0},
+/* 2 */ { 2, s_4_2, -1, -1, 0},
+/* 3 */ { 2, s_4_3, -1, -1, 0},
+/* 4 */ { 2, s_4_4, -1, -1, 0},
+/* 5 */ { 3, s_4_5, -1, -1, 0},
+/* 6 */ { 3, s_4_6, -1, -1, 0},
+/* 7 */ { 3, s_4_7, -1, -1, 0},
+/* 8 */ { 3, s_4_8, -1, -1, 0},
+/* 9 */ { 2, s_4_9, -1, -1, 0},
+/* 10 */ { 4, s_4_10, -1, -1, 0},
+/* 11 */ { 4, s_4_11, -1, -1, 0},
+/* 12 */ { 4, s_4_12, -1, -1, 0},
+/* 13 */ { 4, s_4_13, -1, -1, 0},
+/* 14 */ { 4, s_4_14, -1, -1, 0},
+/* 15 */ { 4, s_4_15, -1, -1, 0},
+/* 16 */ { 4, s_4_16, -1, -1, 0},
+/* 17 */ { 4, s_4_17, -1, -1, 0},
+/* 18 */ { 3, s_4_18, -1, -1, 0},
+/* 19 */ { 1, s_4_19, -1, -1, 0},
+/* 20 */ { 2, s_4_20, 19, -1, 0},
+/* 21 */ { 3, s_4_21, 20, -1, 0},
+/* 22 */ { 2, s_4_22, 19, -1, 0},
+/* 23 */ { 3, s_4_23, 22, -1, 0},
+/* 24 */ { 7, s_4_24, 22, -1, 0},
+/* 25 */ { 2, s_4_25, 19, -1, 0},
+/* 26 */ { 3, s_4_26, 19, -1, 0},
+/* 27 */ { 5, s_4_27, -1, -1, 0},
+/* 28 */ { 3, s_4_28, -1, -1, 0},
+/* 29 */ { 1, s_4_29, -1, -1, 0},
+/* 30 */ { 2, s_4_30, 29, -1, 0},
+/* 31 */ { 2, s_4_31, 29, -1, 0},
+/* 32 */ { 5, s_4_32, 29, -1, 0},
+/* 33 */ { 7, s_4_33, 32, -1, 0},
+/* 34 */ { 7, s_4_34, 32, -1, 0},
+/* 35 */ { 7, s_4_35, 32, -1, 0},
+/* 36 */ { 2, s_4_36, 29, -1, 0},
+/* 37 */ { 4, s_4_37, 29, -1, 0},
+/* 38 */ { 3, s_4_38, 29, -1, 0},
+/* 39 */ { 3, s_4_39, -1, -1, 0},
+/* 40 */ { 3, s_4_40, -1, -1, 0},
+/* 41 */ { 4, s_4_41, -1, -1, 0},
+/* 42 */ { 3, s_4_42, -1, -1, 0},
+/* 43 */ { 3, s_4_43, -1, -1, 0}
+};
+
+static const symbol s_5_0[3] = { 0xC3, 0xA1, 'n' };
+static const symbol s_5_1[3] = { 0xC3, 0xA9, 'n' };
+static const symbol s_5_2[8] = { 0xC3, 0xA1, 'n', 'k', 0xC3, 0xA9, 'n', 't' };
+
+static const struct among a_5[3] =
+{
+/* 0 */ { 3, s_5_0, -1, 2, 0},
+/* 1 */ { 3, s_5_1, -1, 1, 0},
+/* 2 */ { 8, s_5_2, -1, 3, 0}
+};
+
+static const symbol s_6_0[4] = { 's', 't', 'u', 'l' };
+static const symbol s_6_1[5] = { 'a', 's', 't', 'u', 'l' };
+static const symbol s_6_2[6] = { 0xC3, 0xA1, 's', 't', 'u', 'l' };
+static const symbol s_6_3[5] = { 's', 't', 0xC3, 0xBC, 'l' };
+static const symbol s_6_4[6] = { 'e', 's', 't', 0xC3, 0xBC, 'l' };
+static const symbol s_6_5[7] = { 0xC3, 0xA9, 's', 't', 0xC3, 0xBC, 'l' };
+
+static const struct among a_6[6] =
+{
+/* 0 */ { 4, s_6_0, -1, 2, 0},
+/* 1 */ { 5, s_6_1, 0, 1, 0},
+/* 2 */ { 6, s_6_2, 0, 3, 0},
+/* 3 */ { 5, s_6_3, -1, 2, 0},
+/* 4 */ { 6, s_6_4, 3, 1, 0},
+/* 5 */ { 7, s_6_5, 3, 4, 0}
+};
+
+static const symbol s_7_0[2] = { 0xC3, 0xA1 };
+static const symbol s_7_1[2] = { 0xC3, 0xA9 };
+
+static const struct among a_7[2] =
+{
+/* 0 */ { 2, s_7_0, -1, 1, 0},
+/* 1 */ { 2, s_7_1, -1, 2, 0}
+};
+
+static const symbol s_8_0[1] = { 'k' };
+static const symbol s_8_1[2] = { 'a', 'k' };
+static const symbol s_8_2[2] = { 'e', 'k' };
+static const symbol s_8_3[2] = { 'o', 'k' };
+static const symbol s_8_4[3] = { 0xC3, 0xA1, 'k' };
+static const symbol s_8_5[3] = { 0xC3, 0xA9, 'k' };
+static const symbol s_8_6[3] = { 0xC3, 0xB6, 'k' };
+
+static const struct among a_8[7] =
+{
+/* 0 */ { 1, s_8_0, -1, 7, 0},
+/* 1 */ { 2, s_8_1, 0, 4, 0},
+/* 2 */ { 2, s_8_2, 0, 6, 0},
+/* 3 */ { 2, s_8_3, 0, 5, 0},
+/* 4 */ { 3, s_8_4, 0, 1, 0},
+/* 5 */ { 3, s_8_5, 0, 2, 0},
+/* 6 */ { 3, s_8_6, 0, 3, 0}
+};
+
+static const symbol s_9_0[3] = { 0xC3, 0xA9, 'i' };
+static const symbol s_9_1[5] = { 0xC3, 0xA1, 0xC3, 0xA9, 'i' };
+static const symbol s_9_2[5] = { 0xC3, 0xA9, 0xC3, 0xA9, 'i' };
+static const symbol s_9_3[2] = { 0xC3, 0xA9 };
+static const symbol s_9_4[3] = { 'k', 0xC3, 0xA9 };
+static const symbol s_9_5[4] = { 'a', 'k', 0xC3, 0xA9 };
+static const symbol s_9_6[4] = { 'e', 'k', 0xC3, 0xA9 };
+static const symbol s_9_7[4] = { 'o', 'k', 0xC3, 0xA9 };
+static const symbol s_9_8[5] = { 0xC3, 0xA1, 'k', 0xC3, 0xA9 };
+static const symbol s_9_9[5] = { 0xC3, 0xA9, 'k', 0xC3, 0xA9 };
+static const symbol s_9_10[5] = { 0xC3, 0xB6, 'k', 0xC3, 0xA9 };
+static const symbol s_9_11[4] = { 0xC3, 0xA9, 0xC3, 0xA9 };
+
+static const struct among a_9[12] =
+{
+/* 0 */ { 3, s_9_0, -1, 7, 0},
+/* 1 */ { 5, s_9_1, 0, 6, 0},
+/* 2 */ { 5, s_9_2, 0, 5, 0},
+/* 3 */ { 2, s_9_3, -1, 9, 0},
+/* 4 */ { 3, s_9_4, 3, 4, 0},
+/* 5 */ { 4, s_9_5, 4, 1, 0},
+/* 6 */ { 4, s_9_6, 4, 1, 0},
+/* 7 */ { 4, s_9_7, 4, 1, 0},
+/* 8 */ { 5, s_9_8, 4, 3, 0},
+/* 9 */ { 5, s_9_9, 4, 2, 0},
+/* 10 */ { 5, s_9_10, 4, 1, 0},
+/* 11 */ { 4, s_9_11, 3, 8, 0}
+};
+
+static const symbol s_10_0[1] = { 'a' };
+static const symbol s_10_1[2] = { 'j', 'a' };
+static const symbol s_10_2[1] = { 'd' };
+static const symbol s_10_3[2] = { 'a', 'd' };
+static const symbol s_10_4[2] = { 'e', 'd' };
+static const symbol s_10_5[2] = { 'o', 'd' };
+static const symbol s_10_6[3] = { 0xC3, 0xA1, 'd' };
+static const symbol s_10_7[3] = { 0xC3, 0xA9, 'd' };
+static const symbol s_10_8[3] = { 0xC3, 0xB6, 'd' };
+static const symbol s_10_9[1] = { 'e' };
+static const symbol s_10_10[2] = { 'j', 'e' };
+static const symbol s_10_11[2] = { 'n', 'k' };
+static const symbol s_10_12[3] = { 'u', 'n', 'k' };
+static const symbol s_10_13[4] = { 0xC3, 0xA1, 'n', 'k' };
+static const symbol s_10_14[4] = { 0xC3, 0xA9, 'n', 'k' };
+static const symbol s_10_15[4] = { 0xC3, 0xBC, 'n', 'k' };
+static const symbol s_10_16[2] = { 'u', 'k' };
+static const symbol s_10_17[3] = { 'j', 'u', 'k' };
+static const symbol s_10_18[5] = { 0xC3, 0xA1, 'j', 'u', 'k' };
+static const symbol s_10_19[3] = { 0xC3, 0xBC, 'k' };
+static const symbol s_10_20[4] = { 'j', 0xC3, 0xBC, 'k' };
+static const symbol s_10_21[6] = { 0xC3, 0xA9, 'j', 0xC3, 0xBC, 'k' };
+static const symbol s_10_22[1] = { 'm' };
+static const symbol s_10_23[2] = { 'a', 'm' };
+static const symbol s_10_24[2] = { 'e', 'm' };
+static const symbol s_10_25[2] = { 'o', 'm' };
+static const symbol s_10_26[3] = { 0xC3, 0xA1, 'm' };
+static const symbol s_10_27[3] = { 0xC3, 0xA9, 'm' };
+static const symbol s_10_28[1] = { 'o' };
+static const symbol s_10_29[2] = { 0xC3, 0xA1 };
+static const symbol s_10_30[2] = { 0xC3, 0xA9 };
+
+static const struct among a_10[31] =
+{
+/* 0 */ { 1, s_10_0, -1, 18, 0},
+/* 1 */ { 2, s_10_1, 0, 17, 0},
+/* 2 */ { 1, s_10_2, -1, 16, 0},
+/* 3 */ { 2, s_10_3, 2, 13, 0},
+/* 4 */ { 2, s_10_4, 2, 13, 0},
+/* 5 */ { 2, s_10_5, 2, 13, 0},
+/* 6 */ { 3, s_10_6, 2, 14, 0},
+/* 7 */ { 3, s_10_7, 2, 15, 0},
+/* 8 */ { 3, s_10_8, 2, 13, 0},
+/* 9 */ { 1, s_10_9, -1, 18, 0},
+/* 10 */ { 2, s_10_10, 9, 17, 0},
+/* 11 */ { 2, s_10_11, -1, 4, 0},
+/* 12 */ { 3, s_10_12, 11, 1, 0},
+/* 13 */ { 4, s_10_13, 11, 2, 0},
+/* 14 */ { 4, s_10_14, 11, 3, 0},
+/* 15 */ { 4, s_10_15, 11, 1, 0},
+/* 16 */ { 2, s_10_16, -1, 8, 0},
+/* 17 */ { 3, s_10_17, 16, 7, 0},
+/* 18 */ { 5, s_10_18, 17, 5, 0},
+/* 19 */ { 3, s_10_19, -1, 8, 0},
+/* 20 */ { 4, s_10_20, 19, 7, 0},
+/* 21 */ { 6, s_10_21, 20, 6, 0},
+/* 22 */ { 1, s_10_22, -1, 12, 0},
+/* 23 */ { 2, s_10_23, 22, 9, 0},
+/* 24 */ { 2, s_10_24, 22, 9, 0},
+/* 25 */ { 2, s_10_25, 22, 9, 0},
+/* 26 */ { 3, s_10_26, 22, 10, 0},
+/* 27 */ { 3, s_10_27, 22, 11, 0},
+/* 28 */ { 1, s_10_28, -1, 18, 0},
+/* 29 */ { 2, s_10_29, -1, 19, 0},
+/* 30 */ { 2, s_10_30, -1, 20, 0}
+};
+
+static const symbol s_11_0[2] = { 'i', 'd' };
+static const symbol s_11_1[3] = { 'a', 'i', 'd' };
+static const symbol s_11_2[4] = { 'j', 'a', 'i', 'd' };
+static const symbol s_11_3[3] = { 'e', 'i', 'd' };
+static const symbol s_11_4[4] = { 'j', 'e', 'i', 'd' };
+static const symbol s_11_5[4] = { 0xC3, 0xA1, 'i', 'd' };
+static const symbol s_11_6[4] = { 0xC3, 0xA9, 'i', 'd' };
+static const symbol s_11_7[1] = { 'i' };
+static const symbol s_11_8[2] = { 'a', 'i' };
+static const symbol s_11_9[3] = { 'j', 'a', 'i' };
+static const symbol s_11_10[2] = { 'e', 'i' };
+static const symbol s_11_11[3] = { 'j', 'e', 'i' };
+static const symbol s_11_12[3] = { 0xC3, 0xA1, 'i' };
+static const symbol s_11_13[3] = { 0xC3, 0xA9, 'i' };
+static const symbol s_11_14[4] = { 'i', 't', 'e', 'k' };
+static const symbol s_11_15[5] = { 'e', 'i', 't', 'e', 'k' };
+static const symbol s_11_16[6] = { 'j', 'e', 'i', 't', 'e', 'k' };
+static const symbol s_11_17[6] = { 0xC3, 0xA9, 'i', 't', 'e', 'k' };
+static const symbol s_11_18[2] = { 'i', 'k' };
+static const symbol s_11_19[3] = { 'a', 'i', 'k' };
+static const symbol s_11_20[4] = { 'j', 'a', 'i', 'k' };
+static const symbol s_11_21[3] = { 'e', 'i', 'k' };
+static const symbol s_11_22[4] = { 'j', 'e', 'i', 'k' };
+static const symbol s_11_23[4] = { 0xC3, 0xA1, 'i', 'k' };
+static const symbol s_11_24[4] = { 0xC3, 0xA9, 'i', 'k' };
+static const symbol s_11_25[3] = { 'i', 'n', 'k' };
+static const symbol s_11_26[4] = { 'a', 'i', 'n', 'k' };
+static const symbol s_11_27[5] = { 'j', 'a', 'i', 'n', 'k' };
+static const symbol s_11_28[4] = { 'e', 'i', 'n', 'k' };
+static const symbol s_11_29[5] = { 'j', 'e', 'i', 'n', 'k' };
+static const symbol s_11_30[5] = { 0xC3, 0xA1, 'i', 'n', 'k' };
+static const symbol s_11_31[5] = { 0xC3, 0xA9, 'i', 'n', 'k' };
+static const symbol s_11_32[5] = { 'a', 'i', 't', 'o', 'k' };
+static const symbol s_11_33[6] = { 'j', 'a', 'i', 't', 'o', 'k' };
+static const symbol s_11_34[6] = { 0xC3, 0xA1, 'i', 't', 'o', 'k' };
+static const symbol s_11_35[2] = { 'i', 'm' };
+static const symbol s_11_36[3] = { 'a', 'i', 'm' };
+static const symbol s_11_37[4] = { 'j', 'a', 'i', 'm' };
+static const symbol s_11_38[3] = { 'e', 'i', 'm' };
+static const symbol s_11_39[4] = { 'j', 'e', 'i', 'm' };
+static const symbol s_11_40[4] = { 0xC3, 0xA1, 'i', 'm' };
+static const symbol s_11_41[4] = { 0xC3, 0xA9, 'i', 'm' };
+
+static const struct among a_11[42] =
+{
+/* 0 */ { 2, s_11_0, -1, 10, 0},
+/* 1 */ { 3, s_11_1, 0, 9, 0},
+/* 2 */ { 4, s_11_2, 1, 6, 0},
+/* 3 */ { 3, s_11_3, 0, 9, 0},
+/* 4 */ { 4, s_11_4, 3, 6, 0},
+/* 5 */ { 4, s_11_5, 0, 7, 0},
+/* 6 */ { 4, s_11_6, 0, 8, 0},
+/* 7 */ { 1, s_11_7, -1, 15, 0},
+/* 8 */ { 2, s_11_8, 7, 14, 0},
+/* 9 */ { 3, s_11_9, 8, 11, 0},
+/* 10 */ { 2, s_11_10, 7, 14, 0},
+/* 11 */ { 3, s_11_11, 10, 11, 0},
+/* 12 */ { 3, s_11_12, 7, 12, 0},
+/* 13 */ { 3, s_11_13, 7, 13, 0},
+/* 14 */ { 4, s_11_14, -1, 24, 0},
+/* 15 */ { 5, s_11_15, 14, 21, 0},
+/* 16 */ { 6, s_11_16, 15, 20, 0},
+/* 17 */ { 6, s_11_17, 14, 23, 0},
+/* 18 */ { 2, s_11_18, -1, 29, 0},
+/* 19 */ { 3, s_11_19, 18, 26, 0},
+/* 20 */ { 4, s_11_20, 19, 25, 0},
+/* 21 */ { 3, s_11_21, 18, 26, 0},
+/* 22 */ { 4, s_11_22, 21, 25, 0},
+/* 23 */ { 4, s_11_23, 18, 27, 0},
+/* 24 */ { 4, s_11_24, 18, 28, 0},
+/* 25 */ { 3, s_11_25, -1, 20, 0},
+/* 26 */ { 4, s_11_26, 25, 17, 0},
+/* 27 */ { 5, s_11_27, 26, 16, 0},
+/* 28 */ { 4, s_11_28, 25, 17, 0},
+/* 29 */ { 5, s_11_29, 28, 16, 0},
+/* 30 */ { 5, s_11_30, 25, 18, 0},
+/* 31 */ { 5, s_11_31, 25, 19, 0},
+/* 32 */ { 5, s_11_32, -1, 21, 0},
+/* 33 */ { 6, s_11_33, 32, 20, 0},
+/* 34 */ { 6, s_11_34, -1, 22, 0},
+/* 35 */ { 2, s_11_35, -1, 5, 0},
+/* 36 */ { 3, s_11_36, 35, 4, 0},
+/* 37 */ { 4, s_11_37, 36, 1, 0},
+/* 38 */ { 3, s_11_38, 35, 4, 0},
+/* 39 */ { 4, s_11_39, 38, 1, 0},
+/* 40 */ { 4, s_11_40, 35, 2, 0},
+/* 41 */ { 4, s_11_41, 35, 3, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 52, 14 };
+
+static const symbol s_0[] = { 'a' };
+static const symbol s_1[] = { 'e' };
+static const symbol s_2[] = { 'e' };
+static const symbol s_3[] = { 'a' };
+static const symbol s_4[] = { 'a' };
+static const symbol s_5[] = { 'a' };
+static const symbol s_6[] = { 'e' };
+static const symbol s_7[] = { 'a' };
+static const symbol s_8[] = { 'e' };
+static const symbol s_9[] = { 'e' };
+static const symbol s_10[] = { 'a' };
+static const symbol s_11[] = { 'e' };
+static const symbol s_12[] = { 'a' };
+static const symbol s_13[] = { 'e' };
+static const symbol s_14[] = { 'a' };
+static const symbol s_15[] = { 'e' };
+static const symbol s_16[] = { 'a' };
+static const symbol s_17[] = { 'e' };
+static const symbol s_18[] = { 'a' };
+static const symbol s_19[] = { 'e' };
+static const symbol s_20[] = { 'a' };
+static const symbol s_21[] = { 'e' };
+static const symbol s_22[] = { 'a' };
+static const symbol s_23[] = { 'e' };
+static const symbol s_24[] = { 'a' };
+static const symbol s_25[] = { 'e' };
+static const symbol s_26[] = { 'a' };
+static const symbol s_27[] = { 'e' };
+static const symbol s_28[] = { 'a' };
+static const symbol s_29[] = { 'e' };
+static const symbol s_30[] = { 'a' };
+static const symbol s_31[] = { 'e' };
+static const symbol s_32[] = { 'a' };
+static const symbol s_33[] = { 'e' };
+static const symbol s_34[] = { 'a' };
+static const symbol s_35[] = { 'e' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ { int c1 = z->c; /* or, line 51 */
+ if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab1;
+ if (in_grouping_U(z, g_v, 97, 252, 1) < 0) goto lab1; /* goto */ /* non v, line 48 */
+ { int c2 = z->c; /* or, line 49 */
+ if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3;
+ if (!(find_among(z, a_0, 8))) goto lab3; /* among, line 49 */
+ goto lab2;
+ lab3:
+ z->c = c2;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab1;
+ z->c = ret; /* next, line 49 */
+ }
+ }
+ lab2:
+ z->I[0] = z->c; /* setmark p1, line 50 */
+ goto lab0;
+ lab1:
+ z->c = c1;
+ if (out_grouping_U(z, g_v, 97, 252, 0)) return 0;
+ { /* gopast */ /* grouping v, line 53 */
+ int ret = out_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 53 */
+ }
+lab0:
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_v_ending(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 61 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0;
+ among_var = find_among_b(z, a_1, 2); /* substring, line 61 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 61 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 61 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_0); /* <-, line 62 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 63 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_double(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 68 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_2, 23))) return 0; /* among, line 68 */
+ z->c = z->l - m_test;
+ }
+ return 1;
+}
+
+static int r_undouble(struct SN_env * z) {
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 73 */
+ }
+ z->ket = z->c; /* [, line 73 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 1);
+ if (ret < 0) return 0;
+ z->c = ret; /* hop, line 73 */
+ }
+ z->bra = z->c; /* ], line 73 */
+ { int ret = slice_del(z); /* delete, line 73 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_instrum(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 77 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0;
+ among_var = find_among_b(z, a_3, 2); /* substring, line 77 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 77 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 77 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_double(z);
+ if (ret == 0) return 0; /* call double, line 78 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_double(z);
+ if (ret == 0) return 0; /* call double, line 79 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 81 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_undouble(z);
+ if (ret == 0) return 0; /* call undouble, line 82 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_case(struct SN_env * z) {
+ z->ket = z->c; /* [, line 87 */
+ if (!(find_among_b(z, a_4, 44))) return 0; /* substring, line 87 */
+ z->bra = z->c; /* ], line 87 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 87 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 111 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_v_ending(z);
+ if (ret == 0) return 0; /* call v_ending, line 112 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_case_special(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 116 */
+ if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0;
+ among_var = find_among_b(z, a_5, 3); /* substring, line 116 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 116 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 116 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 117 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 118 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 119 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_case_other(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 124 */
+ if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0;
+ among_var = find_among_b(z, a_6, 6); /* substring, line 124 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 124 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 124 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 125 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 126 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 127 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 128 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_factive(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 133 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0;
+ among_var = find_among_b(z, a_7, 2); /* substring, line 133 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 133 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 133 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_double(z);
+ if (ret == 0) return 0; /* call double, line 134 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_double(z);
+ if (ret == 0) return 0; /* call double, line 135 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ { int ret = slice_del(z); /* delete, line 137 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_undouble(z);
+ if (ret == 0) return 0; /* call undouble, line 138 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_plural(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 142 */
+ if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0;
+ among_var = find_among_b(z, a_8, 7); /* substring, line 142 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 142 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 142 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 143 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_8); /* <-, line 144 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 145 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 146 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_del(z); /* delete, line 147 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_del(z); /* delete, line 148 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_del(z); /* delete, line 149 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_owned(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 154 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 169)) return 0;
+ among_var = find_among_b(z, a_9, 12); /* substring, line 154 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 154 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 154 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 155 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_9); /* <-, line 156 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 157 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 158 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_11); /* <-, line 159 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 1, s_12); /* <-, line 160 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_del(z); /* delete, line 161 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 162 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_del(z); /* delete, line 163 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_sing_owner(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 168 */
+ among_var = find_among_b(z, a_10, 31); /* substring, line 168 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 168 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 168 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 169 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_14); /* <-, line 170 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_15); /* <-, line 171 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 172 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_16); /* <-, line 173 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 1, s_17); /* <-, line 174 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_del(z); /* delete, line 175 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_del(z); /* delete, line 176 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_del(z); /* delete, line 177 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_from_s(z, 1, s_18); /* <-, line 178 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_from_s(z, 1, s_19); /* <-, line 179 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 12:
+ { int ret = slice_del(z); /* delete, line 180 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ { int ret = slice_del(z); /* delete, line 181 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 14:
+ { int ret = slice_from_s(z, 1, s_20); /* <-, line 182 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 15:
+ { int ret = slice_from_s(z, 1, s_21); /* <-, line 183 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 16:
+ { int ret = slice_del(z); /* delete, line 184 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 17:
+ { int ret = slice_del(z); /* delete, line 185 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 18:
+ { int ret = slice_del(z); /* delete, line 186 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 19:
+ { int ret = slice_from_s(z, 1, s_22); /* <-, line 187 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 20:
+ { int ret = slice_from_s(z, 1, s_23); /* <-, line 188 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_plur_owner(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 193 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_11, 42); /* substring, line 193 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 193 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 193 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 194 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_24); /* <-, line 195 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_25); /* <-, line 196 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_del(z); /* delete, line 197 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_del(z); /* delete, line 198 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_del(z); /* delete, line 199 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 1, s_26); /* <-, line 200 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 1, s_27); /* <-, line 201 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_del(z); /* delete, line 202 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_del(z); /* delete, line 203 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_del(z); /* delete, line 204 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 12:
+ { int ret = slice_from_s(z, 1, s_28); /* <-, line 205 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ { int ret = slice_from_s(z, 1, s_29); /* <-, line 206 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 14:
+ { int ret = slice_del(z); /* delete, line 207 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 15:
+ { int ret = slice_del(z); /* delete, line 208 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 16:
+ { int ret = slice_del(z); /* delete, line 209 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 17:
+ { int ret = slice_del(z); /* delete, line 210 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 18:
+ { int ret = slice_from_s(z, 1, s_30); /* <-, line 211 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 19:
+ { int ret = slice_from_s(z, 1, s_31); /* <-, line 212 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 20:
+ { int ret = slice_del(z); /* delete, line 214 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 21:
+ { int ret = slice_del(z); /* delete, line 215 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 22:
+ { int ret = slice_from_s(z, 1, s_32); /* <-, line 216 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 23:
+ { int ret = slice_from_s(z, 1, s_33); /* <-, line 217 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 24:
+ { int ret = slice_del(z); /* delete, line 218 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 25:
+ { int ret = slice_del(z); /* delete, line 219 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 26:
+ { int ret = slice_del(z); /* delete, line 220 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 27:
+ { int ret = slice_from_s(z, 1, s_34); /* <-, line 221 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 28:
+ { int ret = slice_from_s(z, 1, s_35); /* <-, line 222 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 29:
+ { int ret = slice_del(z); /* delete, line 223 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int hungarian_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 229 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 229 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 230 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 231 */
+ { int ret = r_instrum(z);
+ if (ret == 0) goto lab1; /* call instrum, line 231 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 232 */
+ { int ret = r_case(z);
+ if (ret == 0) goto lab2; /* call case, line 232 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 233 */
+ { int ret = r_case_special(z);
+ if (ret == 0) goto lab3; /* call case_special, line 233 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 234 */
+ { int ret = r_case_other(z);
+ if (ret == 0) goto lab4; /* call case_other, line 234 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ z->c = z->l - m5;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* do, line 235 */
+ { int ret = r_factive(z);
+ if (ret == 0) goto lab5; /* call factive, line 235 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ z->c = z->l - m6;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 236 */
+ { int ret = r_owned(z);
+ if (ret == 0) goto lab6; /* call owned, line 236 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m7;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 237 */
+ { int ret = r_sing_owner(z);
+ if (ret == 0) goto lab7; /* call sing_owner, line 237 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m8;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 238 */
+ { int ret = r_plur_owner(z);
+ if (ret == 0) goto lab8; /* call plur_owner, line 238 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = z->l - m9;
+ }
+ { int m10 = z->l - z->c; (void)m10; /* do, line 239 */
+ { int ret = r_plural(z);
+ if (ret == 0) goto lab9; /* call plural, line 239 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m10;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * hungarian_UTF_8_create_env(void) { return SN_create_env(0, 1, 0); }
+
+extern void hungarian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_italian.c b/src/backend/snowball/libstemmer/stem_UTF_8_italian.c
new file mode 100644
index 00000000000..395e38a548e
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_italian.c
@@ -0,0 +1,1073 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int italian_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_vowel_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_attached_pronoun(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * italian_UTF_8_create_env(void);
+extern void italian_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[2] = { 'q', 'u' };
+static const symbol s_0_2[2] = { 0xC3, 0xA1 };
+static const symbol s_0_3[2] = { 0xC3, 0xA9 };
+static const symbol s_0_4[2] = { 0xC3, 0xAD };
+static const symbol s_0_5[2] = { 0xC3, 0xB3 };
+static const symbol s_0_6[2] = { 0xC3, 0xBA };
+
+static const struct among a_0[7] =
+{
+/* 0 */ { 0, 0, -1, 7, 0},
+/* 1 */ { 2, s_0_1, 0, 6, 0},
+/* 2 */ { 2, s_0_2, 0, 1, 0},
+/* 3 */ { 2, s_0_3, 0, 2, 0},
+/* 4 */ { 2, s_0_4, 0, 3, 0},
+/* 5 */ { 2, s_0_5, 0, 4, 0},
+/* 6 */ { 2, s_0_6, 0, 5, 0}
+};
+
+static const symbol s_1_1[1] = { 'I' };
+static const symbol s_1_2[1] = { 'U' };
+
+static const struct among a_1[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 1, s_1_1, 0, 1, 0},
+/* 2 */ { 1, s_1_2, 0, 2, 0}
+};
+
+static const symbol s_2_0[2] = { 'l', 'a' };
+static const symbol s_2_1[4] = { 'c', 'e', 'l', 'a' };
+static const symbol s_2_2[6] = { 'g', 'l', 'i', 'e', 'l', 'a' };
+static const symbol s_2_3[4] = { 'm', 'e', 'l', 'a' };
+static const symbol s_2_4[4] = { 't', 'e', 'l', 'a' };
+static const symbol s_2_5[4] = { 'v', 'e', 'l', 'a' };
+static const symbol s_2_6[2] = { 'l', 'e' };
+static const symbol s_2_7[4] = { 'c', 'e', 'l', 'e' };
+static const symbol s_2_8[6] = { 'g', 'l', 'i', 'e', 'l', 'e' };
+static const symbol s_2_9[4] = { 'm', 'e', 'l', 'e' };
+static const symbol s_2_10[4] = { 't', 'e', 'l', 'e' };
+static const symbol s_2_11[4] = { 'v', 'e', 'l', 'e' };
+static const symbol s_2_12[2] = { 'n', 'e' };
+static const symbol s_2_13[4] = { 'c', 'e', 'n', 'e' };
+static const symbol s_2_14[6] = { 'g', 'l', 'i', 'e', 'n', 'e' };
+static const symbol s_2_15[4] = { 'm', 'e', 'n', 'e' };
+static const symbol s_2_16[4] = { 's', 'e', 'n', 'e' };
+static const symbol s_2_17[4] = { 't', 'e', 'n', 'e' };
+static const symbol s_2_18[4] = { 'v', 'e', 'n', 'e' };
+static const symbol s_2_19[2] = { 'c', 'i' };
+static const symbol s_2_20[2] = { 'l', 'i' };
+static const symbol s_2_21[4] = { 'c', 'e', 'l', 'i' };
+static const symbol s_2_22[6] = { 'g', 'l', 'i', 'e', 'l', 'i' };
+static const symbol s_2_23[4] = { 'm', 'e', 'l', 'i' };
+static const symbol s_2_24[4] = { 't', 'e', 'l', 'i' };
+static const symbol s_2_25[4] = { 'v', 'e', 'l', 'i' };
+static const symbol s_2_26[3] = { 'g', 'l', 'i' };
+static const symbol s_2_27[2] = { 'm', 'i' };
+static const symbol s_2_28[2] = { 's', 'i' };
+static const symbol s_2_29[2] = { 't', 'i' };
+static const symbol s_2_30[2] = { 'v', 'i' };
+static const symbol s_2_31[2] = { 'l', 'o' };
+static const symbol s_2_32[4] = { 'c', 'e', 'l', 'o' };
+static const symbol s_2_33[6] = { 'g', 'l', 'i', 'e', 'l', 'o' };
+static const symbol s_2_34[4] = { 'm', 'e', 'l', 'o' };
+static const symbol s_2_35[4] = { 't', 'e', 'l', 'o' };
+static const symbol s_2_36[4] = { 'v', 'e', 'l', 'o' };
+
+static const struct among a_2[37] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 4, s_2_1, 0, -1, 0},
+/* 2 */ { 6, s_2_2, 0, -1, 0},
+/* 3 */ { 4, s_2_3, 0, -1, 0},
+/* 4 */ { 4, s_2_4, 0, -1, 0},
+/* 5 */ { 4, s_2_5, 0, -1, 0},
+/* 6 */ { 2, s_2_6, -1, -1, 0},
+/* 7 */ { 4, s_2_7, 6, -1, 0},
+/* 8 */ { 6, s_2_8, 6, -1, 0},
+/* 9 */ { 4, s_2_9, 6, -1, 0},
+/* 10 */ { 4, s_2_10, 6, -1, 0},
+/* 11 */ { 4, s_2_11, 6, -1, 0},
+/* 12 */ { 2, s_2_12, -1, -1, 0},
+/* 13 */ { 4, s_2_13, 12, -1, 0},
+/* 14 */ { 6, s_2_14, 12, -1, 0},
+/* 15 */ { 4, s_2_15, 12, -1, 0},
+/* 16 */ { 4, s_2_16, 12, -1, 0},
+/* 17 */ { 4, s_2_17, 12, -1, 0},
+/* 18 */ { 4, s_2_18, 12, -1, 0},
+/* 19 */ { 2, s_2_19, -1, -1, 0},
+/* 20 */ { 2, s_2_20, -1, -1, 0},
+/* 21 */ { 4, s_2_21, 20, -1, 0},
+/* 22 */ { 6, s_2_22, 20, -1, 0},
+/* 23 */ { 4, s_2_23, 20, -1, 0},
+/* 24 */ { 4, s_2_24, 20, -1, 0},
+/* 25 */ { 4, s_2_25, 20, -1, 0},
+/* 26 */ { 3, s_2_26, 20, -1, 0},
+/* 27 */ { 2, s_2_27, -1, -1, 0},
+/* 28 */ { 2, s_2_28, -1, -1, 0},
+/* 29 */ { 2, s_2_29, -1, -1, 0},
+/* 30 */ { 2, s_2_30, -1, -1, 0},
+/* 31 */ { 2, s_2_31, -1, -1, 0},
+/* 32 */ { 4, s_2_32, 31, -1, 0},
+/* 33 */ { 6, s_2_33, 31, -1, 0},
+/* 34 */ { 4, s_2_34, 31, -1, 0},
+/* 35 */ { 4, s_2_35, 31, -1, 0},
+/* 36 */ { 4, s_2_36, 31, -1, 0}
+};
+
+static const symbol s_3_0[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_3_1[4] = { 'e', 'n', 'd', 'o' };
+static const symbol s_3_2[2] = { 'a', 'r' };
+static const symbol s_3_3[2] = { 'e', 'r' };
+static const symbol s_3_4[2] = { 'i', 'r' };
+
+static const struct among a_3[5] =
+{
+/* 0 */ { 4, s_3_0, -1, 1, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0},
+/* 2 */ { 2, s_3_2, -1, 2, 0},
+/* 3 */ { 2, s_3_3, -1, 2, 0},
+/* 4 */ { 2, s_3_4, -1, 2, 0}
+};
+
+static const symbol s_4_0[2] = { 'i', 'c' };
+static const symbol s_4_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_4_2[2] = { 'o', 's' };
+static const symbol s_4_3[2] = { 'i', 'v' };
+
+static const struct among a_4[4] =
+{
+/* 0 */ { 2, s_4_0, -1, -1, 0},
+/* 1 */ { 4, s_4_1, -1, -1, 0},
+/* 2 */ { 2, s_4_2, -1, -1, 0},
+/* 3 */ { 2, s_4_3, -1, 1, 0}
+};
+
+static const symbol s_5_0[2] = { 'i', 'c' };
+static const symbol s_5_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_5_2[2] = { 'i', 'v' };
+
+static const struct among a_5[3] =
+{
+/* 0 */ { 2, s_5_0, -1, 1, 0},
+/* 1 */ { 4, s_5_1, -1, 1, 0},
+/* 2 */ { 2, s_5_2, -1, 1, 0}
+};
+
+static const symbol s_6_0[3] = { 'i', 'c', 'a' };
+static const symbol s_6_1[5] = { 'l', 'o', 'g', 'i', 'a' };
+static const symbol s_6_2[3] = { 'o', 's', 'a' };
+static const symbol s_6_3[4] = { 'i', 's', 't', 'a' };
+static const symbol s_6_4[3] = { 'i', 'v', 'a' };
+static const symbol s_6_5[4] = { 'a', 'n', 'z', 'a' };
+static const symbol s_6_6[4] = { 'e', 'n', 'z', 'a' };
+static const symbol s_6_7[3] = { 'i', 'c', 'e' };
+static const symbol s_6_8[6] = { 'a', 't', 'r', 'i', 'c', 'e' };
+static const symbol s_6_9[4] = { 'i', 'c', 'h', 'e' };
+static const symbol s_6_10[5] = { 'l', 'o', 'g', 'i', 'e' };
+static const symbol s_6_11[5] = { 'a', 'b', 'i', 'l', 'e' };
+static const symbol s_6_12[5] = { 'i', 'b', 'i', 'l', 'e' };
+static const symbol s_6_13[6] = { 'u', 's', 'i', 'o', 'n', 'e' };
+static const symbol s_6_14[6] = { 'a', 'z', 'i', 'o', 'n', 'e' };
+static const symbol s_6_15[6] = { 'u', 'z', 'i', 'o', 'n', 'e' };
+static const symbol s_6_16[5] = { 'a', 't', 'o', 'r', 'e' };
+static const symbol s_6_17[3] = { 'o', 's', 'e' };
+static const symbol s_6_18[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_6_19[5] = { 'm', 'e', 'n', 't', 'e' };
+static const symbol s_6_20[6] = { 'a', 'm', 'e', 'n', 't', 'e' };
+static const symbol s_6_21[4] = { 'i', 's', 't', 'e' };
+static const symbol s_6_22[3] = { 'i', 'v', 'e' };
+static const symbol s_6_23[4] = { 'a', 'n', 'z', 'e' };
+static const symbol s_6_24[4] = { 'e', 'n', 'z', 'e' };
+static const symbol s_6_25[3] = { 'i', 'c', 'i' };
+static const symbol s_6_26[6] = { 'a', 't', 'r', 'i', 'c', 'i' };
+static const symbol s_6_27[4] = { 'i', 'c', 'h', 'i' };
+static const symbol s_6_28[5] = { 'a', 'b', 'i', 'l', 'i' };
+static const symbol s_6_29[5] = { 'i', 'b', 'i', 'l', 'i' };
+static const symbol s_6_30[4] = { 'i', 's', 'm', 'i' };
+static const symbol s_6_31[6] = { 'u', 's', 'i', 'o', 'n', 'i' };
+static const symbol s_6_32[6] = { 'a', 'z', 'i', 'o', 'n', 'i' };
+static const symbol s_6_33[6] = { 'u', 'z', 'i', 'o', 'n', 'i' };
+static const symbol s_6_34[5] = { 'a', 't', 'o', 'r', 'i' };
+static const symbol s_6_35[3] = { 'o', 's', 'i' };
+static const symbol s_6_36[4] = { 'a', 'n', 't', 'i' };
+static const symbol s_6_37[6] = { 'a', 'm', 'e', 'n', 't', 'i' };
+static const symbol s_6_38[6] = { 'i', 'm', 'e', 'n', 't', 'i' };
+static const symbol s_6_39[4] = { 'i', 's', 't', 'i' };
+static const symbol s_6_40[3] = { 'i', 'v', 'i' };
+static const symbol s_6_41[3] = { 'i', 'c', 'o' };
+static const symbol s_6_42[4] = { 'i', 's', 'm', 'o' };
+static const symbol s_6_43[3] = { 'o', 's', 'o' };
+static const symbol s_6_44[6] = { 'a', 'm', 'e', 'n', 't', 'o' };
+static const symbol s_6_45[6] = { 'i', 'm', 'e', 'n', 't', 'o' };
+static const symbol s_6_46[3] = { 'i', 'v', 'o' };
+static const symbol s_6_47[4] = { 'i', 't', 0xC3, 0xA0 };
+static const symbol s_6_48[5] = { 'i', 's', 't', 0xC3, 0xA0 };
+static const symbol s_6_49[5] = { 'i', 's', 't', 0xC3, 0xA8 };
+static const symbol s_6_50[5] = { 'i', 's', 't', 0xC3, 0xAC };
+
+static const struct among a_6[51] =
+{
+/* 0 */ { 3, s_6_0, -1, 1, 0},
+/* 1 */ { 5, s_6_1, -1, 3, 0},
+/* 2 */ { 3, s_6_2, -1, 1, 0},
+/* 3 */ { 4, s_6_3, -1, 1, 0},
+/* 4 */ { 3, s_6_4, -1, 9, 0},
+/* 5 */ { 4, s_6_5, -1, 1, 0},
+/* 6 */ { 4, s_6_6, -1, 5, 0},
+/* 7 */ { 3, s_6_7, -1, 1, 0},
+/* 8 */ { 6, s_6_8, 7, 1, 0},
+/* 9 */ { 4, s_6_9, -1, 1, 0},
+/* 10 */ { 5, s_6_10, -1, 3, 0},
+/* 11 */ { 5, s_6_11, -1, 1, 0},
+/* 12 */ { 5, s_6_12, -1, 1, 0},
+/* 13 */ { 6, s_6_13, -1, 4, 0},
+/* 14 */ { 6, s_6_14, -1, 2, 0},
+/* 15 */ { 6, s_6_15, -1, 4, 0},
+/* 16 */ { 5, s_6_16, -1, 2, 0},
+/* 17 */ { 3, s_6_17, -1, 1, 0},
+/* 18 */ { 4, s_6_18, -1, 1, 0},
+/* 19 */ { 5, s_6_19, -1, 1, 0},
+/* 20 */ { 6, s_6_20, 19, 7, 0},
+/* 21 */ { 4, s_6_21, -1, 1, 0},
+/* 22 */ { 3, s_6_22, -1, 9, 0},
+/* 23 */ { 4, s_6_23, -1, 1, 0},
+/* 24 */ { 4, s_6_24, -1, 5, 0},
+/* 25 */ { 3, s_6_25, -1, 1, 0},
+/* 26 */ { 6, s_6_26, 25, 1, 0},
+/* 27 */ { 4, s_6_27, -1, 1, 0},
+/* 28 */ { 5, s_6_28, -1, 1, 0},
+/* 29 */ { 5, s_6_29, -1, 1, 0},
+/* 30 */ { 4, s_6_30, -1, 1, 0},
+/* 31 */ { 6, s_6_31, -1, 4, 0},
+/* 32 */ { 6, s_6_32, -1, 2, 0},
+/* 33 */ { 6, s_6_33, -1, 4, 0},
+/* 34 */ { 5, s_6_34, -1, 2, 0},
+/* 35 */ { 3, s_6_35, -1, 1, 0},
+/* 36 */ { 4, s_6_36, -1, 1, 0},
+/* 37 */ { 6, s_6_37, -1, 6, 0},
+/* 38 */ { 6, s_6_38, -1, 6, 0},
+/* 39 */ { 4, s_6_39, -1, 1, 0},
+/* 40 */ { 3, s_6_40, -1, 9, 0},
+/* 41 */ { 3, s_6_41, -1, 1, 0},
+/* 42 */ { 4, s_6_42, -1, 1, 0},
+/* 43 */ { 3, s_6_43, -1, 1, 0},
+/* 44 */ { 6, s_6_44, -1, 6, 0},
+/* 45 */ { 6, s_6_45, -1, 6, 0},
+/* 46 */ { 3, s_6_46, -1, 9, 0},
+/* 47 */ { 4, s_6_47, -1, 8, 0},
+/* 48 */ { 5, s_6_48, -1, 1, 0},
+/* 49 */ { 5, s_6_49, -1, 1, 0},
+/* 50 */ { 5, s_6_50, -1, 1, 0}
+};
+
+static const symbol s_7_0[4] = { 'i', 's', 'c', 'a' };
+static const symbol s_7_1[4] = { 'e', 'n', 'd', 'a' };
+static const symbol s_7_2[3] = { 'a', 't', 'a' };
+static const symbol s_7_3[3] = { 'i', 't', 'a' };
+static const symbol s_7_4[3] = { 'u', 't', 'a' };
+static const symbol s_7_5[3] = { 'a', 'v', 'a' };
+static const symbol s_7_6[3] = { 'e', 'v', 'a' };
+static const symbol s_7_7[3] = { 'i', 'v', 'a' };
+static const symbol s_7_8[6] = { 'e', 'r', 'e', 'b', 'b', 'e' };
+static const symbol s_7_9[6] = { 'i', 'r', 'e', 'b', 'b', 'e' };
+static const symbol s_7_10[4] = { 'i', 's', 'c', 'e' };
+static const symbol s_7_11[4] = { 'e', 'n', 'd', 'e' };
+static const symbol s_7_12[3] = { 'a', 'r', 'e' };
+static const symbol s_7_13[3] = { 'e', 'r', 'e' };
+static const symbol s_7_14[3] = { 'i', 'r', 'e' };
+static const symbol s_7_15[4] = { 'a', 's', 's', 'e' };
+static const symbol s_7_16[3] = { 'a', 't', 'e' };
+static const symbol s_7_17[5] = { 'a', 'v', 'a', 't', 'e' };
+static const symbol s_7_18[5] = { 'e', 'v', 'a', 't', 'e' };
+static const symbol s_7_19[5] = { 'i', 'v', 'a', 't', 'e' };
+static const symbol s_7_20[3] = { 'e', 't', 'e' };
+static const symbol s_7_21[5] = { 'e', 'r', 'e', 't', 'e' };
+static const symbol s_7_22[5] = { 'i', 'r', 'e', 't', 'e' };
+static const symbol s_7_23[3] = { 'i', 't', 'e' };
+static const symbol s_7_24[6] = { 'e', 'r', 'e', 's', 't', 'e' };
+static const symbol s_7_25[6] = { 'i', 'r', 'e', 's', 't', 'e' };
+static const symbol s_7_26[3] = { 'u', 't', 'e' };
+static const symbol s_7_27[4] = { 'e', 'r', 'a', 'i' };
+static const symbol s_7_28[4] = { 'i', 'r', 'a', 'i' };
+static const symbol s_7_29[4] = { 'i', 's', 'c', 'i' };
+static const symbol s_7_30[4] = { 'e', 'n', 'd', 'i' };
+static const symbol s_7_31[4] = { 'e', 'r', 'e', 'i' };
+static const symbol s_7_32[4] = { 'i', 'r', 'e', 'i' };
+static const symbol s_7_33[4] = { 'a', 's', 's', 'i' };
+static const symbol s_7_34[3] = { 'a', 't', 'i' };
+static const symbol s_7_35[3] = { 'i', 't', 'i' };
+static const symbol s_7_36[6] = { 'e', 'r', 'e', 's', 't', 'i' };
+static const symbol s_7_37[6] = { 'i', 'r', 'e', 's', 't', 'i' };
+static const symbol s_7_38[3] = { 'u', 't', 'i' };
+static const symbol s_7_39[3] = { 'a', 'v', 'i' };
+static const symbol s_7_40[3] = { 'e', 'v', 'i' };
+static const symbol s_7_41[3] = { 'i', 'v', 'i' };
+static const symbol s_7_42[4] = { 'i', 's', 'c', 'o' };
+static const symbol s_7_43[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_7_44[4] = { 'e', 'n', 'd', 'o' };
+static const symbol s_7_45[4] = { 'Y', 'a', 'm', 'o' };
+static const symbol s_7_46[4] = { 'i', 'a', 'm', 'o' };
+static const symbol s_7_47[5] = { 'a', 'v', 'a', 'm', 'o' };
+static const symbol s_7_48[5] = { 'e', 'v', 'a', 'm', 'o' };
+static const symbol s_7_49[5] = { 'i', 'v', 'a', 'm', 'o' };
+static const symbol s_7_50[5] = { 'e', 'r', 'e', 'm', 'o' };
+static const symbol s_7_51[5] = { 'i', 'r', 'e', 'm', 'o' };
+static const symbol s_7_52[6] = { 'a', 's', 's', 'i', 'm', 'o' };
+static const symbol s_7_53[4] = { 'a', 'm', 'm', 'o' };
+static const symbol s_7_54[4] = { 'e', 'm', 'm', 'o' };
+static const symbol s_7_55[6] = { 'e', 'r', 'e', 'm', 'm', 'o' };
+static const symbol s_7_56[6] = { 'i', 'r', 'e', 'm', 'm', 'o' };
+static const symbol s_7_57[4] = { 'i', 'm', 'm', 'o' };
+static const symbol s_7_58[3] = { 'a', 'n', 'o' };
+static const symbol s_7_59[6] = { 'i', 's', 'c', 'a', 'n', 'o' };
+static const symbol s_7_60[5] = { 'a', 'v', 'a', 'n', 'o' };
+static const symbol s_7_61[5] = { 'e', 'v', 'a', 'n', 'o' };
+static const symbol s_7_62[5] = { 'i', 'v', 'a', 'n', 'o' };
+static const symbol s_7_63[6] = { 'e', 'r', 'a', 'n', 'n', 'o' };
+static const symbol s_7_64[6] = { 'i', 'r', 'a', 'n', 'n', 'o' };
+static const symbol s_7_65[3] = { 'o', 'n', 'o' };
+static const symbol s_7_66[6] = { 'i', 's', 'c', 'o', 'n', 'o' };
+static const symbol s_7_67[5] = { 'a', 'r', 'o', 'n', 'o' };
+static const symbol s_7_68[5] = { 'e', 'r', 'o', 'n', 'o' };
+static const symbol s_7_69[5] = { 'i', 'r', 'o', 'n', 'o' };
+static const symbol s_7_70[8] = { 'e', 'r', 'e', 'b', 'b', 'e', 'r', 'o' };
+static const symbol s_7_71[8] = { 'i', 'r', 'e', 'b', 'b', 'e', 'r', 'o' };
+static const symbol s_7_72[6] = { 'a', 's', 's', 'e', 'r', 'o' };
+static const symbol s_7_73[6] = { 'e', 's', 's', 'e', 'r', 'o' };
+static const symbol s_7_74[6] = { 'i', 's', 's', 'e', 'r', 'o' };
+static const symbol s_7_75[3] = { 'a', 't', 'o' };
+static const symbol s_7_76[3] = { 'i', 't', 'o' };
+static const symbol s_7_77[3] = { 'u', 't', 'o' };
+static const symbol s_7_78[3] = { 'a', 'v', 'o' };
+static const symbol s_7_79[3] = { 'e', 'v', 'o' };
+static const symbol s_7_80[3] = { 'i', 'v', 'o' };
+static const symbol s_7_81[2] = { 'a', 'r' };
+static const symbol s_7_82[2] = { 'i', 'r' };
+static const symbol s_7_83[4] = { 'e', 'r', 0xC3, 0xA0 };
+static const symbol s_7_84[4] = { 'i', 'r', 0xC3, 0xA0 };
+static const symbol s_7_85[4] = { 'e', 'r', 0xC3, 0xB2 };
+static const symbol s_7_86[4] = { 'i', 'r', 0xC3, 0xB2 };
+
+static const struct among a_7[87] =
+{
+/* 0 */ { 4, s_7_0, -1, 1, 0},
+/* 1 */ { 4, s_7_1, -1, 1, 0},
+/* 2 */ { 3, s_7_2, -1, 1, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0},
+/* 4 */ { 3, s_7_4, -1, 1, 0},
+/* 5 */ { 3, s_7_5, -1, 1, 0},
+/* 6 */ { 3, s_7_6, -1, 1, 0},
+/* 7 */ { 3, s_7_7, -1, 1, 0},
+/* 8 */ { 6, s_7_8, -1, 1, 0},
+/* 9 */ { 6, s_7_9, -1, 1, 0},
+/* 10 */ { 4, s_7_10, -1, 1, 0},
+/* 11 */ { 4, s_7_11, -1, 1, 0},
+/* 12 */ { 3, s_7_12, -1, 1, 0},
+/* 13 */ { 3, s_7_13, -1, 1, 0},
+/* 14 */ { 3, s_7_14, -1, 1, 0},
+/* 15 */ { 4, s_7_15, -1, 1, 0},
+/* 16 */ { 3, s_7_16, -1, 1, 0},
+/* 17 */ { 5, s_7_17, 16, 1, 0},
+/* 18 */ { 5, s_7_18, 16, 1, 0},
+/* 19 */ { 5, s_7_19, 16, 1, 0},
+/* 20 */ { 3, s_7_20, -1, 1, 0},
+/* 21 */ { 5, s_7_21, 20, 1, 0},
+/* 22 */ { 5, s_7_22, 20, 1, 0},
+/* 23 */ { 3, s_7_23, -1, 1, 0},
+/* 24 */ { 6, s_7_24, -1, 1, 0},
+/* 25 */ { 6, s_7_25, -1, 1, 0},
+/* 26 */ { 3, s_7_26, -1, 1, 0},
+/* 27 */ { 4, s_7_27, -1, 1, 0},
+/* 28 */ { 4, s_7_28, -1, 1, 0},
+/* 29 */ { 4, s_7_29, -1, 1, 0},
+/* 30 */ { 4, s_7_30, -1, 1, 0},
+/* 31 */ { 4, s_7_31, -1, 1, 0},
+/* 32 */ { 4, s_7_32, -1, 1, 0},
+/* 33 */ { 4, s_7_33, -1, 1, 0},
+/* 34 */ { 3, s_7_34, -1, 1, 0},
+/* 35 */ { 3, s_7_35, -1, 1, 0},
+/* 36 */ { 6, s_7_36, -1, 1, 0},
+/* 37 */ { 6, s_7_37, -1, 1, 0},
+/* 38 */ { 3, s_7_38, -1, 1, 0},
+/* 39 */ { 3, s_7_39, -1, 1, 0},
+/* 40 */ { 3, s_7_40, -1, 1, 0},
+/* 41 */ { 3, s_7_41, -1, 1, 0},
+/* 42 */ { 4, s_7_42, -1, 1, 0},
+/* 43 */ { 4, s_7_43, -1, 1, 0},
+/* 44 */ { 4, s_7_44, -1, 1, 0},
+/* 45 */ { 4, s_7_45, -1, 1, 0},
+/* 46 */ { 4, s_7_46, -1, 1, 0},
+/* 47 */ { 5, s_7_47, -1, 1, 0},
+/* 48 */ { 5, s_7_48, -1, 1, 0},
+/* 49 */ { 5, s_7_49, -1, 1, 0},
+/* 50 */ { 5, s_7_50, -1, 1, 0},
+/* 51 */ { 5, s_7_51, -1, 1, 0},
+/* 52 */ { 6, s_7_52, -1, 1, 0},
+/* 53 */ { 4, s_7_53, -1, 1, 0},
+/* 54 */ { 4, s_7_54, -1, 1, 0},
+/* 55 */ { 6, s_7_55, 54, 1, 0},
+/* 56 */ { 6, s_7_56, 54, 1, 0},
+/* 57 */ { 4, s_7_57, -1, 1, 0},
+/* 58 */ { 3, s_7_58, -1, 1, 0},
+/* 59 */ { 6, s_7_59, 58, 1, 0},
+/* 60 */ { 5, s_7_60, 58, 1, 0},
+/* 61 */ { 5, s_7_61, 58, 1, 0},
+/* 62 */ { 5, s_7_62, 58, 1, 0},
+/* 63 */ { 6, s_7_63, -1, 1, 0},
+/* 64 */ { 6, s_7_64, -1, 1, 0},
+/* 65 */ { 3, s_7_65, -1, 1, 0},
+/* 66 */ { 6, s_7_66, 65, 1, 0},
+/* 67 */ { 5, s_7_67, 65, 1, 0},
+/* 68 */ { 5, s_7_68, 65, 1, 0},
+/* 69 */ { 5, s_7_69, 65, 1, 0},
+/* 70 */ { 8, s_7_70, -1, 1, 0},
+/* 71 */ { 8, s_7_71, -1, 1, 0},
+/* 72 */ { 6, s_7_72, -1, 1, 0},
+/* 73 */ { 6, s_7_73, -1, 1, 0},
+/* 74 */ { 6, s_7_74, -1, 1, 0},
+/* 75 */ { 3, s_7_75, -1, 1, 0},
+/* 76 */ { 3, s_7_76, -1, 1, 0},
+/* 77 */ { 3, s_7_77, -1, 1, 0},
+/* 78 */ { 3, s_7_78, -1, 1, 0},
+/* 79 */ { 3, s_7_79, -1, 1, 0},
+/* 80 */ { 3, s_7_80, -1, 1, 0},
+/* 81 */ { 2, s_7_81, -1, 1, 0},
+/* 82 */ { 2, s_7_82, -1, 1, 0},
+/* 83 */ { 4, s_7_83, -1, 1, 0},
+/* 84 */ { 4, s_7_84, -1, 1, 0},
+/* 85 */ { 4, s_7_85, -1, 1, 0},
+/* 86 */ { 4, s_7_86, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1 };
+
+static const unsigned char g_AEIO[] = { 17, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2 };
+
+static const unsigned char g_CG[] = { 17 };
+
+static const symbol s_0[] = { 0xC3, 0xA0 };
+static const symbol s_1[] = { 0xC3, 0xA8 };
+static const symbol s_2[] = { 0xC3, 0xAC };
+static const symbol s_3[] = { 0xC3, 0xB2 };
+static const symbol s_4[] = { 0xC3, 0xB9 };
+static const symbol s_5[] = { 'q', 'U' };
+static const symbol s_6[] = { 'u' };
+static const symbol s_7[] = { 'U' };
+static const symbol s_8[] = { 'i' };
+static const symbol s_9[] = { 'I' };
+static const symbol s_10[] = { 'i' };
+static const symbol s_11[] = { 'u' };
+static const symbol s_12[] = { 'e' };
+static const symbol s_13[] = { 'i', 'c' };
+static const symbol s_14[] = { 'l', 'o', 'g' };
+static const symbol s_15[] = { 'u' };
+static const symbol s_16[] = { 'e', 'n', 't', 'e' };
+static const symbol s_17[] = { 'a', 't' };
+static const symbol s_18[] = { 'a', 't' };
+static const symbol s_19[] = { 'i', 'c' };
+static const symbol s_20[] = { 'i' };
+static const symbol s_21[] = { 'h' };
+
+static int r_prelude(struct SN_env * z) {
+ int among_var;
+ { int c_test = z->c; /* test, line 35 */
+ while(1) { /* repeat, line 35 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 36 */
+ among_var = find_among(z, a_0, 7); /* substring, line 36 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 36 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_0); /* <-, line 37 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 2, s_1); /* <-, line 38 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 2, s_2); /* <-, line 39 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 2, s_3); /* <-, line 40 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 2, s_4); /* <-, line 41 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 2, s_5); /* <-, line 42 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 43 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ z->c = c_test;
+ }
+ while(1) { /* repeat, line 46 */
+ int c2 = z->c;
+ while(1) { /* goto, line 46 */
+ int c3 = z->c;
+ if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2;
+ z->bra = z->c; /* [, line 47 */
+ { int c4 = z->c; /* or, line 47 */
+ if (!(eq_s(z, 1, s_6))) goto lab4;
+ z->ket = z->c; /* ], line 47 */
+ if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab4;
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 47 */
+ if (ret < 0) return ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c4;
+ if (!(eq_s(z, 1, s_8))) goto lab2;
+ z->ket = z->c; /* ], line 48 */
+ if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2;
+ { int ret = slice_from_s(z, 1, s_9); /* <-, line 48 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab3:
+ z->c = c3;
+ break;
+ lab2:
+ z->c = c3;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab1;
+ z->c = ret; /* goto, line 46 */
+ }
+ }
+ continue;
+ lab1:
+ z->c = c2;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 58 */
+ { int c2 = z->c; /* or, line 60 */
+ if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2;
+ { int c3 = z->c; /* or, line 59 */
+ if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab4;
+ { /* gopast */ /* grouping v, line 59 */
+ int ret = out_grouping_U(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c3;
+ if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2;
+ { /* gopast */ /* non v, line 59 */
+ int ret = in_grouping_U(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab2;
+ z->c += ret;
+ }
+ }
+ lab3:
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab0;
+ { int c4 = z->c; /* or, line 61 */
+ if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab6;
+ { /* gopast */ /* grouping v, line 61 */
+ int ret = out_grouping_U(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab6;
+ z->c += ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c4;
+ if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab0;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 61 */
+ }
+ }
+ lab5:
+ ;
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 62 */
+ lab0:
+ z->c = c1;
+ }
+ { int c5 = z->c; /* do, line 64 */
+ { /* gopast */ /* grouping v, line 65 */
+ int ret = out_grouping_U(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 65 */
+ int ret = in_grouping_U(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 65 */
+ { /* gopast */ /* grouping v, line 66 */
+ int ret = out_grouping_U(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 66 */
+ int ret = in_grouping_U(z, g_v, 97, 249, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 66 */
+ lab7:
+ z->c = c5;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 70 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 72 */
+ if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else
+ among_var = find_among(z, a_1, 3); /* substring, line 72 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 72 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 73 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_11); /* <-, line 74 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 75 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_attached_pronoun(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 87 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_2, 37))) return 0; /* substring, line 87 */
+ z->bra = z->c; /* ], line 87 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0;
+ among_var = find_among_b(z, a_3, 5); /* among, line 97 */
+ if (!(among_var)) return 0;
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 97 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 98 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_12); /* <-, line 99 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 104 */
+ among_var = find_among_b(z, a_6, 51); /* substring, line 104 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 104 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 111 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 111 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 113 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 113 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 114 */
+ z->ket = z->c; /* [, line 114 */
+ if (!(eq_s_b(z, 2, s_13))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 114 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 114 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 114 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 117 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_14); /* <-, line 117 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 119 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_15); /* <-, line 119 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 121 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 4, s_16); /* <-, line 121 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 123 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 123 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 125 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 125 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 126 */
+ z->ket = z->c; /* [, line 127 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab1; }
+ among_var = find_among_b(z, a_4, 4); /* substring, line 127 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 127 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 127 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 127 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab1; }
+ case 1:
+ z->ket = z->c; /* [, line 128 */
+ if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 128 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 128 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 128 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab1:
+ ;
+ }
+ break;
+ case 8:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 135 */
+ z->ket = z->c; /* [, line 136 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab2; }
+ among_var = find_among_b(z, a_5, 3); /* substring, line 136 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab2; }
+ z->bra = z->c; /* ], line 136 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab2; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 137 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 137 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab2:
+ ;
+ }
+ break;
+ case 9:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 142 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 142 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 143 */
+ z->ket = z->c; /* [, line 143 */
+ if (!(eq_s_b(z, 2, s_18))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 143 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 143 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 143 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 143 */
+ if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 143 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 143 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 143 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ ;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 148 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 148 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 149 */
+ among_var = find_among_b(z, a_7, 87); /* substring, line 149 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 149 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 163 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_vowel_suffix(struct SN_env * z) {
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 171 */
+ z->ket = z->c; /* [, line 172 */
+ if (in_grouping_b_U(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 172 */
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 172 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 172 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 173 */
+ if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 173 */
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 173 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 173 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 175 */
+ z->ket = z->c; /* [, line 176 */
+ if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 176 */
+ if (in_grouping_b_U(z, g_CG, 99, 103, 0)) { z->c = z->l - m_keep; goto lab1; }
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call RV, line 176 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 176 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ ;
+ }
+ return 1;
+}
+
+extern int italian_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 182 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 182 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 183 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 183 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 184 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 185 */
+ { int ret = r_attached_pronoun(z);
+ if (ret == 0) goto lab2; /* call attached_pronoun, line 185 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 186 */
+ { int m5 = z->l - z->c; (void)m5; /* or, line 186 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab5; /* call standard_suffix, line 186 */
+ if (ret < 0) return ret;
+ }
+ goto lab4;
+ lab5:
+ z->c = z->l - m5;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab3; /* call verb_suffix, line 186 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab4:
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* do, line 187 */
+ { int ret = r_vowel_suffix(z);
+ if (ret == 0) goto lab6; /* call vowel_suffix, line 187 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m6;
+ }
+ z->c = z->lb;
+ { int c7 = z->c; /* do, line 189 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab7; /* call postlude, line 189 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = c7;
+ }
+ return 1;
+}
+
+extern struct SN_env * italian_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void italian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c b/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c
new file mode 100644
index 00000000000..cbb0cd4601c
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c
@@ -0,0 +1,299 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int norwegian_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_other_suffix(struct SN_env * z);
+static int r_consonant_pair(struct SN_env * z);
+static int r_main_suffix(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * norwegian_UTF_8_create_env(void);
+extern void norwegian_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[1] = { 'a' };
+static const symbol s_0_1[1] = { 'e' };
+static const symbol s_0_2[3] = { 'e', 'd', 'e' };
+static const symbol s_0_3[4] = { 'a', 'n', 'd', 'e' };
+static const symbol s_0_4[4] = { 'e', 'n', 'd', 'e' };
+static const symbol s_0_5[3] = { 'a', 'n', 'e' };
+static const symbol s_0_6[3] = { 'e', 'n', 'e' };
+static const symbol s_0_7[6] = { 'h', 'e', 't', 'e', 'n', 'e' };
+static const symbol s_0_8[4] = { 'e', 'r', 't', 'e' };
+static const symbol s_0_9[2] = { 'e', 'n' };
+static const symbol s_0_10[5] = { 'h', 'e', 't', 'e', 'n' };
+static const symbol s_0_11[2] = { 'a', 'r' };
+static const symbol s_0_12[2] = { 'e', 'r' };
+static const symbol s_0_13[5] = { 'h', 'e', 't', 'e', 'r' };
+static const symbol s_0_14[1] = { 's' };
+static const symbol s_0_15[2] = { 'a', 's' };
+static const symbol s_0_16[2] = { 'e', 's' };
+static const symbol s_0_17[4] = { 'e', 'd', 'e', 's' };
+static const symbol s_0_18[5] = { 'e', 'n', 'd', 'e', 's' };
+static const symbol s_0_19[4] = { 'e', 'n', 'e', 's' };
+static const symbol s_0_20[7] = { 'h', 'e', 't', 'e', 'n', 'e', 's' };
+static const symbol s_0_21[3] = { 'e', 'n', 's' };
+static const symbol s_0_22[6] = { 'h', 'e', 't', 'e', 'n', 's' };
+static const symbol s_0_23[3] = { 'e', 'r', 's' };
+static const symbol s_0_24[3] = { 'e', 't', 's' };
+static const symbol s_0_25[2] = { 'e', 't' };
+static const symbol s_0_26[3] = { 'h', 'e', 't' };
+static const symbol s_0_27[3] = { 'e', 'r', 't' };
+static const symbol s_0_28[3] = { 'a', 's', 't' };
+
+static const struct among a_0[29] =
+{
+/* 0 */ { 1, s_0_0, -1, 1, 0},
+/* 1 */ { 1, s_0_1, -1, 1, 0},
+/* 2 */ { 3, s_0_2, 1, 1, 0},
+/* 3 */ { 4, s_0_3, 1, 1, 0},
+/* 4 */ { 4, s_0_4, 1, 1, 0},
+/* 5 */ { 3, s_0_5, 1, 1, 0},
+/* 6 */ { 3, s_0_6, 1, 1, 0},
+/* 7 */ { 6, s_0_7, 6, 1, 0},
+/* 8 */ { 4, s_0_8, 1, 3, 0},
+/* 9 */ { 2, s_0_9, -1, 1, 0},
+/* 10 */ { 5, s_0_10, 9, 1, 0},
+/* 11 */ { 2, s_0_11, -1, 1, 0},
+/* 12 */ { 2, s_0_12, -1, 1, 0},
+/* 13 */ { 5, s_0_13, 12, 1, 0},
+/* 14 */ { 1, s_0_14, -1, 2, 0},
+/* 15 */ { 2, s_0_15, 14, 1, 0},
+/* 16 */ { 2, s_0_16, 14, 1, 0},
+/* 17 */ { 4, s_0_17, 16, 1, 0},
+/* 18 */ { 5, s_0_18, 16, 1, 0},
+/* 19 */ { 4, s_0_19, 16, 1, 0},
+/* 20 */ { 7, s_0_20, 19, 1, 0},
+/* 21 */ { 3, s_0_21, 14, 1, 0},
+/* 22 */ { 6, s_0_22, 21, 1, 0},
+/* 23 */ { 3, s_0_23, 14, 1, 0},
+/* 24 */ { 3, s_0_24, 14, 1, 0},
+/* 25 */ { 2, s_0_25, -1, 1, 0},
+/* 26 */ { 3, s_0_26, 25, 1, 0},
+/* 27 */ { 3, s_0_27, -1, 3, 0},
+/* 28 */ { 3, s_0_28, -1, 1, 0}
+};
+
+static const symbol s_1_0[2] = { 'd', 't' };
+static const symbol s_1_1[2] = { 'v', 't' };
+
+static const struct among a_1[2] =
+{
+/* 0 */ { 2, s_1_0, -1, -1, 0},
+/* 1 */ { 2, s_1_1, -1, -1, 0}
+};
+
+static const symbol s_2_0[3] = { 'l', 'e', 'g' };
+static const symbol s_2_1[4] = { 'e', 'l', 'e', 'g' };
+static const symbol s_2_2[2] = { 'i', 'g' };
+static const symbol s_2_3[3] = { 'e', 'i', 'g' };
+static const symbol s_2_4[3] = { 'l', 'i', 'g' };
+static const symbol s_2_5[4] = { 'e', 'l', 'i', 'g' };
+static const symbol s_2_6[3] = { 'e', 'l', 's' };
+static const symbol s_2_7[3] = { 'l', 'o', 'v' };
+static const symbol s_2_8[4] = { 'e', 'l', 'o', 'v' };
+static const symbol s_2_9[4] = { 's', 'l', 'o', 'v' };
+static const symbol s_2_10[7] = { 'h', 'e', 't', 's', 'l', 'o', 'v' };
+
+static const struct among a_2[11] =
+{
+/* 0 */ { 3, s_2_0, -1, 1, 0},
+/* 1 */ { 4, s_2_1, 0, 1, 0},
+/* 2 */ { 2, s_2_2, -1, 1, 0},
+/* 3 */ { 3, s_2_3, 2, 1, 0},
+/* 4 */ { 3, s_2_4, 2, 1, 0},
+/* 5 */ { 4, s_2_5, 4, 1, 0},
+/* 6 */ { 3, s_2_6, -1, 1, 0},
+/* 7 */ { 3, s_2_7, -1, 1, 0},
+/* 8 */ { 4, s_2_8, 7, 1, 0},
+/* 9 */ { 4, s_2_9, 7, 1, 0},
+/* 10 */ { 7, s_2_10, 9, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 };
+
+static const unsigned char g_s_ending[] = { 119, 125, 149, 1 };
+
+static const symbol s_0[] = { 'k' };
+static const symbol s_1[] = { 'e', 'r' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ { int c_test = z->c; /* test, line 30 */
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3);
+ if (ret < 0) return 0;
+ z->c = ret; /* hop, line 30 */
+ }
+ z->I[1] = z->c; /* setmark x, line 30 */
+ z->c = c_test;
+ }
+ if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 31 */
+ { /* gopast */ /* non v, line 31 */
+ int ret = in_grouping_U(z, g_v, 97, 248, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 31 */
+ /* try, line 32 */
+ if (!(z->I[0] < z->I[1])) goto lab0;
+ z->I[0] = z->I[1];
+lab0:
+ return 1;
+}
+
+static int r_main_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 38 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 38 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 38 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_0, 29); /* substring, line 38 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 38 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 44 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m2 = z->l - z->c; (void)m2; /* or, line 46 */
+ if (in_grouping_b_U(z, g_s_ending, 98, 122, 0)) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m2;
+ if (!(eq_s_b(z, 1, s_0))) return 0;
+ if (out_grouping_b_U(z, g_v, 97, 248, 0)) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 46 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 2, s_1); /* <-, line 48 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_consonant_pair(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 53 */
+ { int mlimit; /* setlimit, line 54 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 54 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 54 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit; return 0; }
+ if (!(find_among_b(z, a_1, 2))) { z->lb = mlimit; return 0; } /* substring, line 54 */
+ z->bra = z->c; /* ], line 54 */
+ z->lb = mlimit;
+ }
+ z->c = z->l - m_test;
+ }
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 59 */
+ }
+ z->bra = z->c; /* ], line 59 */
+ { int ret = slice_del(z); /* delete, line 59 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_other_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 63 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 63 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 63 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_2, 11); /* substring, line 63 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 63 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 67 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int norwegian_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 74 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 74 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 75 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 76 */
+ { int ret = r_main_suffix(z);
+ if (ret == 0) goto lab1; /* call main_suffix, line 76 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 77 */
+ { int ret = r_consonant_pair(z);
+ if (ret == 0) goto lab2; /* call consonant_pair, line 77 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 78 */
+ { int ret = r_other_suffix(z);
+ if (ret == 0) goto lab3; /* call other_suffix, line 78 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * norwegian_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); }
+
+extern void norwegian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_porter.c b/src/backend/snowball/libstemmer/stem_UTF_8_porter.c
new file mode 100644
index 00000000000..421cc0e74a6
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_porter.c
@@ -0,0 +1,755 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int porter_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_Step_5b(struct SN_env * z);
+static int r_Step_5a(struct SN_env * z);
+static int r_Step_4(struct SN_env * z);
+static int r_Step_3(struct SN_env * z);
+static int r_Step_2(struct SN_env * z);
+static int r_Step_1c(struct SN_env * z);
+static int r_Step_1b(struct SN_env * z);
+static int r_Step_1a(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_shortv(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * porter_UTF_8_create_env(void);
+extern void porter_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[1] = { 's' };
+static const symbol s_0_1[3] = { 'i', 'e', 's' };
+static const symbol s_0_2[4] = { 's', 's', 'e', 's' };
+static const symbol s_0_3[2] = { 's', 's' };
+
+static const struct among a_0[4] =
+{
+/* 0 */ { 1, s_0_0, -1, 3, 0},
+/* 1 */ { 3, s_0_1, 0, 2, 0},
+/* 2 */ { 4, s_0_2, 0, 1, 0},
+/* 3 */ { 2, s_0_3, 0, -1, 0}
+};
+
+static const symbol s_1_1[2] = { 'b', 'b' };
+static const symbol s_1_2[2] = { 'd', 'd' };
+static const symbol s_1_3[2] = { 'f', 'f' };
+static const symbol s_1_4[2] = { 'g', 'g' };
+static const symbol s_1_5[2] = { 'b', 'l' };
+static const symbol s_1_6[2] = { 'm', 'm' };
+static const symbol s_1_7[2] = { 'n', 'n' };
+static const symbol s_1_8[2] = { 'p', 'p' };
+static const symbol s_1_9[2] = { 'r', 'r' };
+static const symbol s_1_10[2] = { 'a', 't' };
+static const symbol s_1_11[2] = { 't', 't' };
+static const symbol s_1_12[2] = { 'i', 'z' };
+
+static const struct among a_1[13] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 2, s_1_1, 0, 2, 0},
+/* 2 */ { 2, s_1_2, 0, 2, 0},
+/* 3 */ { 2, s_1_3, 0, 2, 0},
+/* 4 */ { 2, s_1_4, 0, 2, 0},
+/* 5 */ { 2, s_1_5, 0, 1, 0},
+/* 6 */ { 2, s_1_6, 0, 2, 0},
+/* 7 */ { 2, s_1_7, 0, 2, 0},
+/* 8 */ { 2, s_1_8, 0, 2, 0},
+/* 9 */ { 2, s_1_9, 0, 2, 0},
+/* 10 */ { 2, s_1_10, 0, 1, 0},
+/* 11 */ { 2, s_1_11, 0, 2, 0},
+/* 12 */ { 2, s_1_12, 0, 1, 0}
+};
+
+static const symbol s_2_0[2] = { 'e', 'd' };
+static const symbol s_2_1[3] = { 'e', 'e', 'd' };
+static const symbol s_2_2[3] = { 'i', 'n', 'g' };
+
+static const struct among a_2[3] =
+{
+/* 0 */ { 2, s_2_0, -1, 2, 0},
+/* 1 */ { 3, s_2_1, 0, 1, 0},
+/* 2 */ { 3, s_2_2, -1, 2, 0}
+};
+
+static const symbol s_3_0[4] = { 'a', 'n', 'c', 'i' };
+static const symbol s_3_1[4] = { 'e', 'n', 'c', 'i' };
+static const symbol s_3_2[4] = { 'a', 'b', 'l', 'i' };
+static const symbol s_3_3[3] = { 'e', 'l', 'i' };
+static const symbol s_3_4[4] = { 'a', 'l', 'l', 'i' };
+static const symbol s_3_5[5] = { 'o', 'u', 's', 'l', 'i' };
+static const symbol s_3_6[5] = { 'e', 'n', 't', 'l', 'i' };
+static const symbol s_3_7[5] = { 'a', 'l', 'i', 't', 'i' };
+static const symbol s_3_8[6] = { 'b', 'i', 'l', 'i', 't', 'i' };
+static const symbol s_3_9[5] = { 'i', 'v', 'i', 't', 'i' };
+static const symbol s_3_10[6] = { 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_3_11[7] = { 'a', 't', 'i', 'o', 'n', 'a', 'l' };
+static const symbol s_3_12[5] = { 'a', 'l', 'i', 's', 'm' };
+static const symbol s_3_13[5] = { 'a', 't', 'i', 'o', 'n' };
+static const symbol s_3_14[7] = { 'i', 'z', 'a', 't', 'i', 'o', 'n' };
+static const symbol s_3_15[4] = { 'i', 'z', 'e', 'r' };
+static const symbol s_3_16[4] = { 'a', 't', 'o', 'r' };
+static const symbol s_3_17[7] = { 'i', 'v', 'e', 'n', 'e', 's', 's' };
+static const symbol s_3_18[7] = { 'f', 'u', 'l', 'n', 'e', 's', 's' };
+static const symbol s_3_19[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' };
+
+static const struct among a_3[20] =
+{
+/* 0 */ { 4, s_3_0, -1, 3, 0},
+/* 1 */ { 4, s_3_1, -1, 2, 0},
+/* 2 */ { 4, s_3_2, -1, 4, 0},
+/* 3 */ { 3, s_3_3, -1, 6, 0},
+/* 4 */ { 4, s_3_4, -1, 9, 0},
+/* 5 */ { 5, s_3_5, -1, 12, 0},
+/* 6 */ { 5, s_3_6, -1, 5, 0},
+/* 7 */ { 5, s_3_7, -1, 10, 0},
+/* 8 */ { 6, s_3_8, -1, 14, 0},
+/* 9 */ { 5, s_3_9, -1, 13, 0},
+/* 10 */ { 6, s_3_10, -1, 1, 0},
+/* 11 */ { 7, s_3_11, 10, 8, 0},
+/* 12 */ { 5, s_3_12, -1, 10, 0},
+/* 13 */ { 5, s_3_13, -1, 8, 0},
+/* 14 */ { 7, s_3_14, 13, 7, 0},
+/* 15 */ { 4, s_3_15, -1, 7, 0},
+/* 16 */ { 4, s_3_16, -1, 8, 0},
+/* 17 */ { 7, s_3_17, -1, 13, 0},
+/* 18 */ { 7, s_3_18, -1, 11, 0},
+/* 19 */ { 7, s_3_19, -1, 12, 0}
+};
+
+static const symbol s_4_0[5] = { 'i', 'c', 'a', 't', 'e' };
+static const symbol s_4_1[5] = { 'a', 't', 'i', 'v', 'e' };
+static const symbol s_4_2[5] = { 'a', 'l', 'i', 'z', 'e' };
+static const symbol s_4_3[5] = { 'i', 'c', 'i', 't', 'i' };
+static const symbol s_4_4[4] = { 'i', 'c', 'a', 'l' };
+static const symbol s_4_5[3] = { 'f', 'u', 'l' };
+static const symbol s_4_6[4] = { 'n', 'e', 's', 's' };
+
+static const struct among a_4[7] =
+{
+/* 0 */ { 5, s_4_0, -1, 2, 0},
+/* 1 */ { 5, s_4_1, -1, 3, 0},
+/* 2 */ { 5, s_4_2, -1, 1, 0},
+/* 3 */ { 5, s_4_3, -1, 2, 0},
+/* 4 */ { 4, s_4_4, -1, 2, 0},
+/* 5 */ { 3, s_4_5, -1, 3, 0},
+/* 6 */ { 4, s_4_6, -1, 3, 0}
+};
+
+static const symbol s_5_0[2] = { 'i', 'c' };
+static const symbol s_5_1[4] = { 'a', 'n', 'c', 'e' };
+static const symbol s_5_2[4] = { 'e', 'n', 'c', 'e' };
+static const symbol s_5_3[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_5_4[4] = { 'i', 'b', 'l', 'e' };
+static const symbol s_5_5[3] = { 'a', 't', 'e' };
+static const symbol s_5_6[3] = { 'i', 'v', 'e' };
+static const symbol s_5_7[3] = { 'i', 'z', 'e' };
+static const symbol s_5_8[3] = { 'i', 't', 'i' };
+static const symbol s_5_9[2] = { 'a', 'l' };
+static const symbol s_5_10[3] = { 'i', 's', 'm' };
+static const symbol s_5_11[3] = { 'i', 'o', 'n' };
+static const symbol s_5_12[2] = { 'e', 'r' };
+static const symbol s_5_13[3] = { 'o', 'u', 's' };
+static const symbol s_5_14[3] = { 'a', 'n', 't' };
+static const symbol s_5_15[3] = { 'e', 'n', 't' };
+static const symbol s_5_16[4] = { 'm', 'e', 'n', 't' };
+static const symbol s_5_17[5] = { 'e', 'm', 'e', 'n', 't' };
+static const symbol s_5_18[2] = { 'o', 'u' };
+
+static const struct among a_5[19] =
+{
+/* 0 */ { 2, s_5_0, -1, 1, 0},
+/* 1 */ { 4, s_5_1, -1, 1, 0},
+/* 2 */ { 4, s_5_2, -1, 1, 0},
+/* 3 */ { 4, s_5_3, -1, 1, 0},
+/* 4 */ { 4, s_5_4, -1, 1, 0},
+/* 5 */ { 3, s_5_5, -1, 1, 0},
+/* 6 */ { 3, s_5_6, -1, 1, 0},
+/* 7 */ { 3, s_5_7, -1, 1, 0},
+/* 8 */ { 3, s_5_8, -1, 1, 0},
+/* 9 */ { 2, s_5_9, -1, 1, 0},
+/* 10 */ { 3, s_5_10, -1, 1, 0},
+/* 11 */ { 3, s_5_11, -1, 2, 0},
+/* 12 */ { 2, s_5_12, -1, 1, 0},
+/* 13 */ { 3, s_5_13, -1, 1, 0},
+/* 14 */ { 3, s_5_14, -1, 1, 0},
+/* 15 */ { 3, s_5_15, -1, 1, 0},
+/* 16 */ { 4, s_5_16, 15, 1, 0},
+/* 17 */ { 5, s_5_17, 16, 1, 0},
+/* 18 */ { 2, s_5_18, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1 };
+
+static const unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 };
+
+static const symbol s_0[] = { 's', 's' };
+static const symbol s_1[] = { 'i' };
+static const symbol s_2[] = { 'e', 'e' };
+static const symbol s_3[] = { 'e' };
+static const symbol s_4[] = { 'e' };
+static const symbol s_5[] = { 'y' };
+static const symbol s_6[] = { 'Y' };
+static const symbol s_7[] = { 'i' };
+static const symbol s_8[] = { 't', 'i', 'o', 'n' };
+static const symbol s_9[] = { 'e', 'n', 'c', 'e' };
+static const symbol s_10[] = { 'a', 'n', 'c', 'e' };
+static const symbol s_11[] = { 'a', 'b', 'l', 'e' };
+static const symbol s_12[] = { 'e', 'n', 't' };
+static const symbol s_13[] = { 'e' };
+static const symbol s_14[] = { 'i', 'z', 'e' };
+static const symbol s_15[] = { 'a', 't', 'e' };
+static const symbol s_16[] = { 'a', 'l' };
+static const symbol s_17[] = { 'a', 'l' };
+static const symbol s_18[] = { 'f', 'u', 'l' };
+static const symbol s_19[] = { 'o', 'u', 's' };
+static const symbol s_20[] = { 'i', 'v', 'e' };
+static const symbol s_21[] = { 'b', 'l', 'e' };
+static const symbol s_22[] = { 'a', 'l' };
+static const symbol s_23[] = { 'i', 'c' };
+static const symbol s_24[] = { 's' };
+static const symbol s_25[] = { 't' };
+static const symbol s_26[] = { 'e' };
+static const symbol s_27[] = { 'l' };
+static const symbol s_28[] = { 'l' };
+static const symbol s_29[] = { 'y' };
+static const symbol s_30[] = { 'Y' };
+static const symbol s_31[] = { 'y' };
+static const symbol s_32[] = { 'Y' };
+static const symbol s_33[] = { 'Y' };
+static const symbol s_34[] = { 'y' };
+
+static int r_shortv(struct SN_env * z) {
+ if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) return 0;
+ if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0;
+ if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_Step_1a(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 25 */
+ if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0;
+ among_var = find_among_b(z, a_0, 4); /* substring, line 25 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 25 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_0); /* <-, line 26 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 27 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 29 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_1b(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 34 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0;
+ among_var = find_among_b(z, a_2, 3); /* substring, line 34 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 34 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 35 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 2, s_2); /* <-, line 35 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m_test = z->l - z->c; /* test, line 38 */
+ { /* gopast */ /* grouping v, line 38 */
+ int ret = out_grouping_b_U(z, g_v, 97, 121, 1);
+ if (ret < 0) return 0;
+ z->c -= ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int ret = slice_del(z); /* delete, line 38 */
+ if (ret < 0) return ret;
+ }
+ { int m_test = z->l - z->c; /* test, line 39 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else
+ among_var = find_among_b(z, a_1, 13); /* substring, line 39 */
+ if (!(among_var)) return 0;
+ z->c = z->l - m_test;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ z->ket = z->c; /* [, line 44 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 44 */
+ }
+ z->bra = z->c; /* ], line 44 */
+ { int ret = slice_del(z); /* delete, line 44 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ if (z->c != z->I[0]) return 0; /* atmark, line 45 */
+ { int m_test = z->l - z->c; /* test, line 45 */
+ { int ret = r_shortv(z);
+ if (ret == 0) return 0; /* call shortv, line 45 */
+ if (ret < 0) return ret;
+ }
+ z->c = z->l - m_test;
+ }
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_1c(struct SN_env * z) {
+ z->ket = z->c; /* [, line 52 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 52 */
+ if (!(eq_s_b(z, 1, s_5))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_6))) return 0;
+ }
+lab0:
+ z->bra = z->c; /* ], line 52 */
+ { /* gopast */ /* grouping v, line 53 */
+ int ret = out_grouping_b_U(z, g_v, 97, 121, 1);
+ if (ret < 0) return 0;
+ z->c -= ret;
+ }
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 54 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_Step_2(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 58 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_3, 20); /* substring, line 58 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 58 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 58 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 4, s_8); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 4, s_9); /* <-, line 60 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 4, s_10); /* <-, line 61 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 4, s_11); /* <-, line 62 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 3, s_12); /* <-, line 63 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 64 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 3, s_14); /* <-, line 66 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 8:
+ { int ret = slice_from_s(z, 3, s_15); /* <-, line 68 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 9:
+ { int ret = slice_from_s(z, 2, s_16); /* <-, line 69 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 10:
+ { int ret = slice_from_s(z, 2, s_17); /* <-, line 71 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 11:
+ { int ret = slice_from_s(z, 3, s_18); /* <-, line 72 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 12:
+ { int ret = slice_from_s(z, 3, s_19); /* <-, line 74 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 13:
+ { int ret = slice_from_s(z, 3, s_20); /* <-, line 76 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 14:
+ { int ret = slice_from_s(z, 3, s_21); /* <-, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_3(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 82 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_4, 7); /* substring, line 82 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 82 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 82 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_22); /* <-, line 83 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 2, s_23); /* <-, line 85 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 87 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_4(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 92 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_5, 19); /* substring, line 92 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 92 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 92 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 95 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 96 */
+ if (!(eq_s_b(z, 1, s_24))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_25))) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 96 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_Step_5a(struct SN_env * z) {
+ z->ket = z->c; /* [, line 101 */
+ if (!(eq_s_b(z, 1, s_26))) return 0;
+ z->bra = z->c; /* ], line 101 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 102 */
+ { int ret = r_R2(z);
+ if (ret == 0) goto lab1; /* call R2, line 102 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* not, line 102 */
+ { int ret = r_shortv(z);
+ if (ret == 0) goto lab2; /* call shortv, line 102 */
+ if (ret < 0) return ret;
+ }
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ }
+lab0:
+ { int ret = slice_del(z); /* delete, line 103 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_Step_5b(struct SN_env * z) {
+ z->ket = z->c; /* [, line 107 */
+ if (!(eq_s_b(z, 1, s_27))) return 0;
+ z->bra = z->c; /* ], line 107 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 108 */
+ if (ret < 0) return ret;
+ }
+ if (!(eq_s_b(z, 1, s_28))) return 0;
+ { int ret = slice_del(z); /* delete, line 109 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern int porter_UTF_8_stem(struct SN_env * z) {
+ z->B[0] = 0; /* unset Y_found, line 115 */
+ { int c1 = z->c; /* do, line 116 */
+ z->bra = z->c; /* [, line 116 */
+ if (!(eq_s(z, 1, s_29))) goto lab0;
+ z->ket = z->c; /* ], line 116 */
+ { int ret = slice_from_s(z, 1, s_30); /* <-, line 116 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set Y_found, line 116 */
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 117 */
+ while(1) { /* repeat, line 117 */
+ int c3 = z->c;
+ while(1) { /* goto, line 117 */
+ int c4 = z->c;
+ if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab3;
+ z->bra = z->c; /* [, line 117 */
+ if (!(eq_s(z, 1, s_31))) goto lab3;
+ z->ket = z->c; /* ], line 117 */
+ z->c = c4;
+ break;
+ lab3:
+ z->c = c4;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab2;
+ z->c = ret; /* goto, line 117 */
+ }
+ }
+ { int ret = slice_from_s(z, 1, s_32); /* <-, line 117 */
+ if (ret < 0) return ret;
+ }
+ z->B[0] = 1; /* set Y_found, line 117 */
+ continue;
+ lab2:
+ z->c = c3;
+ break;
+ }
+ z->c = c2;
+ }
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { int c5 = z->c; /* do, line 121 */
+ { /* gopast */ /* grouping v, line 122 */
+ int ret = out_grouping_U(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 122 */
+ int ret = in_grouping_U(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 122 */
+ { /* gopast */ /* grouping v, line 123 */
+ int ret = out_grouping_U(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 123 */
+ int ret = in_grouping_U(z, g_v, 97, 121, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 123 */
+ lab4:
+ z->c = c5;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 126 */
+
+ { int m6 = z->l - z->c; (void)m6; /* do, line 127 */
+ { int ret = r_Step_1a(z);
+ if (ret == 0) goto lab5; /* call Step_1a, line 127 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ z->c = z->l - m6;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 128 */
+ { int ret = r_Step_1b(z);
+ if (ret == 0) goto lab6; /* call Step_1b, line 128 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m7;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 129 */
+ { int ret = r_Step_1c(z);
+ if (ret == 0) goto lab7; /* call Step_1c, line 129 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m8;
+ }
+ { int m9 = z->l - z->c; (void)m9; /* do, line 130 */
+ { int ret = r_Step_2(z);
+ if (ret == 0) goto lab8; /* call Step_2, line 130 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = z->l - m9;
+ }
+ { int m10 = z->l - z->c; (void)m10; /* do, line 131 */
+ { int ret = r_Step_3(z);
+ if (ret == 0) goto lab9; /* call Step_3, line 131 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m10;
+ }
+ { int m11 = z->l - z->c; (void)m11; /* do, line 132 */
+ { int ret = r_Step_4(z);
+ if (ret == 0) goto lab10; /* call Step_4, line 132 */
+ if (ret < 0) return ret;
+ }
+ lab10:
+ z->c = z->l - m11;
+ }
+ { int m12 = z->l - z->c; (void)m12; /* do, line 133 */
+ { int ret = r_Step_5a(z);
+ if (ret == 0) goto lab11; /* call Step_5a, line 133 */
+ if (ret < 0) return ret;
+ }
+ lab11:
+ z->c = z->l - m12;
+ }
+ { int m13 = z->l - z->c; (void)m13; /* do, line 134 */
+ { int ret = r_Step_5b(z);
+ if (ret == 0) goto lab12; /* call Step_5b, line 134 */
+ if (ret < 0) return ret;
+ }
+ lab12:
+ z->c = z->l - m13;
+ }
+ z->c = z->lb;
+ { int c14 = z->c; /* do, line 137 */
+ if (!(z->B[0])) goto lab13; /* Boolean test Y_found, line 137 */
+ while(1) { /* repeat, line 137 */
+ int c15 = z->c;
+ while(1) { /* goto, line 137 */
+ int c16 = z->c;
+ z->bra = z->c; /* [, line 137 */
+ if (!(eq_s(z, 1, s_33))) goto lab15;
+ z->ket = z->c; /* ], line 137 */
+ z->c = c16;
+ break;
+ lab15:
+ z->c = c16;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab14;
+ z->c = ret; /* goto, line 137 */
+ }
+ }
+ { int ret = slice_from_s(z, 1, s_34); /* <-, line 137 */
+ if (ret < 0) return ret;
+ }
+ continue;
+ lab14:
+ z->c = c15;
+ break;
+ }
+ lab13:
+ z->c = c14;
+ }
+ return 1;
+}
+
+extern struct SN_env * porter_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); }
+
+extern void porter_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c b/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c
new file mode 100644
index 00000000000..8939cfe016a
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c
@@ -0,0 +1,1023 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int portuguese_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_residual_form(struct SN_env * z);
+static int r_residual_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * portuguese_UTF_8_create_env(void);
+extern void portuguese_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[2] = { 0xC3, 0xA3 };
+static const symbol s_0_2[2] = { 0xC3, 0xB5 };
+
+static const struct among a_0[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 2, s_0_1, 0, 1, 0},
+/* 2 */ { 2, s_0_2, 0, 2, 0}
+};
+
+static const symbol s_1_1[2] = { 'a', '~' };
+static const symbol s_1_2[2] = { 'o', '~' };
+
+static const struct among a_1[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 2, s_1_1, 0, 1, 0},
+/* 2 */ { 2, s_1_2, 0, 2, 0}
+};
+
+static const symbol s_2_0[2] = { 'i', 'c' };
+static const symbol s_2_1[2] = { 'a', 'd' };
+static const symbol s_2_2[2] = { 'o', 's' };
+static const symbol s_2_3[2] = { 'i', 'v' };
+
+static const struct among a_2[4] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 2, s_2_1, -1, -1, 0},
+/* 2 */ { 2, s_2_2, -1, -1, 0},
+/* 3 */ { 2, s_2_3, -1, 1, 0}
+};
+
+static const symbol s_3_0[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_3_1[4] = { 'a', 'v', 'e', 'l' };
+static const symbol s_3_2[5] = { 0xC3, 0xAD, 'v', 'e', 'l' };
+
+static const struct among a_3[3] =
+{
+/* 0 */ { 4, s_3_0, -1, 1, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0},
+/* 2 */ { 5, s_3_2, -1, 1, 0}
+};
+
+static const symbol s_4_0[2] = { 'i', 'c' };
+static const symbol s_4_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_4_2[2] = { 'i', 'v' };
+
+static const struct among a_4[3] =
+{
+/* 0 */ { 2, s_4_0, -1, 1, 0},
+/* 1 */ { 4, s_4_1, -1, 1, 0},
+/* 2 */ { 2, s_4_2, -1, 1, 0}
+};
+
+static const symbol s_5_0[3] = { 'i', 'c', 'a' };
+static const symbol s_5_1[6] = { 0xC3, 0xA2, 'n', 'c', 'i', 'a' };
+static const symbol s_5_2[6] = { 0xC3, 0xAA, 'n', 'c', 'i', 'a' };
+static const symbol s_5_3[3] = { 'i', 'r', 'a' };
+static const symbol s_5_4[5] = { 'a', 'd', 'o', 'r', 'a' };
+static const symbol s_5_5[3] = { 'o', 's', 'a' };
+static const symbol s_5_6[4] = { 'i', 's', 't', 'a' };
+static const symbol s_5_7[3] = { 'i', 'v', 'a' };
+static const symbol s_5_8[3] = { 'e', 'z', 'a' };
+static const symbol s_5_9[6] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a' };
+static const symbol s_5_10[5] = { 'i', 'd', 'a', 'd', 'e' };
+static const symbol s_5_11[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_5_12[5] = { 'm', 'e', 'n', 't', 'e' };
+static const symbol s_5_13[6] = { 'a', 'm', 'e', 'n', 't', 'e' };
+static const symbol s_5_14[5] = { 0xC3, 0xA1, 'v', 'e', 'l' };
+static const symbol s_5_15[5] = { 0xC3, 0xAD, 'v', 'e', 'l' };
+static const symbol s_5_16[6] = { 'u', 'c', 'i', 0xC3, 0xB3, 'n' };
+static const symbol s_5_17[3] = { 'i', 'c', 'o' };
+static const symbol s_5_18[4] = { 'i', 's', 'm', 'o' };
+static const symbol s_5_19[3] = { 'o', 's', 'o' };
+static const symbol s_5_20[6] = { 'a', 'm', 'e', 'n', 't', 'o' };
+static const symbol s_5_21[6] = { 'i', 'm', 'e', 'n', 't', 'o' };
+static const symbol s_5_22[3] = { 'i', 'v', 'o' };
+static const symbol s_5_23[6] = { 'a', 0xC3, 0xA7, 'a', '~', 'o' };
+static const symbol s_5_24[4] = { 'a', 'd', 'o', 'r' };
+static const symbol s_5_25[4] = { 'i', 'c', 'a', 's' };
+static const symbol s_5_26[7] = { 0xC3, 0xAA, 'n', 'c', 'i', 'a', 's' };
+static const symbol s_5_27[4] = { 'i', 'r', 'a', 's' };
+static const symbol s_5_28[6] = { 'a', 'd', 'o', 'r', 'a', 's' };
+static const symbol s_5_29[4] = { 'o', 's', 'a', 's' };
+static const symbol s_5_30[5] = { 'i', 's', 't', 'a', 's' };
+static const symbol s_5_31[4] = { 'i', 'v', 'a', 's' };
+static const symbol s_5_32[4] = { 'e', 'z', 'a', 's' };
+static const symbol s_5_33[7] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a', 's' };
+static const symbol s_5_34[6] = { 'i', 'd', 'a', 'd', 'e', 's' };
+static const symbol s_5_35[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' };
+static const symbol s_5_36[6] = { 'a', 'd', 'o', 'r', 'e', 's' };
+static const symbol s_5_37[5] = { 'a', 'n', 't', 'e', 's' };
+static const symbol s_5_38[7] = { 'a', 0xC3, 0xA7, 'o', '~', 'e', 's' };
+static const symbol s_5_39[4] = { 'i', 'c', 'o', 's' };
+static const symbol s_5_40[5] = { 'i', 's', 'm', 'o', 's' };
+static const symbol s_5_41[4] = { 'o', 's', 'o', 's' };
+static const symbol s_5_42[7] = { 'a', 'm', 'e', 'n', 't', 'o', 's' };
+static const symbol s_5_43[7] = { 'i', 'm', 'e', 'n', 't', 'o', 's' };
+static const symbol s_5_44[4] = { 'i', 'v', 'o', 's' };
+
+static const struct among a_5[45] =
+{
+/* 0 */ { 3, s_5_0, -1, 1, 0},
+/* 1 */ { 6, s_5_1, -1, 1, 0},
+/* 2 */ { 6, s_5_2, -1, 4, 0},
+/* 3 */ { 3, s_5_3, -1, 9, 0},
+/* 4 */ { 5, s_5_4, -1, 1, 0},
+/* 5 */ { 3, s_5_5, -1, 1, 0},
+/* 6 */ { 4, s_5_6, -1, 1, 0},
+/* 7 */ { 3, s_5_7, -1, 8, 0},
+/* 8 */ { 3, s_5_8, -1, 1, 0},
+/* 9 */ { 6, s_5_9, -1, 2, 0},
+/* 10 */ { 5, s_5_10, -1, 7, 0},
+/* 11 */ { 4, s_5_11, -1, 1, 0},
+/* 12 */ { 5, s_5_12, -1, 6, 0},
+/* 13 */ { 6, s_5_13, 12, 5, 0},
+/* 14 */ { 5, s_5_14, -1, 1, 0},
+/* 15 */ { 5, s_5_15, -1, 1, 0},
+/* 16 */ { 6, s_5_16, -1, 3, 0},
+/* 17 */ { 3, s_5_17, -1, 1, 0},
+/* 18 */ { 4, s_5_18, -1, 1, 0},
+/* 19 */ { 3, s_5_19, -1, 1, 0},
+/* 20 */ { 6, s_5_20, -1, 1, 0},
+/* 21 */ { 6, s_5_21, -1, 1, 0},
+/* 22 */ { 3, s_5_22, -1, 8, 0},
+/* 23 */ { 6, s_5_23, -1, 1, 0},
+/* 24 */ { 4, s_5_24, -1, 1, 0},
+/* 25 */ { 4, s_5_25, -1, 1, 0},
+/* 26 */ { 7, s_5_26, -1, 4, 0},
+/* 27 */ { 4, s_5_27, -1, 9, 0},
+/* 28 */ { 6, s_5_28, -1, 1, 0},
+/* 29 */ { 4, s_5_29, -1, 1, 0},
+/* 30 */ { 5, s_5_30, -1, 1, 0},
+/* 31 */ { 4, s_5_31, -1, 8, 0},
+/* 32 */ { 4, s_5_32, -1, 1, 0},
+/* 33 */ { 7, s_5_33, -1, 2, 0},
+/* 34 */ { 6, s_5_34, -1, 7, 0},
+/* 35 */ { 7, s_5_35, -1, 3, 0},
+/* 36 */ { 6, s_5_36, -1, 1, 0},
+/* 37 */ { 5, s_5_37, -1, 1, 0},
+/* 38 */ { 7, s_5_38, -1, 1, 0},
+/* 39 */ { 4, s_5_39, -1, 1, 0},
+/* 40 */ { 5, s_5_40, -1, 1, 0},
+/* 41 */ { 4, s_5_41, -1, 1, 0},
+/* 42 */ { 7, s_5_42, -1, 1, 0},
+/* 43 */ { 7, s_5_43, -1, 1, 0},
+/* 44 */ { 4, s_5_44, -1, 8, 0}
+};
+
+static const symbol s_6_0[3] = { 'a', 'd', 'a' };
+static const symbol s_6_1[3] = { 'i', 'd', 'a' };
+static const symbol s_6_2[2] = { 'i', 'a' };
+static const symbol s_6_3[4] = { 'a', 'r', 'i', 'a' };
+static const symbol s_6_4[4] = { 'e', 'r', 'i', 'a' };
+static const symbol s_6_5[4] = { 'i', 'r', 'i', 'a' };
+static const symbol s_6_6[3] = { 'a', 'r', 'a' };
+static const symbol s_6_7[3] = { 'e', 'r', 'a' };
+static const symbol s_6_8[3] = { 'i', 'r', 'a' };
+static const symbol s_6_9[3] = { 'a', 'v', 'a' };
+static const symbol s_6_10[4] = { 'a', 's', 's', 'e' };
+static const symbol s_6_11[4] = { 'e', 's', 's', 'e' };
+static const symbol s_6_12[4] = { 'i', 's', 's', 'e' };
+static const symbol s_6_13[4] = { 'a', 's', 't', 'e' };
+static const symbol s_6_14[4] = { 'e', 's', 't', 'e' };
+static const symbol s_6_15[4] = { 'i', 's', 't', 'e' };
+static const symbol s_6_16[2] = { 'e', 'i' };
+static const symbol s_6_17[4] = { 'a', 'r', 'e', 'i' };
+static const symbol s_6_18[4] = { 'e', 'r', 'e', 'i' };
+static const symbol s_6_19[4] = { 'i', 'r', 'e', 'i' };
+static const symbol s_6_20[2] = { 'a', 'm' };
+static const symbol s_6_21[3] = { 'i', 'a', 'm' };
+static const symbol s_6_22[5] = { 'a', 'r', 'i', 'a', 'm' };
+static const symbol s_6_23[5] = { 'e', 'r', 'i', 'a', 'm' };
+static const symbol s_6_24[5] = { 'i', 'r', 'i', 'a', 'm' };
+static const symbol s_6_25[4] = { 'a', 'r', 'a', 'm' };
+static const symbol s_6_26[4] = { 'e', 'r', 'a', 'm' };
+static const symbol s_6_27[4] = { 'i', 'r', 'a', 'm' };
+static const symbol s_6_28[4] = { 'a', 'v', 'a', 'm' };
+static const symbol s_6_29[2] = { 'e', 'm' };
+static const symbol s_6_30[4] = { 'a', 'r', 'e', 'm' };
+static const symbol s_6_31[4] = { 'e', 'r', 'e', 'm' };
+static const symbol s_6_32[4] = { 'i', 'r', 'e', 'm' };
+static const symbol s_6_33[5] = { 'a', 's', 's', 'e', 'm' };
+static const symbol s_6_34[5] = { 'e', 's', 's', 'e', 'm' };
+static const symbol s_6_35[5] = { 'i', 's', 's', 'e', 'm' };
+static const symbol s_6_36[3] = { 'a', 'd', 'o' };
+static const symbol s_6_37[3] = { 'i', 'd', 'o' };
+static const symbol s_6_38[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_6_39[4] = { 'e', 'n', 'd', 'o' };
+static const symbol s_6_40[4] = { 'i', 'n', 'd', 'o' };
+static const symbol s_6_41[5] = { 'a', 'r', 'a', '~', 'o' };
+static const symbol s_6_42[5] = { 'e', 'r', 'a', '~', 'o' };
+static const symbol s_6_43[5] = { 'i', 'r', 'a', '~', 'o' };
+static const symbol s_6_44[2] = { 'a', 'r' };
+static const symbol s_6_45[2] = { 'e', 'r' };
+static const symbol s_6_46[2] = { 'i', 'r' };
+static const symbol s_6_47[2] = { 'a', 's' };
+static const symbol s_6_48[4] = { 'a', 'd', 'a', 's' };
+static const symbol s_6_49[4] = { 'i', 'd', 'a', 's' };
+static const symbol s_6_50[3] = { 'i', 'a', 's' };
+static const symbol s_6_51[5] = { 'a', 'r', 'i', 'a', 's' };
+static const symbol s_6_52[5] = { 'e', 'r', 'i', 'a', 's' };
+static const symbol s_6_53[5] = { 'i', 'r', 'i', 'a', 's' };
+static const symbol s_6_54[4] = { 'a', 'r', 'a', 's' };
+static const symbol s_6_55[4] = { 'e', 'r', 'a', 's' };
+static const symbol s_6_56[4] = { 'i', 'r', 'a', 's' };
+static const symbol s_6_57[4] = { 'a', 'v', 'a', 's' };
+static const symbol s_6_58[2] = { 'e', 's' };
+static const symbol s_6_59[5] = { 'a', 'r', 'd', 'e', 's' };
+static const symbol s_6_60[5] = { 'e', 'r', 'd', 'e', 's' };
+static const symbol s_6_61[5] = { 'i', 'r', 'd', 'e', 's' };
+static const symbol s_6_62[4] = { 'a', 'r', 'e', 's' };
+static const symbol s_6_63[4] = { 'e', 'r', 'e', 's' };
+static const symbol s_6_64[4] = { 'i', 'r', 'e', 's' };
+static const symbol s_6_65[5] = { 'a', 's', 's', 'e', 's' };
+static const symbol s_6_66[5] = { 'e', 's', 's', 'e', 's' };
+static const symbol s_6_67[5] = { 'i', 's', 's', 'e', 's' };
+static const symbol s_6_68[5] = { 'a', 's', 't', 'e', 's' };
+static const symbol s_6_69[5] = { 'e', 's', 't', 'e', 's' };
+static const symbol s_6_70[5] = { 'i', 's', 't', 'e', 's' };
+static const symbol s_6_71[2] = { 'i', 's' };
+static const symbol s_6_72[3] = { 'a', 'i', 's' };
+static const symbol s_6_73[3] = { 'e', 'i', 's' };
+static const symbol s_6_74[5] = { 'a', 'r', 'e', 'i', 's' };
+static const symbol s_6_75[5] = { 'e', 'r', 'e', 'i', 's' };
+static const symbol s_6_76[5] = { 'i', 'r', 'e', 'i', 's' };
+static const symbol s_6_77[6] = { 0xC3, 0xA1, 'r', 'e', 'i', 's' };
+static const symbol s_6_78[6] = { 0xC3, 0xA9, 'r', 'e', 'i', 's' };
+static const symbol s_6_79[6] = { 0xC3, 0xAD, 'r', 'e', 'i', 's' };
+static const symbol s_6_80[7] = { 0xC3, 0xA1, 's', 's', 'e', 'i', 's' };
+static const symbol s_6_81[7] = { 0xC3, 0xA9, 's', 's', 'e', 'i', 's' };
+static const symbol s_6_82[7] = { 0xC3, 0xAD, 's', 's', 'e', 'i', 's' };
+static const symbol s_6_83[6] = { 0xC3, 0xA1, 'v', 'e', 'i', 's' };
+static const symbol s_6_84[5] = { 0xC3, 0xAD, 'e', 'i', 's' };
+static const symbol s_6_85[7] = { 'a', 'r', 0xC3, 0xAD, 'e', 'i', 's' };
+static const symbol s_6_86[7] = { 'e', 'r', 0xC3, 0xAD, 'e', 'i', 's' };
+static const symbol s_6_87[7] = { 'i', 'r', 0xC3, 0xAD, 'e', 'i', 's' };
+static const symbol s_6_88[4] = { 'a', 'd', 'o', 's' };
+static const symbol s_6_89[4] = { 'i', 'd', 'o', 's' };
+static const symbol s_6_90[4] = { 'a', 'm', 'o', 's' };
+static const symbol s_6_91[7] = { 0xC3, 0xA1, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_6_92[7] = { 0xC3, 0xA9, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_6_93[7] = { 0xC3, 0xAD, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_6_94[7] = { 0xC3, 0xA1, 'v', 'a', 'm', 'o', 's' };
+static const symbol s_6_95[6] = { 0xC3, 0xAD, 'a', 'm', 'o', 's' };
+static const symbol s_6_96[8] = { 'a', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' };
+static const symbol s_6_97[8] = { 'e', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' };
+static const symbol s_6_98[8] = { 'i', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' };
+static const symbol s_6_99[4] = { 'e', 'm', 'o', 's' };
+static const symbol s_6_100[6] = { 'a', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_6_101[6] = { 'e', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_6_102[6] = { 'i', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_6_103[8] = { 0xC3, 0xA1, 's', 's', 'e', 'm', 'o', 's' };
+static const symbol s_6_104[8] = { 0xC3, 0xAA, 's', 's', 'e', 'm', 'o', 's' };
+static const symbol s_6_105[8] = { 0xC3, 0xAD, 's', 's', 'e', 'm', 'o', 's' };
+static const symbol s_6_106[4] = { 'i', 'm', 'o', 's' };
+static const symbol s_6_107[5] = { 'a', 'r', 'm', 'o', 's' };
+static const symbol s_6_108[5] = { 'e', 'r', 'm', 'o', 's' };
+static const symbol s_6_109[5] = { 'i', 'r', 'm', 'o', 's' };
+static const symbol s_6_110[5] = { 0xC3, 0xA1, 'm', 'o', 's' };
+static const symbol s_6_111[5] = { 'a', 'r', 0xC3, 0xA1, 's' };
+static const symbol s_6_112[5] = { 'e', 'r', 0xC3, 0xA1, 's' };
+static const symbol s_6_113[5] = { 'i', 'r', 0xC3, 0xA1, 's' };
+static const symbol s_6_114[2] = { 'e', 'u' };
+static const symbol s_6_115[2] = { 'i', 'u' };
+static const symbol s_6_116[2] = { 'o', 'u' };
+static const symbol s_6_117[4] = { 'a', 'r', 0xC3, 0xA1 };
+static const symbol s_6_118[4] = { 'e', 'r', 0xC3, 0xA1 };
+static const symbol s_6_119[4] = { 'i', 'r', 0xC3, 0xA1 };
+
+static const struct among a_6[120] =
+{
+/* 0 */ { 3, s_6_0, -1, 1, 0},
+/* 1 */ { 3, s_6_1, -1, 1, 0},
+/* 2 */ { 2, s_6_2, -1, 1, 0},
+/* 3 */ { 4, s_6_3, 2, 1, 0},
+/* 4 */ { 4, s_6_4, 2, 1, 0},
+/* 5 */ { 4, s_6_5, 2, 1, 0},
+/* 6 */ { 3, s_6_6, -1, 1, 0},
+/* 7 */ { 3, s_6_7, -1, 1, 0},
+/* 8 */ { 3, s_6_8, -1, 1, 0},
+/* 9 */ { 3, s_6_9, -1, 1, 0},
+/* 10 */ { 4, s_6_10, -1, 1, 0},
+/* 11 */ { 4, s_6_11, -1, 1, 0},
+/* 12 */ { 4, s_6_12, -1, 1, 0},
+/* 13 */ { 4, s_6_13, -1, 1, 0},
+/* 14 */ { 4, s_6_14, -1, 1, 0},
+/* 15 */ { 4, s_6_15, -1, 1, 0},
+/* 16 */ { 2, s_6_16, -1, 1, 0},
+/* 17 */ { 4, s_6_17, 16, 1, 0},
+/* 18 */ { 4, s_6_18, 16, 1, 0},
+/* 19 */ { 4, s_6_19, 16, 1, 0},
+/* 20 */ { 2, s_6_20, -1, 1, 0},
+/* 21 */ { 3, s_6_21, 20, 1, 0},
+/* 22 */ { 5, s_6_22, 21, 1, 0},
+/* 23 */ { 5, s_6_23, 21, 1, 0},
+/* 24 */ { 5, s_6_24, 21, 1, 0},
+/* 25 */ { 4, s_6_25, 20, 1, 0},
+/* 26 */ { 4, s_6_26, 20, 1, 0},
+/* 27 */ { 4, s_6_27, 20, 1, 0},
+/* 28 */ { 4, s_6_28, 20, 1, 0},
+/* 29 */ { 2, s_6_29, -1, 1, 0},
+/* 30 */ { 4, s_6_30, 29, 1, 0},
+/* 31 */ { 4, s_6_31, 29, 1, 0},
+/* 32 */ { 4, s_6_32, 29, 1, 0},
+/* 33 */ { 5, s_6_33, 29, 1, 0},
+/* 34 */ { 5, s_6_34, 29, 1, 0},
+/* 35 */ { 5, s_6_35, 29, 1, 0},
+/* 36 */ { 3, s_6_36, -1, 1, 0},
+/* 37 */ { 3, s_6_37, -1, 1, 0},
+/* 38 */ { 4, s_6_38, -1, 1, 0},
+/* 39 */ { 4, s_6_39, -1, 1, 0},
+/* 40 */ { 4, s_6_40, -1, 1, 0},
+/* 41 */ { 5, s_6_41, -1, 1, 0},
+/* 42 */ { 5, s_6_42, -1, 1, 0},
+/* 43 */ { 5, s_6_43, -1, 1, 0},
+/* 44 */ { 2, s_6_44, -1, 1, 0},
+/* 45 */ { 2, s_6_45, -1, 1, 0},
+/* 46 */ { 2, s_6_46, -1, 1, 0},
+/* 47 */ { 2, s_6_47, -1, 1, 0},
+/* 48 */ { 4, s_6_48, 47, 1, 0},
+/* 49 */ { 4, s_6_49, 47, 1, 0},
+/* 50 */ { 3, s_6_50, 47, 1, 0},
+/* 51 */ { 5, s_6_51, 50, 1, 0},
+/* 52 */ { 5, s_6_52, 50, 1, 0},
+/* 53 */ { 5, s_6_53, 50, 1, 0},
+/* 54 */ { 4, s_6_54, 47, 1, 0},
+/* 55 */ { 4, s_6_55, 47, 1, 0},
+/* 56 */ { 4, s_6_56, 47, 1, 0},
+/* 57 */ { 4, s_6_57, 47, 1, 0},
+/* 58 */ { 2, s_6_58, -1, 1, 0},
+/* 59 */ { 5, s_6_59, 58, 1, 0},
+/* 60 */ { 5, s_6_60, 58, 1, 0},
+/* 61 */ { 5, s_6_61, 58, 1, 0},
+/* 62 */ { 4, s_6_62, 58, 1, 0},
+/* 63 */ { 4, s_6_63, 58, 1, 0},
+/* 64 */ { 4, s_6_64, 58, 1, 0},
+/* 65 */ { 5, s_6_65, 58, 1, 0},
+/* 66 */ { 5, s_6_66, 58, 1, 0},
+/* 67 */ { 5, s_6_67, 58, 1, 0},
+/* 68 */ { 5, s_6_68, 58, 1, 0},
+/* 69 */ { 5, s_6_69, 58, 1, 0},
+/* 70 */ { 5, s_6_70, 58, 1, 0},
+/* 71 */ { 2, s_6_71, -1, 1, 0},
+/* 72 */ { 3, s_6_72, 71, 1, 0},
+/* 73 */ { 3, s_6_73, 71, 1, 0},
+/* 74 */ { 5, s_6_74, 73, 1, 0},
+/* 75 */ { 5, s_6_75, 73, 1, 0},
+/* 76 */ { 5, s_6_76, 73, 1, 0},
+/* 77 */ { 6, s_6_77, 73, 1, 0},
+/* 78 */ { 6, s_6_78, 73, 1, 0},
+/* 79 */ { 6, s_6_79, 73, 1, 0},
+/* 80 */ { 7, s_6_80, 73, 1, 0},
+/* 81 */ { 7, s_6_81, 73, 1, 0},
+/* 82 */ { 7, s_6_82, 73, 1, 0},
+/* 83 */ { 6, s_6_83, 73, 1, 0},
+/* 84 */ { 5, s_6_84, 73, 1, 0},
+/* 85 */ { 7, s_6_85, 84, 1, 0},
+/* 86 */ { 7, s_6_86, 84, 1, 0},
+/* 87 */ { 7, s_6_87, 84, 1, 0},
+/* 88 */ { 4, s_6_88, -1, 1, 0},
+/* 89 */ { 4, s_6_89, -1, 1, 0},
+/* 90 */ { 4, s_6_90, -1, 1, 0},
+/* 91 */ { 7, s_6_91, 90, 1, 0},
+/* 92 */ { 7, s_6_92, 90, 1, 0},
+/* 93 */ { 7, s_6_93, 90, 1, 0},
+/* 94 */ { 7, s_6_94, 90, 1, 0},
+/* 95 */ { 6, s_6_95, 90, 1, 0},
+/* 96 */ { 8, s_6_96, 95, 1, 0},
+/* 97 */ { 8, s_6_97, 95, 1, 0},
+/* 98 */ { 8, s_6_98, 95, 1, 0},
+/* 99 */ { 4, s_6_99, -1, 1, 0},
+/*100 */ { 6, s_6_100, 99, 1, 0},
+/*101 */ { 6, s_6_101, 99, 1, 0},
+/*102 */ { 6, s_6_102, 99, 1, 0},
+/*103 */ { 8, s_6_103, 99, 1, 0},
+/*104 */ { 8, s_6_104, 99, 1, 0},
+/*105 */ { 8, s_6_105, 99, 1, 0},
+/*106 */ { 4, s_6_106, -1, 1, 0},
+/*107 */ { 5, s_6_107, -1, 1, 0},
+/*108 */ { 5, s_6_108, -1, 1, 0},
+/*109 */ { 5, s_6_109, -1, 1, 0},
+/*110 */ { 5, s_6_110, -1, 1, 0},
+/*111 */ { 5, s_6_111, -1, 1, 0},
+/*112 */ { 5, s_6_112, -1, 1, 0},
+/*113 */ { 5, s_6_113, -1, 1, 0},
+/*114 */ { 2, s_6_114, -1, 1, 0},
+/*115 */ { 2, s_6_115, -1, 1, 0},
+/*116 */ { 2, s_6_116, -1, 1, 0},
+/*117 */ { 4, s_6_117, -1, 1, 0},
+/*118 */ { 4, s_6_118, -1, 1, 0},
+/*119 */ { 4, s_6_119, -1, 1, 0}
+};
+
+static const symbol s_7_0[1] = { 'a' };
+static const symbol s_7_1[1] = { 'i' };
+static const symbol s_7_2[1] = { 'o' };
+static const symbol s_7_3[2] = { 'o', 's' };
+static const symbol s_7_4[2] = { 0xC3, 0xA1 };
+static const symbol s_7_5[2] = { 0xC3, 0xAD };
+static const symbol s_7_6[2] = { 0xC3, 0xB3 };
+
+static const struct among a_7[7] =
+{
+/* 0 */ { 1, s_7_0, -1, 1, 0},
+/* 1 */ { 1, s_7_1, -1, 1, 0},
+/* 2 */ { 1, s_7_2, -1, 1, 0},
+/* 3 */ { 2, s_7_3, -1, 1, 0},
+/* 4 */ { 2, s_7_4, -1, 1, 0},
+/* 5 */ { 2, s_7_5, -1, 1, 0},
+/* 6 */ { 2, s_7_6, -1, 1, 0}
+};
+
+static const symbol s_8_0[1] = { 'e' };
+static const symbol s_8_1[2] = { 0xC3, 0xA7 };
+static const symbol s_8_2[2] = { 0xC3, 0xA9 };
+static const symbol s_8_3[2] = { 0xC3, 0xAA };
+
+static const struct among a_8[4] =
+{
+/* 0 */ { 1, s_8_0, -1, 1, 0},
+/* 1 */ { 2, s_8_1, -1, 2, 0},
+/* 2 */ { 2, s_8_2, -1, 1, 0},
+/* 3 */ { 2, s_8_3, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2 };
+
+static const symbol s_0[] = { 'a', '~' };
+static const symbol s_1[] = { 'o', '~' };
+static const symbol s_2[] = { 0xC3, 0xA3 };
+static const symbol s_3[] = { 0xC3, 0xB5 };
+static const symbol s_4[] = { 'l', 'o', 'g' };
+static const symbol s_5[] = { 'u' };
+static const symbol s_6[] = { 'e', 'n', 't', 'e' };
+static const symbol s_7[] = { 'a', 't' };
+static const symbol s_8[] = { 'a', 't' };
+static const symbol s_9[] = { 'e' };
+static const symbol s_10[] = { 'i', 'r' };
+static const symbol s_11[] = { 'u' };
+static const symbol s_12[] = { 'g' };
+static const symbol s_13[] = { 'i' };
+static const symbol s_14[] = { 'c' };
+static const symbol s_15[] = { 'c' };
+static const symbol s_16[] = { 'i' };
+static const symbol s_17[] = { 'c' };
+
+static int r_prelude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 36 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 37 */
+ if (z->c + 1 >= z->l || (z->p[z->c + 1] != 163 && z->p[z->c + 1] != 181)) among_var = 3; else
+ among_var = find_among(z, a_0, 3); /* substring, line 37 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 37 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_0); /* <-, line 38 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 2, s_1); /* <-, line 39 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 40 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 50 */
+ { int c2 = z->c; /* or, line 52 */
+ if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2;
+ { int c3 = z->c; /* or, line 51 */
+ if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab4;
+ { /* gopast */ /* grouping v, line 51 */
+ int ret = out_grouping_U(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c3;
+ if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2;
+ { /* gopast */ /* non v, line 51 */
+ int ret = in_grouping_U(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab2;
+ z->c += ret;
+ }
+ }
+ lab3:
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab0;
+ { int c4 = z->c; /* or, line 53 */
+ if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab6;
+ { /* gopast */ /* grouping v, line 53 */
+ int ret = out_grouping_U(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab6;
+ z->c += ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c4;
+ if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab0;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 53 */
+ }
+ }
+ lab5:
+ ;
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 54 */
+ lab0:
+ z->c = c1;
+ }
+ { int c5 = z->c; /* do, line 56 */
+ { /* gopast */ /* grouping v, line 57 */
+ int ret = out_grouping_U(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 57 */
+ int ret = in_grouping_U(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 57 */
+ { /* gopast */ /* grouping v, line 58 */
+ int ret = out_grouping_U(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 58 */
+ int ret = in_grouping_U(z, g_v, 97, 250, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 58 */
+ lab7:
+ z->c = c5;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 62 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 63 */
+ if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else
+ among_var = find_among(z, a_1, 3); /* substring, line 63 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 63 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 2, s_2); /* <-, line 64 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 2, s_3); /* <-, line 65 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 66 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 77 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((839714 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_5, 45); /* substring, line 77 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 77 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 93 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 93 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 98 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_4); /* <-, line 98 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 102 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 106 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 4, s_6); /* <-, line 106 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 110 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */
+ z->ket = z->c; /* [, line 112 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab0; }
+ among_var = find_among_b(z, a_2, 4); /* substring, line 112 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 112 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 112 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 112 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab0; }
+ case 1:
+ z->ket = z->c; /* [, line 113 */
+ if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 113 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 113 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 113 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ ;
+ }
+ break;
+ case 6:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 122 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 122 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 123 */
+ z->ket = z->c; /* [, line 124 */
+ if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m_keep; goto lab1; }
+ among_var = find_among_b(z, a_3, 3); /* substring, line 124 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 124 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab1; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 127 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 127 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab1:
+ ;
+ }
+ break;
+ case 7:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 134 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 135 */
+ z->ket = z->c; /* [, line 136 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab2; }
+ among_var = find_among_b(z, a_4, 3); /* substring, line 136 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab2; }
+ z->bra = z->c; /* ], line 136 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab2; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 139 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 139 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab2:
+ ;
+ }
+ break;
+ case 8:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 146 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 146 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 147 */
+ z->ket = z->c; /* [, line 148 */
+ if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 148 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 148 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 148 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ ;
+ }
+ break;
+ case 9:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 153 */
+ if (ret < 0) return ret;
+ }
+ if (!(eq_s_b(z, 1, s_9))) return 0;
+ { int ret = slice_from_s(z, 2, s_10); /* <-, line 154 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 159 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 159 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 160 */
+ among_var = find_among_b(z, a_6, 120); /* substring, line 160 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 160 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 179 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_residual_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 184 */
+ among_var = find_among_b(z, a_7, 7); /* substring, line 184 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 184 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 187 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 187 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_residual_form(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 192 */
+ among_var = find_among_b(z, a_8, 4); /* substring, line 192 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 192 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 194 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 194 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 194 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 194 */
+ if (!(eq_s_b(z, 1, s_11))) goto lab1;
+ z->bra = z->c; /* ], line 194 */
+ { int m_test = z->l - z->c; /* test, line 194 */
+ if (!(eq_s_b(z, 1, s_12))) goto lab1;
+ z->c = z->l - m_test;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_13))) return 0;
+ z->bra = z->c; /* ], line 195 */
+ { int m_test = z->l - z->c; /* test, line 195 */
+ if (!(eq_s_b(z, 1, s_14))) return 0;
+ z->c = z->l - m_test;
+ }
+ }
+ lab0:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 195 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 195 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_15); /* <-, line 196 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int portuguese_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 202 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 202 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 203 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 203 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 204 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 205 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 209 */
+ { int m5 = z->l - z->c; (void)m5; /* and, line 207 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 206 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab6; /* call standard_suffix, line 206 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab4; /* call verb_suffix, line 206 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ z->c = z->l - m5;
+ { int m7 = z->l - z->c; (void)m7; /* do, line 207 */
+ z->ket = z->c; /* [, line 207 */
+ if (!(eq_s_b(z, 1, s_16))) goto lab7;
+ z->bra = z->c; /* ], line 207 */
+ { int m_test = z->l - z->c; /* test, line 207 */
+ if (!(eq_s_b(z, 1, s_17))) goto lab7;
+ z->c = z->l - m_test;
+ }
+ { int ret = r_RV(z);
+ if (ret == 0) goto lab7; /* call RV, line 207 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 207 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m7;
+ }
+ }
+ goto lab3;
+ lab4:
+ z->c = z->l - m4;
+ { int ret = r_residual_suffix(z);
+ if (ret == 0) goto lab2; /* call residual_suffix, line 209 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab3:
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m8 = z->l - z->c; (void)m8; /* do, line 211 */
+ { int ret = r_residual_form(z);
+ if (ret == 0) goto lab8; /* call residual_form, line 211 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = z->l - m8;
+ }
+ z->c = z->lb;
+ { int c9 = z->c; /* do, line 213 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab9; /* call postlude, line 213 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = c9;
+ }
+ return 1;
+}
+
+extern struct SN_env * portuguese_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void portuguese_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c b/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c
new file mode 100644
index 00000000000..e82ebfe95f8
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c
@@ -0,0 +1,1004 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int romanian_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_vowel_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_combo_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_step_0(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_prelude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * romanian_UTF_8_create_env(void);
+extern void romanian_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[1] = { 'I' };
+static const symbol s_0_2[1] = { 'U' };
+
+static const struct among a_0[3] =
+{
+/* 0 */ { 0, 0, -1, 3, 0},
+/* 1 */ { 1, s_0_1, 0, 1, 0},
+/* 2 */ { 1, s_0_2, 0, 2, 0}
+};
+
+static const symbol s_1_0[2] = { 'e', 'a' };
+static const symbol s_1_1[5] = { 'a', 0xC5, 0xA3, 'i', 'a' };
+static const symbol s_1_2[3] = { 'a', 'u', 'a' };
+static const symbol s_1_3[3] = { 'i', 'u', 'a' };
+static const symbol s_1_4[5] = { 'a', 0xC5, 0xA3, 'i', 'e' };
+static const symbol s_1_5[3] = { 'e', 'l', 'e' };
+static const symbol s_1_6[3] = { 'i', 'l', 'e' };
+static const symbol s_1_7[4] = { 'i', 'i', 'l', 'e' };
+static const symbol s_1_8[3] = { 'i', 'e', 'i' };
+static const symbol s_1_9[4] = { 'a', 't', 'e', 'i' };
+static const symbol s_1_10[2] = { 'i', 'i' };
+static const symbol s_1_11[4] = { 'u', 'l', 'u', 'i' };
+static const symbol s_1_12[2] = { 'u', 'l' };
+static const symbol s_1_13[4] = { 'e', 'l', 'o', 'r' };
+static const symbol s_1_14[4] = { 'i', 'l', 'o', 'r' };
+static const symbol s_1_15[5] = { 'i', 'i', 'l', 'o', 'r' };
+
+static const struct among a_1[16] =
+{
+/* 0 */ { 2, s_1_0, -1, 3, 0},
+/* 1 */ { 5, s_1_1, -1, 7, 0},
+/* 2 */ { 3, s_1_2, -1, 2, 0},
+/* 3 */ { 3, s_1_3, -1, 4, 0},
+/* 4 */ { 5, s_1_4, -1, 7, 0},
+/* 5 */ { 3, s_1_5, -1, 3, 0},
+/* 6 */ { 3, s_1_6, -1, 5, 0},
+/* 7 */ { 4, s_1_7, 6, 4, 0},
+/* 8 */ { 3, s_1_8, -1, 4, 0},
+/* 9 */ { 4, s_1_9, -1, 6, 0},
+/* 10 */ { 2, s_1_10, -1, 4, 0},
+/* 11 */ { 4, s_1_11, -1, 1, 0},
+/* 12 */ { 2, s_1_12, -1, 1, 0},
+/* 13 */ { 4, s_1_13, -1, 3, 0},
+/* 14 */ { 4, s_1_14, -1, 4, 0},
+/* 15 */ { 5, s_1_15, 14, 4, 0}
+};
+
+static const symbol s_2_0[5] = { 'i', 'c', 'a', 'l', 'a' };
+static const symbol s_2_1[5] = { 'i', 'c', 'i', 'v', 'a' };
+static const symbol s_2_2[5] = { 'a', 't', 'i', 'v', 'a' };
+static const symbol s_2_3[5] = { 'i', 't', 'i', 'v', 'a' };
+static const symbol s_2_4[5] = { 'i', 'c', 'a', 'l', 'e' };
+static const symbol s_2_5[7] = { 'a', 0xC5, 0xA3, 'i', 'u', 'n', 'e' };
+static const symbol s_2_6[7] = { 'i', 0xC5, 0xA3, 'i', 'u', 'n', 'e' };
+static const symbol s_2_7[6] = { 'a', 't', 'o', 'a', 'r', 'e' };
+static const symbol s_2_8[6] = { 'i', 't', 'o', 'a', 'r', 'e' };
+static const symbol s_2_9[7] = { 0xC4, 0x83, 't', 'o', 'a', 'r', 'e' };
+static const symbol s_2_10[7] = { 'i', 'c', 'i', 't', 'a', 't', 'e' };
+static const symbol s_2_11[9] = { 'a', 'b', 'i', 'l', 'i', 't', 'a', 't', 'e' };
+static const symbol s_2_12[9] = { 'i', 'b', 'i', 'l', 'i', 't', 'a', 't', 'e' };
+static const symbol s_2_13[7] = { 'i', 'v', 'i', 't', 'a', 't', 'e' };
+static const symbol s_2_14[5] = { 'i', 'c', 'i', 'v', 'e' };
+static const symbol s_2_15[5] = { 'a', 't', 'i', 'v', 'e' };
+static const symbol s_2_16[5] = { 'i', 't', 'i', 'v', 'e' };
+static const symbol s_2_17[5] = { 'i', 'c', 'a', 'l', 'i' };
+static const symbol s_2_18[5] = { 'a', 't', 'o', 'r', 'i' };
+static const symbol s_2_19[7] = { 'i', 'c', 'a', 't', 'o', 'r', 'i' };
+static const symbol s_2_20[5] = { 'i', 't', 'o', 'r', 'i' };
+static const symbol s_2_21[6] = { 0xC4, 0x83, 't', 'o', 'r', 'i' };
+static const symbol s_2_22[7] = { 'i', 'c', 'i', 't', 'a', 't', 'i' };
+static const symbol s_2_23[9] = { 'a', 'b', 'i', 'l', 'i', 't', 'a', 't', 'i' };
+static const symbol s_2_24[7] = { 'i', 'v', 'i', 't', 'a', 't', 'i' };
+static const symbol s_2_25[5] = { 'i', 'c', 'i', 'v', 'i' };
+static const symbol s_2_26[5] = { 'a', 't', 'i', 'v', 'i' };
+static const symbol s_2_27[5] = { 'i', 't', 'i', 'v', 'i' };
+static const symbol s_2_28[7] = { 'i', 'c', 'i', 't', 0xC4, 0x83, 'i' };
+static const symbol s_2_29[9] = { 'a', 'b', 'i', 'l', 'i', 't', 0xC4, 0x83, 'i' };
+static const symbol s_2_30[7] = { 'i', 'v', 'i', 't', 0xC4, 0x83, 'i' };
+static const symbol s_2_31[9] = { 'i', 'c', 'i', 't', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_2_32[11] = { 'a', 'b', 'i', 'l', 'i', 't', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_2_33[9] = { 'i', 'v', 'i', 't', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_2_34[4] = { 'i', 'c', 'a', 'l' };
+static const symbol s_2_35[4] = { 'a', 't', 'o', 'r' };
+static const symbol s_2_36[6] = { 'i', 'c', 'a', 't', 'o', 'r' };
+static const symbol s_2_37[4] = { 'i', 't', 'o', 'r' };
+static const symbol s_2_38[5] = { 0xC4, 0x83, 't', 'o', 'r' };
+static const symbol s_2_39[4] = { 'i', 'c', 'i', 'v' };
+static const symbol s_2_40[4] = { 'a', 't', 'i', 'v' };
+static const symbol s_2_41[4] = { 'i', 't', 'i', 'v' };
+static const symbol s_2_42[6] = { 'i', 'c', 'a', 'l', 0xC4, 0x83 };
+static const symbol s_2_43[6] = { 'i', 'c', 'i', 'v', 0xC4, 0x83 };
+static const symbol s_2_44[6] = { 'a', 't', 'i', 'v', 0xC4, 0x83 };
+static const symbol s_2_45[6] = { 'i', 't', 'i', 'v', 0xC4, 0x83 };
+
+static const struct among a_2[46] =
+{
+/* 0 */ { 5, s_2_0, -1, 4, 0},
+/* 1 */ { 5, s_2_1, -1, 4, 0},
+/* 2 */ { 5, s_2_2, -1, 5, 0},
+/* 3 */ { 5, s_2_3, -1, 6, 0},
+/* 4 */ { 5, s_2_4, -1, 4, 0},
+/* 5 */ { 7, s_2_5, -1, 5, 0},
+/* 6 */ { 7, s_2_6, -1, 6, 0},
+/* 7 */ { 6, s_2_7, -1, 5, 0},
+/* 8 */ { 6, s_2_8, -1, 6, 0},
+/* 9 */ { 7, s_2_9, -1, 5, 0},
+/* 10 */ { 7, s_2_10, -1, 4, 0},
+/* 11 */ { 9, s_2_11, -1, 1, 0},
+/* 12 */ { 9, s_2_12, -1, 2, 0},
+/* 13 */ { 7, s_2_13, -1, 3, 0},
+/* 14 */ { 5, s_2_14, -1, 4, 0},
+/* 15 */ { 5, s_2_15, -1, 5, 0},
+/* 16 */ { 5, s_2_16, -1, 6, 0},
+/* 17 */ { 5, s_2_17, -1, 4, 0},
+/* 18 */ { 5, s_2_18, -1, 5, 0},
+/* 19 */ { 7, s_2_19, 18, 4, 0},
+/* 20 */ { 5, s_2_20, -1, 6, 0},
+/* 21 */ { 6, s_2_21, -1, 5, 0},
+/* 22 */ { 7, s_2_22, -1, 4, 0},
+/* 23 */ { 9, s_2_23, -1, 1, 0},
+/* 24 */ { 7, s_2_24, -1, 3, 0},
+/* 25 */ { 5, s_2_25, -1, 4, 0},
+/* 26 */ { 5, s_2_26, -1, 5, 0},
+/* 27 */ { 5, s_2_27, -1, 6, 0},
+/* 28 */ { 7, s_2_28, -1, 4, 0},
+/* 29 */ { 9, s_2_29, -1, 1, 0},
+/* 30 */ { 7, s_2_30, -1, 3, 0},
+/* 31 */ { 9, s_2_31, -1, 4, 0},
+/* 32 */ { 11, s_2_32, -1, 1, 0},
+/* 33 */ { 9, s_2_33, -1, 3, 0},
+/* 34 */ { 4, s_2_34, -1, 4, 0},
+/* 35 */ { 4, s_2_35, -1, 5, 0},
+/* 36 */ { 6, s_2_36, 35, 4, 0},
+/* 37 */ { 4, s_2_37, -1, 6, 0},
+/* 38 */ { 5, s_2_38, -1, 5, 0},
+/* 39 */ { 4, s_2_39, -1, 4, 0},
+/* 40 */ { 4, s_2_40, -1, 5, 0},
+/* 41 */ { 4, s_2_41, -1, 6, 0},
+/* 42 */ { 6, s_2_42, -1, 4, 0},
+/* 43 */ { 6, s_2_43, -1, 4, 0},
+/* 44 */ { 6, s_2_44, -1, 5, 0},
+/* 45 */ { 6, s_2_45, -1, 6, 0}
+};
+
+static const symbol s_3_0[3] = { 'i', 'c', 'a' };
+static const symbol s_3_1[5] = { 'a', 'b', 'i', 'l', 'a' };
+static const symbol s_3_2[5] = { 'i', 'b', 'i', 'l', 'a' };
+static const symbol s_3_3[4] = { 'o', 'a', 's', 'a' };
+static const symbol s_3_4[3] = { 'a', 't', 'a' };
+static const symbol s_3_5[3] = { 'i', 't', 'a' };
+static const symbol s_3_6[4] = { 'a', 'n', 't', 'a' };
+static const symbol s_3_7[4] = { 'i', 's', 't', 'a' };
+static const symbol s_3_8[3] = { 'u', 't', 'a' };
+static const symbol s_3_9[3] = { 'i', 'v', 'a' };
+static const symbol s_3_10[2] = { 'i', 'c' };
+static const symbol s_3_11[3] = { 'i', 'c', 'e' };
+static const symbol s_3_12[5] = { 'a', 'b', 'i', 'l', 'e' };
+static const symbol s_3_13[5] = { 'i', 'b', 'i', 'l', 'e' };
+static const symbol s_3_14[4] = { 'i', 's', 'm', 'e' };
+static const symbol s_3_15[4] = { 'i', 'u', 'n', 'e' };
+static const symbol s_3_16[4] = { 'o', 'a', 's', 'e' };
+static const symbol s_3_17[3] = { 'a', 't', 'e' };
+static const symbol s_3_18[5] = { 'i', 't', 'a', 't', 'e' };
+static const symbol s_3_19[3] = { 'i', 't', 'e' };
+static const symbol s_3_20[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_3_21[4] = { 'i', 's', 't', 'e' };
+static const symbol s_3_22[3] = { 'u', 't', 'e' };
+static const symbol s_3_23[3] = { 'i', 'v', 'e' };
+static const symbol s_3_24[3] = { 'i', 'c', 'i' };
+static const symbol s_3_25[5] = { 'a', 'b', 'i', 'l', 'i' };
+static const symbol s_3_26[5] = { 'i', 'b', 'i', 'l', 'i' };
+static const symbol s_3_27[4] = { 'i', 'u', 'n', 'i' };
+static const symbol s_3_28[5] = { 'a', 't', 'o', 'r', 'i' };
+static const symbol s_3_29[3] = { 'o', 's', 'i' };
+static const symbol s_3_30[3] = { 'a', 't', 'i' };
+static const symbol s_3_31[5] = { 'i', 't', 'a', 't', 'i' };
+static const symbol s_3_32[3] = { 'i', 't', 'i' };
+static const symbol s_3_33[4] = { 'a', 'n', 't', 'i' };
+static const symbol s_3_34[4] = { 'i', 's', 't', 'i' };
+static const symbol s_3_35[3] = { 'u', 't', 'i' };
+static const symbol s_3_36[5] = { 'i', 0xC5, 0x9F, 't', 'i' };
+static const symbol s_3_37[3] = { 'i', 'v', 'i' };
+static const symbol s_3_38[5] = { 'i', 't', 0xC4, 0x83, 'i' };
+static const symbol s_3_39[4] = { 'o', 0xC5, 0x9F, 'i' };
+static const symbol s_3_40[7] = { 'i', 't', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_3_41[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_3_42[4] = { 'i', 'b', 'i', 'l' };
+static const symbol s_3_43[3] = { 'i', 's', 'm' };
+static const symbol s_3_44[4] = { 'a', 't', 'o', 'r' };
+static const symbol s_3_45[2] = { 'o', 's' };
+static const symbol s_3_46[2] = { 'a', 't' };
+static const symbol s_3_47[2] = { 'i', 't' };
+static const symbol s_3_48[3] = { 'a', 'n', 't' };
+static const symbol s_3_49[3] = { 'i', 's', 't' };
+static const symbol s_3_50[2] = { 'u', 't' };
+static const symbol s_3_51[2] = { 'i', 'v' };
+static const symbol s_3_52[4] = { 'i', 'c', 0xC4, 0x83 };
+static const symbol s_3_53[6] = { 'a', 'b', 'i', 'l', 0xC4, 0x83 };
+static const symbol s_3_54[6] = { 'i', 'b', 'i', 'l', 0xC4, 0x83 };
+static const symbol s_3_55[5] = { 'o', 'a', 's', 0xC4, 0x83 };
+static const symbol s_3_56[4] = { 'a', 't', 0xC4, 0x83 };
+static const symbol s_3_57[4] = { 'i', 't', 0xC4, 0x83 };
+static const symbol s_3_58[5] = { 'a', 'n', 't', 0xC4, 0x83 };
+static const symbol s_3_59[5] = { 'i', 's', 't', 0xC4, 0x83 };
+static const symbol s_3_60[4] = { 'u', 't', 0xC4, 0x83 };
+static const symbol s_3_61[4] = { 'i', 'v', 0xC4, 0x83 };
+
+static const struct among a_3[62] =
+{
+/* 0 */ { 3, s_3_0, -1, 1, 0},
+/* 1 */ { 5, s_3_1, -1, 1, 0},
+/* 2 */ { 5, s_3_2, -1, 1, 0},
+/* 3 */ { 4, s_3_3, -1, 1, 0},
+/* 4 */ { 3, s_3_4, -1, 1, 0},
+/* 5 */ { 3, s_3_5, -1, 1, 0},
+/* 6 */ { 4, s_3_6, -1, 1, 0},
+/* 7 */ { 4, s_3_7, -1, 3, 0},
+/* 8 */ { 3, s_3_8, -1, 1, 0},
+/* 9 */ { 3, s_3_9, -1, 1, 0},
+/* 10 */ { 2, s_3_10, -1, 1, 0},
+/* 11 */ { 3, s_3_11, -1, 1, 0},
+/* 12 */ { 5, s_3_12, -1, 1, 0},
+/* 13 */ { 5, s_3_13, -1, 1, 0},
+/* 14 */ { 4, s_3_14, -1, 3, 0},
+/* 15 */ { 4, s_3_15, -1, 2, 0},
+/* 16 */ { 4, s_3_16, -1, 1, 0},
+/* 17 */ { 3, s_3_17, -1, 1, 0},
+/* 18 */ { 5, s_3_18, 17, 1, 0},
+/* 19 */ { 3, s_3_19, -1, 1, 0},
+/* 20 */ { 4, s_3_20, -1, 1, 0},
+/* 21 */ { 4, s_3_21, -1, 3, 0},
+/* 22 */ { 3, s_3_22, -1, 1, 0},
+/* 23 */ { 3, s_3_23, -1, 1, 0},
+/* 24 */ { 3, s_3_24, -1, 1, 0},
+/* 25 */ { 5, s_3_25, -1, 1, 0},
+/* 26 */ { 5, s_3_26, -1, 1, 0},
+/* 27 */ { 4, s_3_27, -1, 2, 0},
+/* 28 */ { 5, s_3_28, -1, 1, 0},
+/* 29 */ { 3, s_3_29, -1, 1, 0},
+/* 30 */ { 3, s_3_30, -1, 1, 0},
+/* 31 */ { 5, s_3_31, 30, 1, 0},
+/* 32 */ { 3, s_3_32, -1, 1, 0},
+/* 33 */ { 4, s_3_33, -1, 1, 0},
+/* 34 */ { 4, s_3_34, -1, 3, 0},
+/* 35 */ { 3, s_3_35, -1, 1, 0},
+/* 36 */ { 5, s_3_36, -1, 3, 0},
+/* 37 */ { 3, s_3_37, -1, 1, 0},
+/* 38 */ { 5, s_3_38, -1, 1, 0},
+/* 39 */ { 4, s_3_39, -1, 1, 0},
+/* 40 */ { 7, s_3_40, -1, 1, 0},
+/* 41 */ { 4, s_3_41, -1, 1, 0},
+/* 42 */ { 4, s_3_42, -1, 1, 0},
+/* 43 */ { 3, s_3_43, -1, 3, 0},
+/* 44 */ { 4, s_3_44, -1, 1, 0},
+/* 45 */ { 2, s_3_45, -1, 1, 0},
+/* 46 */ { 2, s_3_46, -1, 1, 0},
+/* 47 */ { 2, s_3_47, -1, 1, 0},
+/* 48 */ { 3, s_3_48, -1, 1, 0},
+/* 49 */ { 3, s_3_49, -1, 3, 0},
+/* 50 */ { 2, s_3_50, -1, 1, 0},
+/* 51 */ { 2, s_3_51, -1, 1, 0},
+/* 52 */ { 4, s_3_52, -1, 1, 0},
+/* 53 */ { 6, s_3_53, -1, 1, 0},
+/* 54 */ { 6, s_3_54, -1, 1, 0},
+/* 55 */ { 5, s_3_55, -1, 1, 0},
+/* 56 */ { 4, s_3_56, -1, 1, 0},
+/* 57 */ { 4, s_3_57, -1, 1, 0},
+/* 58 */ { 5, s_3_58, -1, 1, 0},
+/* 59 */ { 5, s_3_59, -1, 3, 0},
+/* 60 */ { 4, s_3_60, -1, 1, 0},
+/* 61 */ { 4, s_3_61, -1, 1, 0}
+};
+
+static const symbol s_4_0[2] = { 'e', 'a' };
+static const symbol s_4_1[2] = { 'i', 'a' };
+static const symbol s_4_2[3] = { 'e', 's', 'c' };
+static const symbol s_4_3[4] = { 0xC4, 0x83, 's', 'c' };
+static const symbol s_4_4[3] = { 'i', 'n', 'd' };
+static const symbol s_4_5[4] = { 0xC3, 0xA2, 'n', 'd' };
+static const symbol s_4_6[3] = { 'a', 'r', 'e' };
+static const symbol s_4_7[3] = { 'e', 'r', 'e' };
+static const symbol s_4_8[3] = { 'i', 'r', 'e' };
+static const symbol s_4_9[4] = { 0xC3, 0xA2, 'r', 'e' };
+static const symbol s_4_10[2] = { 's', 'e' };
+static const symbol s_4_11[3] = { 'a', 's', 'e' };
+static const symbol s_4_12[4] = { 's', 'e', 's', 'e' };
+static const symbol s_4_13[3] = { 'i', 's', 'e' };
+static const symbol s_4_14[3] = { 'u', 's', 'e' };
+static const symbol s_4_15[4] = { 0xC3, 0xA2, 's', 'e' };
+static const symbol s_4_16[5] = { 'e', 0xC5, 0x9F, 't', 'e' };
+static const symbol s_4_17[6] = { 0xC4, 0x83, 0xC5, 0x9F, 't', 'e' };
+static const symbol s_4_18[3] = { 'e', 'z', 'e' };
+static const symbol s_4_19[2] = { 'a', 'i' };
+static const symbol s_4_20[3] = { 'e', 'a', 'i' };
+static const symbol s_4_21[3] = { 'i', 'a', 'i' };
+static const symbol s_4_22[3] = { 's', 'e', 'i' };
+static const symbol s_4_23[5] = { 'e', 0xC5, 0x9F, 't', 'i' };
+static const symbol s_4_24[6] = { 0xC4, 0x83, 0xC5, 0x9F, 't', 'i' };
+static const symbol s_4_25[2] = { 'u', 'i' };
+static const symbol s_4_26[3] = { 'e', 'z', 'i' };
+static const symbol s_4_27[4] = { 'a', 0xC5, 0x9F, 'i' };
+static const symbol s_4_28[5] = { 's', 'e', 0xC5, 0x9F, 'i' };
+static const symbol s_4_29[6] = { 'a', 's', 'e', 0xC5, 0x9F, 'i' };
+static const symbol s_4_30[7] = { 's', 'e', 's', 'e', 0xC5, 0x9F, 'i' };
+static const symbol s_4_31[6] = { 'i', 's', 'e', 0xC5, 0x9F, 'i' };
+static const symbol s_4_32[6] = { 'u', 's', 'e', 0xC5, 0x9F, 'i' };
+static const symbol s_4_33[7] = { 0xC3, 0xA2, 's', 'e', 0xC5, 0x9F, 'i' };
+static const symbol s_4_34[4] = { 'i', 0xC5, 0x9F, 'i' };
+static const symbol s_4_35[4] = { 'u', 0xC5, 0x9F, 'i' };
+static const symbol s_4_36[5] = { 0xC3, 0xA2, 0xC5, 0x9F, 'i' };
+static const symbol s_4_37[3] = { 0xC3, 0xA2, 'i' };
+static const symbol s_4_38[4] = { 'a', 0xC5, 0xA3, 'i' };
+static const symbol s_4_39[5] = { 'e', 'a', 0xC5, 0xA3, 'i' };
+static const symbol s_4_40[5] = { 'i', 'a', 0xC5, 0xA3, 'i' };
+static const symbol s_4_41[4] = { 'e', 0xC5, 0xA3, 'i' };
+static const symbol s_4_42[4] = { 'i', 0xC5, 0xA3, 'i' };
+static const symbol s_4_43[7] = { 'a', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_44[8] = { 's', 'e', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_45[9] = { 'a', 's', 'e', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_46[10] = { 's', 'e', 's', 'e', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_47[9] = { 'i', 's', 'e', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_48[9] = { 'u', 's', 'e', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_49[10] = { 0xC3, 0xA2, 's', 'e', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_50[7] = { 'i', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_51[7] = { 'u', 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_52[8] = { 0xC3, 0xA2, 'r', 0xC4, 0x83, 0xC5, 0xA3, 'i' };
+static const symbol s_4_53[5] = { 0xC3, 0xA2, 0xC5, 0xA3, 'i' };
+static const symbol s_4_54[2] = { 'a', 'm' };
+static const symbol s_4_55[3] = { 'e', 'a', 'm' };
+static const symbol s_4_56[3] = { 'i', 'a', 'm' };
+static const symbol s_4_57[2] = { 'e', 'm' };
+static const symbol s_4_58[4] = { 'a', 's', 'e', 'm' };
+static const symbol s_4_59[5] = { 's', 'e', 's', 'e', 'm' };
+static const symbol s_4_60[4] = { 'i', 's', 'e', 'm' };
+static const symbol s_4_61[4] = { 'u', 's', 'e', 'm' };
+static const symbol s_4_62[5] = { 0xC3, 0xA2, 's', 'e', 'm' };
+static const symbol s_4_63[2] = { 'i', 'm' };
+static const symbol s_4_64[3] = { 0xC4, 0x83, 'm' };
+static const symbol s_4_65[5] = { 'a', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_66[6] = { 's', 'e', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_67[7] = { 'a', 's', 'e', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_68[8] = { 's', 'e', 's', 'e', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_69[7] = { 'i', 's', 'e', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_70[7] = { 'u', 's', 'e', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_71[8] = { 0xC3, 0xA2, 's', 'e', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_72[5] = { 'i', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_73[5] = { 'u', 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_74[6] = { 0xC3, 0xA2, 'r', 0xC4, 0x83, 'm' };
+static const symbol s_4_75[3] = { 0xC3, 0xA2, 'm' };
+static const symbol s_4_76[2] = { 'a', 'u' };
+static const symbol s_4_77[3] = { 'e', 'a', 'u' };
+static const symbol s_4_78[3] = { 'i', 'a', 'u' };
+static const symbol s_4_79[4] = { 'i', 'n', 'd', 'u' };
+static const symbol s_4_80[5] = { 0xC3, 0xA2, 'n', 'd', 'u' };
+static const symbol s_4_81[2] = { 'e', 'z' };
+static const symbol s_4_82[6] = { 'e', 'a', 's', 'c', 0xC4, 0x83 };
+static const symbol s_4_83[4] = { 'a', 'r', 0xC4, 0x83 };
+static const symbol s_4_84[5] = { 's', 'e', 'r', 0xC4, 0x83 };
+static const symbol s_4_85[6] = { 'a', 's', 'e', 'r', 0xC4, 0x83 };
+static const symbol s_4_86[7] = { 's', 'e', 's', 'e', 'r', 0xC4, 0x83 };
+static const symbol s_4_87[6] = { 'i', 's', 'e', 'r', 0xC4, 0x83 };
+static const symbol s_4_88[6] = { 'u', 's', 'e', 'r', 0xC4, 0x83 };
+static const symbol s_4_89[7] = { 0xC3, 0xA2, 's', 'e', 'r', 0xC4, 0x83 };
+static const symbol s_4_90[4] = { 'i', 'r', 0xC4, 0x83 };
+static const symbol s_4_91[4] = { 'u', 'r', 0xC4, 0x83 };
+static const symbol s_4_92[5] = { 0xC3, 0xA2, 'r', 0xC4, 0x83 };
+static const symbol s_4_93[5] = { 'e', 'a', 'z', 0xC4, 0x83 };
+
+static const struct among a_4[94] =
+{
+/* 0 */ { 2, s_4_0, -1, 1, 0},
+/* 1 */ { 2, s_4_1, -1, 1, 0},
+/* 2 */ { 3, s_4_2, -1, 1, 0},
+/* 3 */ { 4, s_4_3, -1, 1, 0},
+/* 4 */ { 3, s_4_4, -1, 1, 0},
+/* 5 */ { 4, s_4_5, -1, 1, 0},
+/* 6 */ { 3, s_4_6, -1, 1, 0},
+/* 7 */ { 3, s_4_7, -1, 1, 0},
+/* 8 */ { 3, s_4_8, -1, 1, 0},
+/* 9 */ { 4, s_4_9, -1, 1, 0},
+/* 10 */ { 2, s_4_10, -1, 2, 0},
+/* 11 */ { 3, s_4_11, 10, 1, 0},
+/* 12 */ { 4, s_4_12, 10, 2, 0},
+/* 13 */ { 3, s_4_13, 10, 1, 0},
+/* 14 */ { 3, s_4_14, 10, 1, 0},
+/* 15 */ { 4, s_4_15, 10, 1, 0},
+/* 16 */ { 5, s_4_16, -1, 1, 0},
+/* 17 */ { 6, s_4_17, -1, 1, 0},
+/* 18 */ { 3, s_4_18, -1, 1, 0},
+/* 19 */ { 2, s_4_19, -1, 1, 0},
+/* 20 */ { 3, s_4_20, 19, 1, 0},
+/* 21 */ { 3, s_4_21, 19, 1, 0},
+/* 22 */ { 3, s_4_22, -1, 2, 0},
+/* 23 */ { 5, s_4_23, -1, 1, 0},
+/* 24 */ { 6, s_4_24, -1, 1, 0},
+/* 25 */ { 2, s_4_25, -1, 1, 0},
+/* 26 */ { 3, s_4_26, -1, 1, 0},
+/* 27 */ { 4, s_4_27, -1, 1, 0},
+/* 28 */ { 5, s_4_28, -1, 2, 0},
+/* 29 */ { 6, s_4_29, 28, 1, 0},
+/* 30 */ { 7, s_4_30, 28, 2, 0},
+/* 31 */ { 6, s_4_31, 28, 1, 0},
+/* 32 */ { 6, s_4_32, 28, 1, 0},
+/* 33 */ { 7, s_4_33, 28, 1, 0},
+/* 34 */ { 4, s_4_34, -1, 1, 0},
+/* 35 */ { 4, s_4_35, -1, 1, 0},
+/* 36 */ { 5, s_4_36, -1, 1, 0},
+/* 37 */ { 3, s_4_37, -1, 1, 0},
+/* 38 */ { 4, s_4_38, -1, 2, 0},
+/* 39 */ { 5, s_4_39, 38, 1, 0},
+/* 40 */ { 5, s_4_40, 38, 1, 0},
+/* 41 */ { 4, s_4_41, -1, 2, 0},
+/* 42 */ { 4, s_4_42, -1, 2, 0},
+/* 43 */ { 7, s_4_43, -1, 1, 0},
+/* 44 */ { 8, s_4_44, -1, 2, 0},
+/* 45 */ { 9, s_4_45, 44, 1, 0},
+/* 46 */ { 10, s_4_46, 44, 2, 0},
+/* 47 */ { 9, s_4_47, 44, 1, 0},
+/* 48 */ { 9, s_4_48, 44, 1, 0},
+/* 49 */ { 10, s_4_49, 44, 1, 0},
+/* 50 */ { 7, s_4_50, -1, 1, 0},
+/* 51 */ { 7, s_4_51, -1, 1, 0},
+/* 52 */ { 8, s_4_52, -1, 1, 0},
+/* 53 */ { 5, s_4_53, -1, 2, 0},
+/* 54 */ { 2, s_4_54, -1, 1, 0},
+/* 55 */ { 3, s_4_55, 54, 1, 0},
+/* 56 */ { 3, s_4_56, 54, 1, 0},
+/* 57 */ { 2, s_4_57, -1, 2, 0},
+/* 58 */ { 4, s_4_58, 57, 1, 0},
+/* 59 */ { 5, s_4_59, 57, 2, 0},
+/* 60 */ { 4, s_4_60, 57, 1, 0},
+/* 61 */ { 4, s_4_61, 57, 1, 0},
+/* 62 */ { 5, s_4_62, 57, 1, 0},
+/* 63 */ { 2, s_4_63, -1, 2, 0},
+/* 64 */ { 3, s_4_64, -1, 2, 0},
+/* 65 */ { 5, s_4_65, 64, 1, 0},
+/* 66 */ { 6, s_4_66, 64, 2, 0},
+/* 67 */ { 7, s_4_67, 66, 1, 0},
+/* 68 */ { 8, s_4_68, 66, 2, 0},
+/* 69 */ { 7, s_4_69, 66, 1, 0},
+/* 70 */ { 7, s_4_70, 66, 1, 0},
+/* 71 */ { 8, s_4_71, 66, 1, 0},
+/* 72 */ { 5, s_4_72, 64, 1, 0},
+/* 73 */ { 5, s_4_73, 64, 1, 0},
+/* 74 */ { 6, s_4_74, 64, 1, 0},
+/* 75 */ { 3, s_4_75, -1, 2, 0},
+/* 76 */ { 2, s_4_76, -1, 1, 0},
+/* 77 */ { 3, s_4_77, 76, 1, 0},
+/* 78 */ { 3, s_4_78, 76, 1, 0},
+/* 79 */ { 4, s_4_79, -1, 1, 0},
+/* 80 */ { 5, s_4_80, -1, 1, 0},
+/* 81 */ { 2, s_4_81, -1, 1, 0},
+/* 82 */ { 6, s_4_82, -1, 1, 0},
+/* 83 */ { 4, s_4_83, -1, 1, 0},
+/* 84 */ { 5, s_4_84, -1, 2, 0},
+/* 85 */ { 6, s_4_85, 84, 1, 0},
+/* 86 */ { 7, s_4_86, 84, 2, 0},
+/* 87 */ { 6, s_4_87, 84, 1, 0},
+/* 88 */ { 6, s_4_88, 84, 1, 0},
+/* 89 */ { 7, s_4_89, 84, 1, 0},
+/* 90 */ { 4, s_4_90, -1, 1, 0},
+/* 91 */ { 4, s_4_91, -1, 1, 0},
+/* 92 */ { 5, s_4_92, -1, 1, 0},
+/* 93 */ { 5, s_4_93, -1, 1, 0}
+};
+
+static const symbol s_5_0[1] = { 'a' };
+static const symbol s_5_1[1] = { 'e' };
+static const symbol s_5_2[2] = { 'i', 'e' };
+static const symbol s_5_3[1] = { 'i' };
+static const symbol s_5_4[2] = { 0xC4, 0x83 };
+
+static const struct among a_5[5] =
+{
+/* 0 */ { 1, s_5_0, -1, 1, 0},
+/* 1 */ { 1, s_5_1, -1, 1, 0},
+/* 2 */ { 2, s_5_2, 1, 1, 0},
+/* 3 */ { 1, s_5_3, -1, 1, 0},
+/* 4 */ { 2, s_5_4, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 4 };
+
+static const symbol s_0[] = { 'u' };
+static const symbol s_1[] = { 'U' };
+static const symbol s_2[] = { 'i' };
+static const symbol s_3[] = { 'I' };
+static const symbol s_4[] = { 'i' };
+static const symbol s_5[] = { 'u' };
+static const symbol s_6[] = { 'a' };
+static const symbol s_7[] = { 'e' };
+static const symbol s_8[] = { 'i' };
+static const symbol s_9[] = { 'a', 'b' };
+static const symbol s_10[] = { 'i' };
+static const symbol s_11[] = { 'a', 't' };
+static const symbol s_12[] = { 'a', 0xC5, 0xA3, 'i' };
+static const symbol s_13[] = { 'a', 'b', 'i', 'l' };
+static const symbol s_14[] = { 'i', 'b', 'i', 'l' };
+static const symbol s_15[] = { 'i', 'v' };
+static const symbol s_16[] = { 'i', 'c' };
+static const symbol s_17[] = { 'a', 't' };
+static const symbol s_18[] = { 'i', 't' };
+static const symbol s_19[] = { 0xC5, 0xA3 };
+static const symbol s_20[] = { 't' };
+static const symbol s_21[] = { 'i', 's', 't' };
+static const symbol s_22[] = { 'u' };
+
+static int r_prelude(struct SN_env * z) {
+ while(1) { /* repeat, line 32 */
+ int c1 = z->c;
+ while(1) { /* goto, line 32 */
+ int c2 = z->c;
+ if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1;
+ z->bra = z->c; /* [, line 33 */
+ { int c3 = z->c; /* or, line 33 */
+ if (!(eq_s(z, 1, s_0))) goto lab3;
+ z->ket = z->c; /* ], line 33 */
+ if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab3;
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 33 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab3:
+ z->c = c3;
+ if (!(eq_s(z, 1, s_2))) goto lab1;
+ z->ket = z->c; /* ], line 34 */
+ if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1;
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 34 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab2:
+ z->c = c2;
+ break;
+ lab1:
+ z->c = c2;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* goto, line 32 */
+ }
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 44 */
+ { int c2 = z->c; /* or, line 46 */
+ if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2;
+ { int c3 = z->c; /* or, line 45 */
+ if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab4;
+ { /* gopast */ /* grouping v, line 45 */
+ int ret = out_grouping_U(z, g_v, 97, 259, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c3;
+ if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2;
+ { /* gopast */ /* non v, line 45 */
+ int ret = in_grouping_U(z, g_v, 97, 259, 1);
+ if (ret < 0) goto lab2;
+ z->c += ret;
+ }
+ }
+ lab3:
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab0;
+ { int c4 = z->c; /* or, line 47 */
+ if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab6;
+ { /* gopast */ /* grouping v, line 47 */
+ int ret = out_grouping_U(z, g_v, 97, 259, 1);
+ if (ret < 0) goto lab6;
+ z->c += ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c4;
+ if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab0;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 47 */
+ }
+ }
+ lab5:
+ ;
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 48 */
+ lab0:
+ z->c = c1;
+ }
+ { int c5 = z->c; /* do, line 50 */
+ { /* gopast */ /* grouping v, line 51 */
+ int ret = out_grouping_U(z, g_v, 97, 259, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 51 */
+ int ret = in_grouping_U(z, g_v, 97, 259, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 51 */
+ { /* gopast */ /* grouping v, line 52 */
+ int ret = out_grouping_U(z, g_v, 97, 259, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 52 */
+ int ret = in_grouping_U(z, g_v, 97, 259, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 52 */
+ lab7:
+ z->c = c5;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 56 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 58 */
+ if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else
+ among_var = find_among(z, a_0, 3); /* substring, line 58 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 58 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_5); /* <-, line 60 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 61 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_step_0(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 73 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_1, 16); /* substring, line 73 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 73 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 73 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 75 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_6); /* <-, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_7); /* <-, line 79 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_8); /* <-, line 81 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int m1 = z->l - z->c; (void)m1; /* not, line 83 */
+ if (!(eq_s_b(z, 2, s_9))) goto lab0;
+ return 0;
+ lab0:
+ z->c = z->l - m1;
+ }
+ { int ret = slice_from_s(z, 1, s_10); /* <-, line 83 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 2, s_11); /* <-, line 85 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ { int ret = slice_from_s(z, 4, s_12); /* <-, line 87 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_combo_suffix(struct SN_env * z) {
+ int among_var;
+ { int m_test = z->l - z->c; /* test, line 91 */
+ z->ket = z->c; /* [, line 92 */
+ among_var = find_among_b(z, a_2, 46); /* substring, line 92 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 92 */
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 92 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 4, s_13); /* <-, line 101 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 4, s_14); /* <-, line 104 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 2, s_15); /* <-, line 107 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 2, s_16); /* <-, line 113 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 2, s_17); /* <-, line 118 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_from_s(z, 2, s_18); /* <-, line 122 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->B[0] = 1; /* set standard_suffix_removed, line 125 */
+ z->c = z->l - m_test;
+ }
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->B[0] = 0; /* unset standard_suffix_removed, line 130 */
+ while(1) { /* repeat, line 131 */
+ int m1 = z->l - z->c; (void)m1;
+ { int ret = r_combo_suffix(z);
+ if (ret == 0) goto lab0; /* call combo_suffix, line 131 */
+ if (ret < 0) return ret;
+ }
+ continue;
+ lab0:
+ z->c = z->l - m1;
+ break;
+ }
+ z->ket = z->c; /* [, line 132 */
+ among_var = find_among_b(z, a_3, 62); /* substring, line 132 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 132 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 132 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 149 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (!(eq_s_b(z, 2, s_19))) return 0;
+ z->bra = z->c; /* ], line 152 */
+ { int ret = slice_from_s(z, 1, s_20); /* <-, line 152 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 3, s_21); /* <-, line 156 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->B[0] = 1; /* set standard_suffix_removed, line 160 */
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 164 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 164 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 165 */
+ among_var = find_among_b(z, a_4, 94); /* substring, line 165 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 165 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int m2 = z->l - z->c; (void)m2; /* or, line 200 */
+ if (out_grouping_b_U(z, g_v, 97, 259, 0)) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m2;
+ if (!(eq_s_b(z, 1, s_22))) { z->lb = mlimit; return 0; }
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 200 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 214 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_vowel_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 219 */
+ among_var = find_among_b(z, a_5, 5); /* substring, line 219 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 219 */
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 219 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 220 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int romanian_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 226 */
+ { int ret = r_prelude(z);
+ if (ret == 0) goto lab0; /* call prelude, line 226 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ { int c2 = z->c; /* do, line 227 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab1; /* call mark_regions, line 227 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = c2;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 228 */
+
+ { int m3 = z->l - z->c; (void)m3; /* do, line 229 */
+ { int ret = r_step_0(z);
+ if (ret == 0) goto lab2; /* call step_0, line 229 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 230 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab3; /* call standard_suffix, line 230 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 231 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 231 */
+ if (!(z->B[0])) goto lab6; /* Boolean test standard_suffix_removed, line 231 */
+ goto lab5;
+ lab6:
+ z->c = z->l - m6;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab4; /* call verb_suffix, line 231 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ lab4:
+ z->c = z->l - m5;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 232 */
+ { int ret = r_vowel_suffix(z);
+ if (ret == 0) goto lab7; /* call vowel_suffix, line 232 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = z->l - m7;
+ }
+ z->c = z->lb;
+ { int c8 = z->c; /* do, line 234 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab8; /* call postlude, line 234 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ z->c = c8;
+ }
+ return 1;
+}
+
+extern struct SN_env * romanian_UTF_8_create_env(void) { return SN_create_env(0, 3, 1); }
+
+extern void romanian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_russian.c b/src/backend/snowball/libstemmer/stem_UTF_8_russian.c
new file mode 100644
index 00000000000..fcbcc6cf464
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_russian.c
@@ -0,0 +1,694 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int russian_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_tidy_up(struct SN_env * z);
+static int r_derivational(struct SN_env * z);
+static int r_noun(struct SN_env * z);
+static int r_verb(struct SN_env * z);
+static int r_reflexive(struct SN_env * z);
+static int r_adjectival(struct SN_env * z);
+static int r_adjective(struct SN_env * z);
+static int r_perfective_gerund(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * russian_UTF_8_create_env(void);
+extern void russian_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[10] = { 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8, 0xD1, 0x81, 0xD1, 0x8C };
+static const symbol s_0_1[12] = { 0xD1, 0x8B, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8, 0xD1, 0x81, 0xD1, 0x8C };
+static const symbol s_0_2[12] = { 0xD0, 0xB8, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8, 0xD1, 0x81, 0xD1, 0x8C };
+static const symbol s_0_3[2] = { 0xD0, 0xB2 };
+static const symbol s_0_4[4] = { 0xD1, 0x8B, 0xD0, 0xB2 };
+static const symbol s_0_5[4] = { 0xD0, 0xB8, 0xD0, 0xB2 };
+static const symbol s_0_6[6] = { 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8 };
+static const symbol s_0_7[8] = { 0xD1, 0x8B, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8 };
+static const symbol s_0_8[8] = { 0xD0, 0xB8, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8 };
+
+static const struct among a_0[9] =
+{
+/* 0 */ { 10, s_0_0, -1, 1, 0},
+/* 1 */ { 12, s_0_1, 0, 2, 0},
+/* 2 */ { 12, s_0_2, 0, 2, 0},
+/* 3 */ { 2, s_0_3, -1, 1, 0},
+/* 4 */ { 4, s_0_4, 3, 2, 0},
+/* 5 */ { 4, s_0_5, 3, 2, 0},
+/* 6 */ { 6, s_0_6, -1, 1, 0},
+/* 7 */ { 8, s_0_7, 6, 2, 0},
+/* 8 */ { 8, s_0_8, 6, 2, 0}
+};
+
+static const symbol s_1_0[6] = { 0xD0, 0xB5, 0xD0, 0xBC, 0xD1, 0x83 };
+static const symbol s_1_1[6] = { 0xD0, 0xBE, 0xD0, 0xBC, 0xD1, 0x83 };
+static const symbol s_1_2[4] = { 0xD1, 0x8B, 0xD1, 0x85 };
+static const symbol s_1_3[4] = { 0xD0, 0xB8, 0xD1, 0x85 };
+static const symbol s_1_4[4] = { 0xD1, 0x83, 0xD1, 0x8E };
+static const symbol s_1_5[4] = { 0xD1, 0x8E, 0xD1, 0x8E };
+static const symbol s_1_6[4] = { 0xD0, 0xB5, 0xD1, 0x8E };
+static const symbol s_1_7[4] = { 0xD0, 0xBE, 0xD1, 0x8E };
+static const symbol s_1_8[4] = { 0xD1, 0x8F, 0xD1, 0x8F };
+static const symbol s_1_9[4] = { 0xD0, 0xB0, 0xD1, 0x8F };
+static const symbol s_1_10[4] = { 0xD1, 0x8B, 0xD0, 0xB5 };
+static const symbol s_1_11[4] = { 0xD0, 0xB5, 0xD0, 0xB5 };
+static const symbol s_1_12[4] = { 0xD0, 0xB8, 0xD0, 0xB5 };
+static const symbol s_1_13[4] = { 0xD0, 0xBE, 0xD0, 0xB5 };
+static const symbol s_1_14[6] = { 0xD1, 0x8B, 0xD0, 0xBC, 0xD0, 0xB8 };
+static const symbol s_1_15[6] = { 0xD0, 0xB8, 0xD0, 0xBC, 0xD0, 0xB8 };
+static const symbol s_1_16[4] = { 0xD1, 0x8B, 0xD0, 0xB9 };
+static const symbol s_1_17[4] = { 0xD0, 0xB5, 0xD0, 0xB9 };
+static const symbol s_1_18[4] = { 0xD0, 0xB8, 0xD0, 0xB9 };
+static const symbol s_1_19[4] = { 0xD0, 0xBE, 0xD0, 0xB9 };
+static const symbol s_1_20[4] = { 0xD1, 0x8B, 0xD0, 0xBC };
+static const symbol s_1_21[4] = { 0xD0, 0xB5, 0xD0, 0xBC };
+static const symbol s_1_22[4] = { 0xD0, 0xB8, 0xD0, 0xBC };
+static const symbol s_1_23[4] = { 0xD0, 0xBE, 0xD0, 0xBC };
+static const symbol s_1_24[6] = { 0xD0, 0xB5, 0xD0, 0xB3, 0xD0, 0xBE };
+static const symbol s_1_25[6] = { 0xD0, 0xBE, 0xD0, 0xB3, 0xD0, 0xBE };
+
+static const struct among a_1[26] =
+{
+/* 0 */ { 6, s_1_0, -1, 1, 0},
+/* 1 */ { 6, s_1_1, -1, 1, 0},
+/* 2 */ { 4, s_1_2, -1, 1, 0},
+/* 3 */ { 4, s_1_3, -1, 1, 0},
+/* 4 */ { 4, s_1_4, -1, 1, 0},
+/* 5 */ { 4, s_1_5, -1, 1, 0},
+/* 6 */ { 4, s_1_6, -1, 1, 0},
+/* 7 */ { 4, s_1_7, -1, 1, 0},
+/* 8 */ { 4, s_1_8, -1, 1, 0},
+/* 9 */ { 4, s_1_9, -1, 1, 0},
+/* 10 */ { 4, s_1_10, -1, 1, 0},
+/* 11 */ { 4, s_1_11, -1, 1, 0},
+/* 12 */ { 4, s_1_12, -1, 1, 0},
+/* 13 */ { 4, s_1_13, -1, 1, 0},
+/* 14 */ { 6, s_1_14, -1, 1, 0},
+/* 15 */ { 6, s_1_15, -1, 1, 0},
+/* 16 */ { 4, s_1_16, -1, 1, 0},
+/* 17 */ { 4, s_1_17, -1, 1, 0},
+/* 18 */ { 4, s_1_18, -1, 1, 0},
+/* 19 */ { 4, s_1_19, -1, 1, 0},
+/* 20 */ { 4, s_1_20, -1, 1, 0},
+/* 21 */ { 4, s_1_21, -1, 1, 0},
+/* 22 */ { 4, s_1_22, -1, 1, 0},
+/* 23 */ { 4, s_1_23, -1, 1, 0},
+/* 24 */ { 6, s_1_24, -1, 1, 0},
+/* 25 */ { 6, s_1_25, -1, 1, 0}
+};
+
+static const symbol s_2_0[4] = { 0xD0, 0xB2, 0xD1, 0x88 };
+static const symbol s_2_1[6] = { 0xD1, 0x8B, 0xD0, 0xB2, 0xD1, 0x88 };
+static const symbol s_2_2[6] = { 0xD0, 0xB8, 0xD0, 0xB2, 0xD1, 0x88 };
+static const symbol s_2_3[2] = { 0xD1, 0x89 };
+static const symbol s_2_4[4] = { 0xD1, 0x8E, 0xD1, 0x89 };
+static const symbol s_2_5[6] = { 0xD1, 0x83, 0xD1, 0x8E, 0xD1, 0x89 };
+static const symbol s_2_6[4] = { 0xD0, 0xB5, 0xD0, 0xBC };
+static const symbol s_2_7[4] = { 0xD0, 0xBD, 0xD0, 0xBD };
+
+static const struct among a_2[8] =
+{
+/* 0 */ { 4, s_2_0, -1, 1, 0},
+/* 1 */ { 6, s_2_1, 0, 2, 0},
+/* 2 */ { 6, s_2_2, 0, 2, 0},
+/* 3 */ { 2, s_2_3, -1, 1, 0},
+/* 4 */ { 4, s_2_4, 3, 1, 0},
+/* 5 */ { 6, s_2_5, 4, 2, 0},
+/* 6 */ { 4, s_2_6, -1, 1, 0},
+/* 7 */ { 4, s_2_7, -1, 1, 0}
+};
+
+static const symbol s_3_0[4] = { 0xD1, 0x81, 0xD1, 0x8C };
+static const symbol s_3_1[4] = { 0xD1, 0x81, 0xD1, 0x8F };
+
+static const struct among a_3[2] =
+{
+/* 0 */ { 4, s_3_0, -1, 1, 0},
+/* 1 */ { 4, s_3_1, -1, 1, 0}
+};
+
+static const symbol s_4_0[4] = { 0xD1, 0x8B, 0xD1, 0x82 };
+static const symbol s_4_1[4] = { 0xD1, 0x8E, 0xD1, 0x82 };
+static const symbol s_4_2[6] = { 0xD1, 0x83, 0xD1, 0x8E, 0xD1, 0x82 };
+static const symbol s_4_3[4] = { 0xD1, 0x8F, 0xD1, 0x82 };
+static const symbol s_4_4[4] = { 0xD0, 0xB5, 0xD1, 0x82 };
+static const symbol s_4_5[6] = { 0xD1, 0x83, 0xD0, 0xB5, 0xD1, 0x82 };
+static const symbol s_4_6[4] = { 0xD0, 0xB8, 0xD1, 0x82 };
+static const symbol s_4_7[4] = { 0xD0, 0xBD, 0xD1, 0x8B };
+static const symbol s_4_8[6] = { 0xD0, 0xB5, 0xD0, 0xBD, 0xD1, 0x8B };
+static const symbol s_4_9[4] = { 0xD1, 0x82, 0xD1, 0x8C };
+static const symbol s_4_10[6] = { 0xD1, 0x8B, 0xD1, 0x82, 0xD1, 0x8C };
+static const symbol s_4_11[6] = { 0xD0, 0xB8, 0xD1, 0x82, 0xD1, 0x8C };
+static const symbol s_4_12[6] = { 0xD0, 0xB5, 0xD1, 0x88, 0xD1, 0x8C };
+static const symbol s_4_13[6] = { 0xD0, 0xB8, 0xD1, 0x88, 0xD1, 0x8C };
+static const symbol s_4_14[2] = { 0xD1, 0x8E };
+static const symbol s_4_15[4] = { 0xD1, 0x83, 0xD1, 0x8E };
+static const symbol s_4_16[4] = { 0xD0, 0xBB, 0xD0, 0xB0 };
+static const symbol s_4_17[6] = { 0xD1, 0x8B, 0xD0, 0xBB, 0xD0, 0xB0 };
+static const symbol s_4_18[6] = { 0xD0, 0xB8, 0xD0, 0xBB, 0xD0, 0xB0 };
+static const symbol s_4_19[4] = { 0xD0, 0xBD, 0xD0, 0xB0 };
+static const symbol s_4_20[6] = { 0xD0, 0xB5, 0xD0, 0xBD, 0xD0, 0xB0 };
+static const symbol s_4_21[6] = { 0xD0, 0xB5, 0xD1, 0x82, 0xD0, 0xB5 };
+static const symbol s_4_22[6] = { 0xD0, 0xB8, 0xD1, 0x82, 0xD0, 0xB5 };
+static const symbol s_4_23[6] = { 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5 };
+static const symbol s_4_24[8] = { 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5 };
+static const symbol s_4_25[8] = { 0xD0, 0xB5, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5 };
+static const symbol s_4_26[4] = { 0xD0, 0xBB, 0xD0, 0xB8 };
+static const symbol s_4_27[6] = { 0xD1, 0x8B, 0xD0, 0xBB, 0xD0, 0xB8 };
+static const symbol s_4_28[6] = { 0xD0, 0xB8, 0xD0, 0xBB, 0xD0, 0xB8 };
+static const symbol s_4_29[2] = { 0xD0, 0xB9 };
+static const symbol s_4_30[4] = { 0xD1, 0x83, 0xD0, 0xB9 };
+static const symbol s_4_31[4] = { 0xD0, 0xB5, 0xD0, 0xB9 };
+static const symbol s_4_32[2] = { 0xD0, 0xBB };
+static const symbol s_4_33[4] = { 0xD1, 0x8B, 0xD0, 0xBB };
+static const symbol s_4_34[4] = { 0xD0, 0xB8, 0xD0, 0xBB };
+static const symbol s_4_35[4] = { 0xD1, 0x8B, 0xD0, 0xBC };
+static const symbol s_4_36[4] = { 0xD0, 0xB5, 0xD0, 0xBC };
+static const symbol s_4_37[4] = { 0xD0, 0xB8, 0xD0, 0xBC };
+static const symbol s_4_38[2] = { 0xD0, 0xBD };
+static const symbol s_4_39[4] = { 0xD0, 0xB5, 0xD0, 0xBD };
+static const symbol s_4_40[4] = { 0xD0, 0xBB, 0xD0, 0xBE };
+static const symbol s_4_41[6] = { 0xD1, 0x8B, 0xD0, 0xBB, 0xD0, 0xBE };
+static const symbol s_4_42[6] = { 0xD0, 0xB8, 0xD0, 0xBB, 0xD0, 0xBE };
+static const symbol s_4_43[4] = { 0xD0, 0xBD, 0xD0, 0xBE };
+static const symbol s_4_44[6] = { 0xD0, 0xB5, 0xD0, 0xBD, 0xD0, 0xBE };
+static const symbol s_4_45[6] = { 0xD0, 0xBD, 0xD0, 0xBD, 0xD0, 0xBE };
+
+static const struct among a_4[46] =
+{
+/* 0 */ { 4, s_4_0, -1, 2, 0},
+/* 1 */ { 4, s_4_1, -1, 1, 0},
+/* 2 */ { 6, s_4_2, 1, 2, 0},
+/* 3 */ { 4, s_4_3, -1, 2, 0},
+/* 4 */ { 4, s_4_4, -1, 1, 0},
+/* 5 */ { 6, s_4_5, 4, 2, 0},
+/* 6 */ { 4, s_4_6, -1, 2, 0},
+/* 7 */ { 4, s_4_7, -1, 1, 0},
+/* 8 */ { 6, s_4_8, 7, 2, 0},
+/* 9 */ { 4, s_4_9, -1, 1, 0},
+/* 10 */ { 6, s_4_10, 9, 2, 0},
+/* 11 */ { 6, s_4_11, 9, 2, 0},
+/* 12 */ { 6, s_4_12, -1, 1, 0},
+/* 13 */ { 6, s_4_13, -1, 2, 0},
+/* 14 */ { 2, s_4_14, -1, 2, 0},
+/* 15 */ { 4, s_4_15, 14, 2, 0},
+/* 16 */ { 4, s_4_16, -1, 1, 0},
+/* 17 */ { 6, s_4_17, 16, 2, 0},
+/* 18 */ { 6, s_4_18, 16, 2, 0},
+/* 19 */ { 4, s_4_19, -1, 1, 0},
+/* 20 */ { 6, s_4_20, 19, 2, 0},
+/* 21 */ { 6, s_4_21, -1, 1, 0},
+/* 22 */ { 6, s_4_22, -1, 2, 0},
+/* 23 */ { 6, s_4_23, -1, 1, 0},
+/* 24 */ { 8, s_4_24, 23, 2, 0},
+/* 25 */ { 8, s_4_25, 23, 2, 0},
+/* 26 */ { 4, s_4_26, -1, 1, 0},
+/* 27 */ { 6, s_4_27, 26, 2, 0},
+/* 28 */ { 6, s_4_28, 26, 2, 0},
+/* 29 */ { 2, s_4_29, -1, 1, 0},
+/* 30 */ { 4, s_4_30, 29, 2, 0},
+/* 31 */ { 4, s_4_31, 29, 2, 0},
+/* 32 */ { 2, s_4_32, -1, 1, 0},
+/* 33 */ { 4, s_4_33, 32, 2, 0},
+/* 34 */ { 4, s_4_34, 32, 2, 0},
+/* 35 */ { 4, s_4_35, -1, 2, 0},
+/* 36 */ { 4, s_4_36, -1, 1, 0},
+/* 37 */ { 4, s_4_37, -1, 2, 0},
+/* 38 */ { 2, s_4_38, -1, 1, 0},
+/* 39 */ { 4, s_4_39, 38, 2, 0},
+/* 40 */ { 4, s_4_40, -1, 1, 0},
+/* 41 */ { 6, s_4_41, 40, 2, 0},
+/* 42 */ { 6, s_4_42, 40, 2, 0},
+/* 43 */ { 4, s_4_43, -1, 1, 0},
+/* 44 */ { 6, s_4_44, 43, 2, 0},
+/* 45 */ { 6, s_4_45, 43, 1, 0}
+};
+
+static const symbol s_5_0[2] = { 0xD1, 0x83 };
+static const symbol s_5_1[4] = { 0xD1, 0x8F, 0xD1, 0x85 };
+static const symbol s_5_2[6] = { 0xD0, 0xB8, 0xD1, 0x8F, 0xD1, 0x85 };
+static const symbol s_5_3[4] = { 0xD0, 0xB0, 0xD1, 0x85 };
+static const symbol s_5_4[2] = { 0xD1, 0x8B };
+static const symbol s_5_5[2] = { 0xD1, 0x8C };
+static const symbol s_5_6[2] = { 0xD1, 0x8E };
+static const symbol s_5_7[4] = { 0xD1, 0x8C, 0xD1, 0x8E };
+static const symbol s_5_8[4] = { 0xD0, 0xB8, 0xD1, 0x8E };
+static const symbol s_5_9[2] = { 0xD1, 0x8F };
+static const symbol s_5_10[4] = { 0xD1, 0x8C, 0xD1, 0x8F };
+static const symbol s_5_11[4] = { 0xD0, 0xB8, 0xD1, 0x8F };
+static const symbol s_5_12[2] = { 0xD0, 0xB0 };
+static const symbol s_5_13[4] = { 0xD0, 0xB5, 0xD0, 0xB2 };
+static const symbol s_5_14[4] = { 0xD0, 0xBE, 0xD0, 0xB2 };
+static const symbol s_5_15[2] = { 0xD0, 0xB5 };
+static const symbol s_5_16[4] = { 0xD1, 0x8C, 0xD0, 0xB5 };
+static const symbol s_5_17[4] = { 0xD0, 0xB8, 0xD0, 0xB5 };
+static const symbol s_5_18[2] = { 0xD0, 0xB8 };
+static const symbol s_5_19[4] = { 0xD0, 0xB5, 0xD0, 0xB8 };
+static const symbol s_5_20[4] = { 0xD0, 0xB8, 0xD0, 0xB8 };
+static const symbol s_5_21[6] = { 0xD1, 0x8F, 0xD0, 0xBC, 0xD0, 0xB8 };
+static const symbol s_5_22[8] = { 0xD0, 0xB8, 0xD1, 0x8F, 0xD0, 0xBC, 0xD0, 0xB8 };
+static const symbol s_5_23[6] = { 0xD0, 0xB0, 0xD0, 0xBC, 0xD0, 0xB8 };
+static const symbol s_5_24[2] = { 0xD0, 0xB9 };
+static const symbol s_5_25[4] = { 0xD0, 0xB5, 0xD0, 0xB9 };
+static const symbol s_5_26[6] = { 0xD0, 0xB8, 0xD0, 0xB5, 0xD0, 0xB9 };
+static const symbol s_5_27[4] = { 0xD0, 0xB8, 0xD0, 0xB9 };
+static const symbol s_5_28[4] = { 0xD0, 0xBE, 0xD0, 0xB9 };
+static const symbol s_5_29[4] = { 0xD1, 0x8F, 0xD0, 0xBC };
+static const symbol s_5_30[6] = { 0xD0, 0xB8, 0xD1, 0x8F, 0xD0, 0xBC };
+static const symbol s_5_31[4] = { 0xD0, 0xB0, 0xD0, 0xBC };
+static const symbol s_5_32[4] = { 0xD0, 0xB5, 0xD0, 0xBC };
+static const symbol s_5_33[6] = { 0xD0, 0xB8, 0xD0, 0xB5, 0xD0, 0xBC };
+static const symbol s_5_34[4] = { 0xD0, 0xBE, 0xD0, 0xBC };
+static const symbol s_5_35[2] = { 0xD0, 0xBE };
+
+static const struct among a_5[36] =
+{
+/* 0 */ { 2, s_5_0, -1, 1, 0},
+/* 1 */ { 4, s_5_1, -1, 1, 0},
+/* 2 */ { 6, s_5_2, 1, 1, 0},
+/* 3 */ { 4, s_5_3, -1, 1, 0},
+/* 4 */ { 2, s_5_4, -1, 1, 0},
+/* 5 */ { 2, s_5_5, -1, 1, 0},
+/* 6 */ { 2, s_5_6, -1, 1, 0},
+/* 7 */ { 4, s_5_7, 6, 1, 0},
+/* 8 */ { 4, s_5_8, 6, 1, 0},
+/* 9 */ { 2, s_5_9, -1, 1, 0},
+/* 10 */ { 4, s_5_10, 9, 1, 0},
+/* 11 */ { 4, s_5_11, 9, 1, 0},
+/* 12 */ { 2, s_5_12, -1, 1, 0},
+/* 13 */ { 4, s_5_13, -1, 1, 0},
+/* 14 */ { 4, s_5_14, -1, 1, 0},
+/* 15 */ { 2, s_5_15, -1, 1, 0},
+/* 16 */ { 4, s_5_16, 15, 1, 0},
+/* 17 */ { 4, s_5_17, 15, 1, 0},
+/* 18 */ { 2, s_5_18, -1, 1, 0},
+/* 19 */ { 4, s_5_19, 18, 1, 0},
+/* 20 */ { 4, s_5_20, 18, 1, 0},
+/* 21 */ { 6, s_5_21, 18, 1, 0},
+/* 22 */ { 8, s_5_22, 21, 1, 0},
+/* 23 */ { 6, s_5_23, 18, 1, 0},
+/* 24 */ { 2, s_5_24, -1, 1, 0},
+/* 25 */ { 4, s_5_25, 24, 1, 0},
+/* 26 */ { 6, s_5_26, 25, 1, 0},
+/* 27 */ { 4, s_5_27, 24, 1, 0},
+/* 28 */ { 4, s_5_28, 24, 1, 0},
+/* 29 */ { 4, s_5_29, -1, 1, 0},
+/* 30 */ { 6, s_5_30, 29, 1, 0},
+/* 31 */ { 4, s_5_31, -1, 1, 0},
+/* 32 */ { 4, s_5_32, -1, 1, 0},
+/* 33 */ { 6, s_5_33, 32, 1, 0},
+/* 34 */ { 4, s_5_34, -1, 1, 0},
+/* 35 */ { 2, s_5_35, -1, 1, 0}
+};
+
+static const symbol s_6_0[6] = { 0xD0, 0xBE, 0xD1, 0x81, 0xD1, 0x82 };
+static const symbol s_6_1[8] = { 0xD0, 0xBE, 0xD1, 0x81, 0xD1, 0x82, 0xD1, 0x8C };
+
+static const struct among a_6[2] =
+{
+/* 0 */ { 6, s_6_0, -1, 1, 0},
+/* 1 */ { 8, s_6_1, -1, 1, 0}
+};
+
+static const symbol s_7_0[6] = { 0xD0, 0xB5, 0xD0, 0xB9, 0xD1, 0x88 };
+static const symbol s_7_1[2] = { 0xD1, 0x8C };
+static const symbol s_7_2[8] = { 0xD0, 0xB5, 0xD0, 0xB9, 0xD1, 0x88, 0xD0, 0xB5 };
+static const symbol s_7_3[2] = { 0xD0, 0xBD };
+
+static const struct among a_7[4] =
+{
+/* 0 */ { 6, s_7_0, -1, 1, 0},
+/* 1 */ { 2, s_7_1, -1, 3, 0},
+/* 2 */ { 8, s_7_2, -1, 1, 0},
+/* 3 */ { 2, s_7_3, -1, 2, 0}
+};
+
+static const unsigned char g_v[] = { 33, 65, 8, 232 };
+
+static const symbol s_0[] = { 0xD0, 0xB0 };
+static const symbol s_1[] = { 0xD1, 0x8F };
+static const symbol s_2[] = { 0xD0, 0xB0 };
+static const symbol s_3[] = { 0xD1, 0x8F };
+static const symbol s_4[] = { 0xD0, 0xB0 };
+static const symbol s_5[] = { 0xD1, 0x8F };
+static const symbol s_6[] = { 0xD0, 0xBD };
+static const symbol s_7[] = { 0xD0, 0xBD };
+static const symbol s_8[] = { 0xD0, 0xBD };
+static const symbol s_9[] = { 0xD0, 0xB8 };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ { int c1 = z->c; /* do, line 61 */
+ { /* gopast */ /* grouping v, line 62 */
+ int ret = out_grouping_U(z, g_v, 1072, 1103, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark pV, line 62 */
+ { /* gopast */ /* non v, line 62 */
+ int ret = in_grouping_U(z, g_v, 1072, 1103, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ { /* gopast */ /* grouping v, line 63 */
+ int ret = out_grouping_U(z, g_v, 1072, 1103, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 63 */
+ int ret = in_grouping_U(z, g_v, 1072, 1103, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p2, line 63 */
+ lab0:
+ z->c = c1;
+ }
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_perfective_gerund(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 72 */
+ among_var = find_among_b(z, a_0, 9); /* substring, line 72 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 72 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 76 */
+ if (!(eq_s_b(z, 2, s_0))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 2, s_1))) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 76 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 83 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_adjective(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 88 */
+ among_var = find_among_b(z, a_1, 26); /* substring, line 88 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 88 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 97 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_adjectival(struct SN_env * z) {
+ int among_var;
+ { int ret = r_adjective(z);
+ if (ret == 0) return 0; /* call adjective, line 102 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 109 */
+ z->ket = z->c; /* [, line 110 */
+ among_var = find_among_b(z, a_2, 8); /* substring, line 110 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 110 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab0; }
+ case 1:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 115 */
+ if (!(eq_s_b(z, 2, s_2))) goto lab2;
+ goto lab1;
+ lab2:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 2, s_3))) { z->c = z->l - m_keep; goto lab0; }
+ }
+ lab1:
+ { int ret = slice_del(z); /* delete, line 115 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 122 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab0:
+ ;
+ }
+ return 1;
+}
+
+static int r_reflexive(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 129 */
+ if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 140 && z->p[z->c - 1] != 143)) return 0;
+ among_var = find_among_b(z, a_3, 2); /* substring, line 129 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 129 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 132 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_verb(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 137 */
+ among_var = find_among_b(z, a_4, 46); /* substring, line 137 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 137 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m1 = z->l - z->c; (void)m1; /* or, line 143 */
+ if (!(eq_s_b(z, 2, s_4))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 2, s_5))) return 0;
+ }
+ lab0:
+ { int ret = slice_del(z); /* delete, line 143 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 151 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_noun(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 160 */
+ among_var = find_among_b(z, a_5, 36); /* substring, line 160 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 160 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 167 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_derivational(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 176 */
+ if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 130 && z->p[z->c - 1] != 140)) return 0;
+ among_var = find_among_b(z, a_6, 2); /* substring, line 176 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 176 */
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 176 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 179 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_tidy_up(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 184 */
+ among_var = find_among_b(z, a_7, 4); /* substring, line 184 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 184 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 188 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 189 */
+ if (!(eq_s_b(z, 2, s_6))) return 0;
+ z->bra = z->c; /* ], line 189 */
+ if (!(eq_s_b(z, 2, s_7))) return 0;
+ { int ret = slice_del(z); /* delete, line 189 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (!(eq_s_b(z, 2, s_8))) return 0;
+ { int ret = slice_del(z); /* delete, line 192 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_del(z); /* delete, line 194 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int russian_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 201 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 201 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 202 */
+
+ { int mlimit; /* setlimit, line 202 */
+ int m2 = z->l - z->c; (void)m2;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 202 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m2;
+ { int m3 = z->l - z->c; (void)m3; /* do, line 203 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 204 */
+ { int ret = r_perfective_gerund(z);
+ if (ret == 0) goto lab3; /* call perfective_gerund, line 204 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab3:
+ z->c = z->l - m4;
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 205 */
+ { int ret = r_reflexive(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call reflexive, line 205 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ ;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* or, line 206 */
+ { int ret = r_adjectival(z);
+ if (ret == 0) goto lab6; /* call adjectival, line 206 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m5;
+ { int ret = r_verb(z);
+ if (ret == 0) goto lab7; /* call verb, line 206 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab7:
+ z->c = z->l - m5;
+ { int ret = r_noun(z);
+ if (ret == 0) goto lab1; /* call noun, line 206 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ ;
+ }
+ lab2:
+ lab1:
+ z->c = z->l - m3;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 209 */
+ z->ket = z->c; /* [, line 209 */
+ if (!(eq_s_b(z, 2, s_9))) { z->c = z->l - m_keep; goto lab8; }
+ z->bra = z->c; /* ], line 209 */
+ { int ret = slice_del(z); /* delete, line 209 */
+ if (ret < 0) return ret;
+ }
+ lab8:
+ ;
+ }
+ { int m6 = z->l - z->c; (void)m6; /* do, line 212 */
+ { int ret = r_derivational(z);
+ if (ret == 0) goto lab9; /* call derivational, line 212 */
+ if (ret < 0) return ret;
+ }
+ lab9:
+ z->c = z->l - m6;
+ }
+ { int m7 = z->l - z->c; (void)m7; /* do, line 213 */
+ { int ret = r_tidy_up(z);
+ if (ret == 0) goto lab10; /* call tidy_up, line 213 */
+ if (ret < 0) return ret;
+ }
+ lab10:
+ z->c = z->l - m7;
+ }
+ z->lb = mlimit;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * russian_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); }
+
+extern void russian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c b/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c
new file mode 100644
index 00000000000..5ac83fdc1df
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c
@@ -0,0 +1,1097 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int spanish_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_residual_suffix(struct SN_env * z);
+static int r_verb_suffix(struct SN_env * z);
+static int r_y_verb_suffix(struct SN_env * z);
+static int r_standard_suffix(struct SN_env * z);
+static int r_attached_pronoun(struct SN_env * z);
+static int r_R2(struct SN_env * z);
+static int r_R1(struct SN_env * z);
+static int r_RV(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * spanish_UTF_8_create_env(void);
+extern void spanish_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_1[2] = { 0xC3, 0xA1 };
+static const symbol s_0_2[2] = { 0xC3, 0xA9 };
+static const symbol s_0_3[2] = { 0xC3, 0xAD };
+static const symbol s_0_4[2] = { 0xC3, 0xB3 };
+static const symbol s_0_5[2] = { 0xC3, 0xBA };
+
+static const struct among a_0[6] =
+{
+/* 0 */ { 0, 0, -1, 6, 0},
+/* 1 */ { 2, s_0_1, 0, 1, 0},
+/* 2 */ { 2, s_0_2, 0, 2, 0},
+/* 3 */ { 2, s_0_3, 0, 3, 0},
+/* 4 */ { 2, s_0_4, 0, 4, 0},
+/* 5 */ { 2, s_0_5, 0, 5, 0}
+};
+
+static const symbol s_1_0[2] = { 'l', 'a' };
+static const symbol s_1_1[4] = { 's', 'e', 'l', 'a' };
+static const symbol s_1_2[2] = { 'l', 'e' };
+static const symbol s_1_3[2] = { 'm', 'e' };
+static const symbol s_1_4[2] = { 's', 'e' };
+static const symbol s_1_5[2] = { 'l', 'o' };
+static const symbol s_1_6[4] = { 's', 'e', 'l', 'o' };
+static const symbol s_1_7[3] = { 'l', 'a', 's' };
+static const symbol s_1_8[5] = { 's', 'e', 'l', 'a', 's' };
+static const symbol s_1_9[3] = { 'l', 'e', 's' };
+static const symbol s_1_10[3] = { 'l', 'o', 's' };
+static const symbol s_1_11[5] = { 's', 'e', 'l', 'o', 's' };
+static const symbol s_1_12[3] = { 'n', 'o', 's' };
+
+static const struct among a_1[13] =
+{
+/* 0 */ { 2, s_1_0, -1, -1, 0},
+/* 1 */ { 4, s_1_1, 0, -1, 0},
+/* 2 */ { 2, s_1_2, -1, -1, 0},
+/* 3 */ { 2, s_1_3, -1, -1, 0},
+/* 4 */ { 2, s_1_4, -1, -1, 0},
+/* 5 */ { 2, s_1_5, -1, -1, 0},
+/* 6 */ { 4, s_1_6, 5, -1, 0},
+/* 7 */ { 3, s_1_7, -1, -1, 0},
+/* 8 */ { 5, s_1_8, 7, -1, 0},
+/* 9 */ { 3, s_1_9, -1, -1, 0},
+/* 10 */ { 3, s_1_10, -1, -1, 0},
+/* 11 */ { 5, s_1_11, 10, -1, 0},
+/* 12 */ { 3, s_1_12, -1, -1, 0}
+};
+
+static const symbol s_2_0[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_2_1[5] = { 'i', 'e', 'n', 'd', 'o' };
+static const symbol s_2_2[5] = { 'y', 'e', 'n', 'd', 'o' };
+static const symbol s_2_3[5] = { 0xC3, 0xA1, 'n', 'd', 'o' };
+static const symbol s_2_4[6] = { 'i', 0xC3, 0xA9, 'n', 'd', 'o' };
+static const symbol s_2_5[2] = { 'a', 'r' };
+static const symbol s_2_6[2] = { 'e', 'r' };
+static const symbol s_2_7[2] = { 'i', 'r' };
+static const symbol s_2_8[3] = { 0xC3, 0xA1, 'r' };
+static const symbol s_2_9[3] = { 0xC3, 0xA9, 'r' };
+static const symbol s_2_10[3] = { 0xC3, 0xAD, 'r' };
+
+static const struct among a_2[11] =
+{
+/* 0 */ { 4, s_2_0, -1, 6, 0},
+/* 1 */ { 5, s_2_1, -1, 6, 0},
+/* 2 */ { 5, s_2_2, -1, 7, 0},
+/* 3 */ { 5, s_2_3, -1, 2, 0},
+/* 4 */ { 6, s_2_4, -1, 1, 0},
+/* 5 */ { 2, s_2_5, -1, 6, 0},
+/* 6 */ { 2, s_2_6, -1, 6, 0},
+/* 7 */ { 2, s_2_7, -1, 6, 0},
+/* 8 */ { 3, s_2_8, -1, 3, 0},
+/* 9 */ { 3, s_2_9, -1, 4, 0},
+/* 10 */ { 3, s_2_10, -1, 5, 0}
+};
+
+static const symbol s_3_0[2] = { 'i', 'c' };
+static const symbol s_3_1[2] = { 'a', 'd' };
+static const symbol s_3_2[2] = { 'o', 's' };
+static const symbol s_3_3[2] = { 'i', 'v' };
+
+static const struct among a_3[4] =
+{
+/* 0 */ { 2, s_3_0, -1, -1, 0},
+/* 1 */ { 2, s_3_1, -1, -1, 0},
+/* 2 */ { 2, s_3_2, -1, -1, 0},
+/* 3 */ { 2, s_3_3, -1, 1, 0}
+};
+
+static const symbol s_4_0[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_4_1[4] = { 'i', 'b', 'l', 'e' };
+static const symbol s_4_2[4] = { 'a', 'n', 't', 'e' };
+
+static const struct among a_4[3] =
+{
+/* 0 */ { 4, s_4_0, -1, 1, 0},
+/* 1 */ { 4, s_4_1, -1, 1, 0},
+/* 2 */ { 4, s_4_2, -1, 1, 0}
+};
+
+static const symbol s_5_0[2] = { 'i', 'c' };
+static const symbol s_5_1[4] = { 'a', 'b', 'i', 'l' };
+static const symbol s_5_2[2] = { 'i', 'v' };
+
+static const struct among a_5[3] =
+{
+/* 0 */ { 2, s_5_0, -1, 1, 0},
+/* 1 */ { 4, s_5_1, -1, 1, 0},
+/* 2 */ { 2, s_5_2, -1, 1, 0}
+};
+
+static const symbol s_6_0[3] = { 'i', 'c', 'a' };
+static const symbol s_6_1[5] = { 'a', 'n', 'c', 'i', 'a' };
+static const symbol s_6_2[5] = { 'e', 'n', 'c', 'i', 'a' };
+static const symbol s_6_3[5] = { 'a', 'd', 'o', 'r', 'a' };
+static const symbol s_6_4[3] = { 'o', 's', 'a' };
+static const symbol s_6_5[4] = { 'i', 's', 't', 'a' };
+static const symbol s_6_6[3] = { 'i', 'v', 'a' };
+static const symbol s_6_7[4] = { 'a', 'n', 'z', 'a' };
+static const symbol s_6_8[6] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a' };
+static const symbol s_6_9[4] = { 'i', 'd', 'a', 'd' };
+static const symbol s_6_10[4] = { 'a', 'b', 'l', 'e' };
+static const symbol s_6_11[4] = { 'i', 'b', 'l', 'e' };
+static const symbol s_6_12[4] = { 'a', 'n', 't', 'e' };
+static const symbol s_6_13[5] = { 'm', 'e', 'n', 't', 'e' };
+static const symbol s_6_14[6] = { 'a', 'm', 'e', 'n', 't', 'e' };
+static const symbol s_6_15[6] = { 'a', 'c', 'i', 0xC3, 0xB3, 'n' };
+static const symbol s_6_16[6] = { 'u', 'c', 'i', 0xC3, 0xB3, 'n' };
+static const symbol s_6_17[3] = { 'i', 'c', 'o' };
+static const symbol s_6_18[4] = { 'i', 's', 'm', 'o' };
+static const symbol s_6_19[3] = { 'o', 's', 'o' };
+static const symbol s_6_20[7] = { 'a', 'm', 'i', 'e', 'n', 't', 'o' };
+static const symbol s_6_21[7] = { 'i', 'm', 'i', 'e', 'n', 't', 'o' };
+static const symbol s_6_22[3] = { 'i', 'v', 'o' };
+static const symbol s_6_23[4] = { 'a', 'd', 'o', 'r' };
+static const symbol s_6_24[4] = { 'i', 'c', 'a', 's' };
+static const symbol s_6_25[6] = { 'a', 'n', 'c', 'i', 'a', 's' };
+static const symbol s_6_26[6] = { 'e', 'n', 'c', 'i', 'a', 's' };
+static const symbol s_6_27[6] = { 'a', 'd', 'o', 'r', 'a', 's' };
+static const symbol s_6_28[4] = { 'o', 's', 'a', 's' };
+static const symbol s_6_29[5] = { 'i', 's', 't', 'a', 's' };
+static const symbol s_6_30[4] = { 'i', 'v', 'a', 's' };
+static const symbol s_6_31[5] = { 'a', 'n', 'z', 'a', 's' };
+static const symbol s_6_32[7] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a', 's' };
+static const symbol s_6_33[6] = { 'i', 'd', 'a', 'd', 'e', 's' };
+static const symbol s_6_34[5] = { 'a', 'b', 'l', 'e', 's' };
+static const symbol s_6_35[5] = { 'i', 'b', 'l', 'e', 's' };
+static const symbol s_6_36[7] = { 'a', 'c', 'i', 'o', 'n', 'e', 's' };
+static const symbol s_6_37[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' };
+static const symbol s_6_38[6] = { 'a', 'd', 'o', 'r', 'e', 's' };
+static const symbol s_6_39[5] = { 'a', 'n', 't', 'e', 's' };
+static const symbol s_6_40[4] = { 'i', 'c', 'o', 's' };
+static const symbol s_6_41[5] = { 'i', 's', 'm', 'o', 's' };
+static const symbol s_6_42[4] = { 'o', 's', 'o', 's' };
+static const symbol s_6_43[8] = { 'a', 'm', 'i', 'e', 'n', 't', 'o', 's' };
+static const symbol s_6_44[8] = { 'i', 'm', 'i', 'e', 'n', 't', 'o', 's' };
+static const symbol s_6_45[4] = { 'i', 'v', 'o', 's' };
+
+static const struct among a_6[46] =
+{
+/* 0 */ { 3, s_6_0, -1, 1, 0},
+/* 1 */ { 5, s_6_1, -1, 2, 0},
+/* 2 */ { 5, s_6_2, -1, 5, 0},
+/* 3 */ { 5, s_6_3, -1, 2, 0},
+/* 4 */ { 3, s_6_4, -1, 1, 0},
+/* 5 */ { 4, s_6_5, -1, 1, 0},
+/* 6 */ { 3, s_6_6, -1, 9, 0},
+/* 7 */ { 4, s_6_7, -1, 1, 0},
+/* 8 */ { 6, s_6_8, -1, 3, 0},
+/* 9 */ { 4, s_6_9, -1, 8, 0},
+/* 10 */ { 4, s_6_10, -1, 1, 0},
+/* 11 */ { 4, s_6_11, -1, 1, 0},
+/* 12 */ { 4, s_6_12, -1, 2, 0},
+/* 13 */ { 5, s_6_13, -1, 7, 0},
+/* 14 */ { 6, s_6_14, 13, 6, 0},
+/* 15 */ { 6, s_6_15, -1, 2, 0},
+/* 16 */ { 6, s_6_16, -1, 4, 0},
+/* 17 */ { 3, s_6_17, -1, 1, 0},
+/* 18 */ { 4, s_6_18, -1, 1, 0},
+/* 19 */ { 3, s_6_19, -1, 1, 0},
+/* 20 */ { 7, s_6_20, -1, 1, 0},
+/* 21 */ { 7, s_6_21, -1, 1, 0},
+/* 22 */ { 3, s_6_22, -1, 9, 0},
+/* 23 */ { 4, s_6_23, -1, 2, 0},
+/* 24 */ { 4, s_6_24, -1, 1, 0},
+/* 25 */ { 6, s_6_25, -1, 2, 0},
+/* 26 */ { 6, s_6_26, -1, 5, 0},
+/* 27 */ { 6, s_6_27, -1, 2, 0},
+/* 28 */ { 4, s_6_28, -1, 1, 0},
+/* 29 */ { 5, s_6_29, -1, 1, 0},
+/* 30 */ { 4, s_6_30, -1, 9, 0},
+/* 31 */ { 5, s_6_31, -1, 1, 0},
+/* 32 */ { 7, s_6_32, -1, 3, 0},
+/* 33 */ { 6, s_6_33, -1, 8, 0},
+/* 34 */ { 5, s_6_34, -1, 1, 0},
+/* 35 */ { 5, s_6_35, -1, 1, 0},
+/* 36 */ { 7, s_6_36, -1, 2, 0},
+/* 37 */ { 7, s_6_37, -1, 4, 0},
+/* 38 */ { 6, s_6_38, -1, 2, 0},
+/* 39 */ { 5, s_6_39, -1, 2, 0},
+/* 40 */ { 4, s_6_40, -1, 1, 0},
+/* 41 */ { 5, s_6_41, -1, 1, 0},
+/* 42 */ { 4, s_6_42, -1, 1, 0},
+/* 43 */ { 8, s_6_43, -1, 1, 0},
+/* 44 */ { 8, s_6_44, -1, 1, 0},
+/* 45 */ { 4, s_6_45, -1, 9, 0}
+};
+
+static const symbol s_7_0[2] = { 'y', 'a' };
+static const symbol s_7_1[2] = { 'y', 'e' };
+static const symbol s_7_2[3] = { 'y', 'a', 'n' };
+static const symbol s_7_3[3] = { 'y', 'e', 'n' };
+static const symbol s_7_4[5] = { 'y', 'e', 'r', 'o', 'n' };
+static const symbol s_7_5[5] = { 'y', 'e', 'n', 'd', 'o' };
+static const symbol s_7_6[2] = { 'y', 'o' };
+static const symbol s_7_7[3] = { 'y', 'a', 's' };
+static const symbol s_7_8[3] = { 'y', 'e', 's' };
+static const symbol s_7_9[4] = { 'y', 'a', 'i', 's' };
+static const symbol s_7_10[5] = { 'y', 'a', 'm', 'o', 's' };
+static const symbol s_7_11[3] = { 'y', 0xC3, 0xB3 };
+
+static const struct among a_7[12] =
+{
+/* 0 */ { 2, s_7_0, -1, 1, 0},
+/* 1 */ { 2, s_7_1, -1, 1, 0},
+/* 2 */ { 3, s_7_2, -1, 1, 0},
+/* 3 */ { 3, s_7_3, -1, 1, 0},
+/* 4 */ { 5, s_7_4, -1, 1, 0},
+/* 5 */ { 5, s_7_5, -1, 1, 0},
+/* 6 */ { 2, s_7_6, -1, 1, 0},
+/* 7 */ { 3, s_7_7, -1, 1, 0},
+/* 8 */ { 3, s_7_8, -1, 1, 0},
+/* 9 */ { 4, s_7_9, -1, 1, 0},
+/* 10 */ { 5, s_7_10, -1, 1, 0},
+/* 11 */ { 3, s_7_11, -1, 1, 0}
+};
+
+static const symbol s_8_0[3] = { 'a', 'b', 'a' };
+static const symbol s_8_1[3] = { 'a', 'd', 'a' };
+static const symbol s_8_2[3] = { 'i', 'd', 'a' };
+static const symbol s_8_3[3] = { 'a', 'r', 'a' };
+static const symbol s_8_4[4] = { 'i', 'e', 'r', 'a' };
+static const symbol s_8_5[3] = { 0xC3, 0xAD, 'a' };
+static const symbol s_8_6[5] = { 'a', 'r', 0xC3, 0xAD, 'a' };
+static const symbol s_8_7[5] = { 'e', 'r', 0xC3, 0xAD, 'a' };
+static const symbol s_8_8[5] = { 'i', 'r', 0xC3, 0xAD, 'a' };
+static const symbol s_8_9[2] = { 'a', 'd' };
+static const symbol s_8_10[2] = { 'e', 'd' };
+static const symbol s_8_11[2] = { 'i', 'd' };
+static const symbol s_8_12[3] = { 'a', 's', 'e' };
+static const symbol s_8_13[4] = { 'i', 'e', 's', 'e' };
+static const symbol s_8_14[4] = { 'a', 's', 't', 'e' };
+static const symbol s_8_15[4] = { 'i', 's', 't', 'e' };
+static const symbol s_8_16[2] = { 'a', 'n' };
+static const symbol s_8_17[4] = { 'a', 'b', 'a', 'n' };
+static const symbol s_8_18[4] = { 'a', 'r', 'a', 'n' };
+static const symbol s_8_19[5] = { 'i', 'e', 'r', 'a', 'n' };
+static const symbol s_8_20[4] = { 0xC3, 0xAD, 'a', 'n' };
+static const symbol s_8_21[6] = { 'a', 'r', 0xC3, 0xAD, 'a', 'n' };
+static const symbol s_8_22[6] = { 'e', 'r', 0xC3, 0xAD, 'a', 'n' };
+static const symbol s_8_23[6] = { 'i', 'r', 0xC3, 0xAD, 'a', 'n' };
+static const symbol s_8_24[2] = { 'e', 'n' };
+static const symbol s_8_25[4] = { 'a', 's', 'e', 'n' };
+static const symbol s_8_26[5] = { 'i', 'e', 's', 'e', 'n' };
+static const symbol s_8_27[4] = { 'a', 'r', 'o', 'n' };
+static const symbol s_8_28[5] = { 'i', 'e', 'r', 'o', 'n' };
+static const symbol s_8_29[5] = { 'a', 'r', 0xC3, 0xA1, 'n' };
+static const symbol s_8_30[5] = { 'e', 'r', 0xC3, 0xA1, 'n' };
+static const symbol s_8_31[5] = { 'i', 'r', 0xC3, 0xA1, 'n' };
+static const symbol s_8_32[3] = { 'a', 'd', 'o' };
+static const symbol s_8_33[3] = { 'i', 'd', 'o' };
+static const symbol s_8_34[4] = { 'a', 'n', 'd', 'o' };
+static const symbol s_8_35[5] = { 'i', 'e', 'n', 'd', 'o' };
+static const symbol s_8_36[2] = { 'a', 'r' };
+static const symbol s_8_37[2] = { 'e', 'r' };
+static const symbol s_8_38[2] = { 'i', 'r' };
+static const symbol s_8_39[2] = { 'a', 's' };
+static const symbol s_8_40[4] = { 'a', 'b', 'a', 's' };
+static const symbol s_8_41[4] = { 'a', 'd', 'a', 's' };
+static const symbol s_8_42[4] = { 'i', 'd', 'a', 's' };
+static const symbol s_8_43[4] = { 'a', 'r', 'a', 's' };
+static const symbol s_8_44[5] = { 'i', 'e', 'r', 'a', 's' };
+static const symbol s_8_45[4] = { 0xC3, 0xAD, 'a', 's' };
+static const symbol s_8_46[6] = { 'a', 'r', 0xC3, 0xAD, 'a', 's' };
+static const symbol s_8_47[6] = { 'e', 'r', 0xC3, 0xAD, 'a', 's' };
+static const symbol s_8_48[6] = { 'i', 'r', 0xC3, 0xAD, 'a', 's' };
+static const symbol s_8_49[2] = { 'e', 's' };
+static const symbol s_8_50[4] = { 'a', 's', 'e', 's' };
+static const symbol s_8_51[5] = { 'i', 'e', 's', 'e', 's' };
+static const symbol s_8_52[5] = { 'a', 'b', 'a', 'i', 's' };
+static const symbol s_8_53[5] = { 'a', 'r', 'a', 'i', 's' };
+static const symbol s_8_54[6] = { 'i', 'e', 'r', 'a', 'i', 's' };
+static const symbol s_8_55[5] = { 0xC3, 0xAD, 'a', 'i', 's' };
+static const symbol s_8_56[7] = { 'a', 'r', 0xC3, 0xAD, 'a', 'i', 's' };
+static const symbol s_8_57[7] = { 'e', 'r', 0xC3, 0xAD, 'a', 'i', 's' };
+static const symbol s_8_58[7] = { 'i', 'r', 0xC3, 0xAD, 'a', 'i', 's' };
+static const symbol s_8_59[5] = { 'a', 's', 'e', 'i', 's' };
+static const symbol s_8_60[6] = { 'i', 'e', 's', 'e', 'i', 's' };
+static const symbol s_8_61[6] = { 'a', 's', 't', 'e', 'i', 's' };
+static const symbol s_8_62[6] = { 'i', 's', 't', 'e', 'i', 's' };
+static const symbol s_8_63[4] = { 0xC3, 0xA1, 'i', 's' };
+static const symbol s_8_64[4] = { 0xC3, 0xA9, 'i', 's' };
+static const symbol s_8_65[6] = { 'a', 'r', 0xC3, 0xA9, 'i', 's' };
+static const symbol s_8_66[6] = { 'e', 'r', 0xC3, 0xA9, 'i', 's' };
+static const symbol s_8_67[6] = { 'i', 'r', 0xC3, 0xA9, 'i', 's' };
+static const symbol s_8_68[4] = { 'a', 'd', 'o', 's' };
+static const symbol s_8_69[4] = { 'i', 'd', 'o', 's' };
+static const symbol s_8_70[4] = { 'a', 'm', 'o', 's' };
+static const symbol s_8_71[7] = { 0xC3, 0xA1, 'b', 'a', 'm', 'o', 's' };
+static const symbol s_8_72[7] = { 0xC3, 0xA1, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_8_73[8] = { 'i', 0xC3, 0xA9, 'r', 'a', 'm', 'o', 's' };
+static const symbol s_8_74[6] = { 0xC3, 0xAD, 'a', 'm', 'o', 's' };
+static const symbol s_8_75[8] = { 'a', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' };
+static const symbol s_8_76[8] = { 'e', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' };
+static const symbol s_8_77[8] = { 'i', 'r', 0xC3, 0xAD, 'a', 'm', 'o', 's' };
+static const symbol s_8_78[4] = { 'e', 'm', 'o', 's' };
+static const symbol s_8_79[6] = { 'a', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_8_80[6] = { 'e', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_8_81[6] = { 'i', 'r', 'e', 'm', 'o', 's' };
+static const symbol s_8_82[7] = { 0xC3, 0xA1, 's', 'e', 'm', 'o', 's' };
+static const symbol s_8_83[8] = { 'i', 0xC3, 0xA9, 's', 'e', 'm', 'o', 's' };
+static const symbol s_8_84[4] = { 'i', 'm', 'o', 's' };
+static const symbol s_8_85[5] = { 'a', 'r', 0xC3, 0xA1, 's' };
+static const symbol s_8_86[5] = { 'e', 'r', 0xC3, 0xA1, 's' };
+static const symbol s_8_87[5] = { 'i', 'r', 0xC3, 0xA1, 's' };
+static const symbol s_8_88[3] = { 0xC3, 0xAD, 's' };
+static const symbol s_8_89[4] = { 'a', 'r', 0xC3, 0xA1 };
+static const symbol s_8_90[4] = { 'e', 'r', 0xC3, 0xA1 };
+static const symbol s_8_91[4] = { 'i', 'r', 0xC3, 0xA1 };
+static const symbol s_8_92[4] = { 'a', 'r', 0xC3, 0xA9 };
+static const symbol s_8_93[4] = { 'e', 'r', 0xC3, 0xA9 };
+static const symbol s_8_94[4] = { 'i', 'r', 0xC3, 0xA9 };
+static const symbol s_8_95[3] = { 'i', 0xC3, 0xB3 };
+
+static const struct among a_8[96] =
+{
+/* 0 */ { 3, s_8_0, -1, 2, 0},
+/* 1 */ { 3, s_8_1, -1, 2, 0},
+/* 2 */ { 3, s_8_2, -1, 2, 0},
+/* 3 */ { 3, s_8_3, -1, 2, 0},
+/* 4 */ { 4, s_8_4, -1, 2, 0},
+/* 5 */ { 3, s_8_5, -1, 2, 0},
+/* 6 */ { 5, s_8_6, 5, 2, 0},
+/* 7 */ { 5, s_8_7, 5, 2, 0},
+/* 8 */ { 5, s_8_8, 5, 2, 0},
+/* 9 */ { 2, s_8_9, -1, 2, 0},
+/* 10 */ { 2, s_8_10, -1, 2, 0},
+/* 11 */ { 2, s_8_11, -1, 2, 0},
+/* 12 */ { 3, s_8_12, -1, 2, 0},
+/* 13 */ { 4, s_8_13, -1, 2, 0},
+/* 14 */ { 4, s_8_14, -1, 2, 0},
+/* 15 */ { 4, s_8_15, -1, 2, 0},
+/* 16 */ { 2, s_8_16, -1, 2, 0},
+/* 17 */ { 4, s_8_17, 16, 2, 0},
+/* 18 */ { 4, s_8_18, 16, 2, 0},
+/* 19 */ { 5, s_8_19, 16, 2, 0},
+/* 20 */ { 4, s_8_20, 16, 2, 0},
+/* 21 */ { 6, s_8_21, 20, 2, 0},
+/* 22 */ { 6, s_8_22, 20, 2, 0},
+/* 23 */ { 6, s_8_23, 20, 2, 0},
+/* 24 */ { 2, s_8_24, -1, 1, 0},
+/* 25 */ { 4, s_8_25, 24, 2, 0},
+/* 26 */ { 5, s_8_26, 24, 2, 0},
+/* 27 */ { 4, s_8_27, -1, 2, 0},
+/* 28 */ { 5, s_8_28, -1, 2, 0},
+/* 29 */ { 5, s_8_29, -1, 2, 0},
+/* 30 */ { 5, s_8_30, -1, 2, 0},
+/* 31 */ { 5, s_8_31, -1, 2, 0},
+/* 32 */ { 3, s_8_32, -1, 2, 0},
+/* 33 */ { 3, s_8_33, -1, 2, 0},
+/* 34 */ { 4, s_8_34, -1, 2, 0},
+/* 35 */ { 5, s_8_35, -1, 2, 0},
+/* 36 */ { 2, s_8_36, -1, 2, 0},
+/* 37 */ { 2, s_8_37, -1, 2, 0},
+/* 38 */ { 2, s_8_38, -1, 2, 0},
+/* 39 */ { 2, s_8_39, -1, 2, 0},
+/* 40 */ { 4, s_8_40, 39, 2, 0},
+/* 41 */ { 4, s_8_41, 39, 2, 0},
+/* 42 */ { 4, s_8_42, 39, 2, 0},
+/* 43 */ { 4, s_8_43, 39, 2, 0},
+/* 44 */ { 5, s_8_44, 39, 2, 0},
+/* 45 */ { 4, s_8_45, 39, 2, 0},
+/* 46 */ { 6, s_8_46, 45, 2, 0},
+/* 47 */ { 6, s_8_47, 45, 2, 0},
+/* 48 */ { 6, s_8_48, 45, 2, 0},
+/* 49 */ { 2, s_8_49, -1, 1, 0},
+/* 50 */ { 4, s_8_50, 49, 2, 0},
+/* 51 */ { 5, s_8_51, 49, 2, 0},
+/* 52 */ { 5, s_8_52, -1, 2, 0},
+/* 53 */ { 5, s_8_53, -1, 2, 0},
+/* 54 */ { 6, s_8_54, -1, 2, 0},
+/* 55 */ { 5, s_8_55, -1, 2, 0},
+/* 56 */ { 7, s_8_56, 55, 2, 0},
+/* 57 */ { 7, s_8_57, 55, 2, 0},
+/* 58 */ { 7, s_8_58, 55, 2, 0},
+/* 59 */ { 5, s_8_59, -1, 2, 0},
+/* 60 */ { 6, s_8_60, -1, 2, 0},
+/* 61 */ { 6, s_8_61, -1, 2, 0},
+/* 62 */ { 6, s_8_62, -1, 2, 0},
+/* 63 */ { 4, s_8_63, -1, 2, 0},
+/* 64 */ { 4, s_8_64, -1, 1, 0},
+/* 65 */ { 6, s_8_65, 64, 2, 0},
+/* 66 */ { 6, s_8_66, 64, 2, 0},
+/* 67 */ { 6, s_8_67, 64, 2, 0},
+/* 68 */ { 4, s_8_68, -1, 2, 0},
+/* 69 */ { 4, s_8_69, -1, 2, 0},
+/* 70 */ { 4, s_8_70, -1, 2, 0},
+/* 71 */ { 7, s_8_71, 70, 2, 0},
+/* 72 */ { 7, s_8_72, 70, 2, 0},
+/* 73 */ { 8, s_8_73, 70, 2, 0},
+/* 74 */ { 6, s_8_74, 70, 2, 0},
+/* 75 */ { 8, s_8_75, 74, 2, 0},
+/* 76 */ { 8, s_8_76, 74, 2, 0},
+/* 77 */ { 8, s_8_77, 74, 2, 0},
+/* 78 */ { 4, s_8_78, -1, 1, 0},
+/* 79 */ { 6, s_8_79, 78, 2, 0},
+/* 80 */ { 6, s_8_80, 78, 2, 0},
+/* 81 */ { 6, s_8_81, 78, 2, 0},
+/* 82 */ { 7, s_8_82, 78, 2, 0},
+/* 83 */ { 8, s_8_83, 78, 2, 0},
+/* 84 */ { 4, s_8_84, -1, 2, 0},
+/* 85 */ { 5, s_8_85, -1, 2, 0},
+/* 86 */ { 5, s_8_86, -1, 2, 0},
+/* 87 */ { 5, s_8_87, -1, 2, 0},
+/* 88 */ { 3, s_8_88, -1, 2, 0},
+/* 89 */ { 4, s_8_89, -1, 2, 0},
+/* 90 */ { 4, s_8_90, -1, 2, 0},
+/* 91 */ { 4, s_8_91, -1, 2, 0},
+/* 92 */ { 4, s_8_92, -1, 2, 0},
+/* 93 */ { 4, s_8_93, -1, 2, 0},
+/* 94 */ { 4, s_8_94, -1, 2, 0},
+/* 95 */ { 3, s_8_95, -1, 2, 0}
+};
+
+static const symbol s_9_0[1] = { 'a' };
+static const symbol s_9_1[1] = { 'e' };
+static const symbol s_9_2[1] = { 'o' };
+static const symbol s_9_3[2] = { 'o', 's' };
+static const symbol s_9_4[2] = { 0xC3, 0xA1 };
+static const symbol s_9_5[2] = { 0xC3, 0xA9 };
+static const symbol s_9_6[2] = { 0xC3, 0xAD };
+static const symbol s_9_7[2] = { 0xC3, 0xB3 };
+
+static const struct among a_9[8] =
+{
+/* 0 */ { 1, s_9_0, -1, 1, 0},
+/* 1 */ { 1, s_9_1, -1, 2, 0},
+/* 2 */ { 1, s_9_2, -1, 1, 0},
+/* 3 */ { 2, s_9_3, -1, 1, 0},
+/* 4 */ { 2, s_9_4, -1, 1, 0},
+/* 5 */ { 2, s_9_5, -1, 2, 0},
+/* 6 */ { 2, s_9_6, -1, 1, 0},
+/* 7 */ { 2, s_9_7, -1, 1, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10 };
+
+static const symbol s_0[] = { 'a' };
+static const symbol s_1[] = { 'e' };
+static const symbol s_2[] = { 'i' };
+static const symbol s_3[] = { 'o' };
+static const symbol s_4[] = { 'u' };
+static const symbol s_5[] = { 'i', 'e', 'n', 'd', 'o' };
+static const symbol s_6[] = { 'a', 'n', 'd', 'o' };
+static const symbol s_7[] = { 'a', 'r' };
+static const symbol s_8[] = { 'e', 'r' };
+static const symbol s_9[] = { 'i', 'r' };
+static const symbol s_10[] = { 'u' };
+static const symbol s_11[] = { 'i', 'c' };
+static const symbol s_12[] = { 'l', 'o', 'g' };
+static const symbol s_13[] = { 'u' };
+static const symbol s_14[] = { 'e', 'n', 't', 'e' };
+static const symbol s_15[] = { 'a', 't' };
+static const symbol s_16[] = { 'a', 't' };
+static const symbol s_17[] = { 'u' };
+static const symbol s_18[] = { 'u' };
+static const symbol s_19[] = { 'g' };
+static const symbol s_20[] = { 'u' };
+static const symbol s_21[] = { 'g' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ z->I[1] = z->l;
+ z->I[2] = z->l;
+ { int c1 = z->c; /* do, line 37 */
+ { int c2 = z->c; /* or, line 39 */
+ if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2;
+ { int c3 = z->c; /* or, line 38 */
+ if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab4;
+ { /* gopast */ /* grouping v, line 38 */
+ int ret = out_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab4;
+ z->c += ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = c3;
+ if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2;
+ { /* gopast */ /* non v, line 38 */
+ int ret = in_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab2;
+ z->c += ret;
+ }
+ }
+ lab3:
+ goto lab1;
+ lab2:
+ z->c = c2;
+ if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab0;
+ { int c4 = z->c; /* or, line 40 */
+ if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab6;
+ { /* gopast */ /* grouping v, line 40 */
+ int ret = out_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab6;
+ z->c += ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = c4;
+ if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab0;
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 40 */
+ }
+ }
+ lab5:
+ ;
+ }
+ lab1:
+ z->I[0] = z->c; /* setmark pV, line 41 */
+ lab0:
+ z->c = c1;
+ }
+ { int c5 = z->c; /* do, line 43 */
+ { /* gopast */ /* grouping v, line 44 */
+ int ret = out_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 44 */
+ int ret = in_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[1] = z->c; /* setmark p1, line 44 */
+ { /* gopast */ /* grouping v, line 45 */
+ int ret = out_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ { /* gopast */ /* non v, line 45 */
+ int ret = in_grouping_U(z, g_v, 97, 252, 1);
+ if (ret < 0) goto lab7;
+ z->c += ret;
+ }
+ z->I[2] = z->c; /* setmark p2, line 45 */
+ lab7:
+ z->c = c5;
+ }
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ int among_var;
+ while(1) { /* repeat, line 49 */
+ int c1 = z->c;
+ z->bra = z->c; /* [, line 50 */
+ if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((67641858 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else
+ among_var = find_among(z, a_0, 6); /* substring, line 50 */
+ if (!(among_var)) goto lab0;
+ z->ket = z->c; /* ], line 50 */
+ switch(among_var) {
+ case 0: goto lab0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_0); /* <-, line 51 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 1, s_1); /* <-, line 52 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_2); /* <-, line 53 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_3); /* <-, line 54 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = slice_from_s(z, 1, s_4); /* <-, line 55 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab0;
+ z->c = ret; /* next, line 57 */
+ }
+ break;
+ }
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ return 1;
+}
+
+static int r_RV(struct SN_env * z) {
+ if (!(z->I[0] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R1(struct SN_env * z) {
+ if (!(z->I[1] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_R2(struct SN_env * z) {
+ if (!(z->I[2] <= z->c)) return 0;
+ return 1;
+}
+
+static int r_attached_pronoun(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 68 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_1, 13))) return 0; /* substring, line 68 */
+ z->bra = z->c; /* ], line 68 */
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0;
+ among_var = find_among_b(z, a_2, 11); /* substring, line 72 */
+ if (!(among_var)) return 0;
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 72 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ z->bra = z->c; /* ], line 73 */
+ { int ret = slice_from_s(z, 5, s_5); /* <-, line 73 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ z->bra = z->c; /* ], line 74 */
+ { int ret = slice_from_s(z, 4, s_6); /* <-, line 74 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ z->bra = z->c; /* ], line 75 */
+ { int ret = slice_from_s(z, 2, s_7); /* <-, line 75 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ z->bra = z->c; /* ], line 76 */
+ { int ret = slice_from_s(z, 2, s_8); /* <-, line 76 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ z->bra = z->c; /* ], line 77 */
+ { int ret = slice_from_s(z, 2, s_9); /* <-, line 77 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = slice_del(z); /* delete, line 81 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 7:
+ if (!(eq_s_b(z, 1, s_10))) return 0;
+ { int ret = slice_del(z); /* delete, line 82 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_standard_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 87 */
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ among_var = find_among_b(z, a_6, 46); /* substring, line 87 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 87 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 99 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 99 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 105 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 105 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 106 */
+ z->ket = z->c; /* [, line 106 */
+ if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 106 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 106 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 106 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ break;
+ case 3:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 111 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 3, s_12); /* <-, line 111 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 115 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 1, s_13); /* <-, line 115 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 5:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 119 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_from_s(z, 4, s_14); /* <-, line 119 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 6:
+ { int ret = r_R1(z);
+ if (ret == 0) return 0; /* call R1, line 123 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 123 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 124 */
+ z->ket = z->c; /* [, line 125 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab1; }
+ among_var = find_among_b(z, a_3, 4); /* substring, line 125 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 125 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 125 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 125 */
+ if (ret < 0) return ret;
+ }
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab1; }
+ case 1:
+ z->ket = z->c; /* [, line 126 */
+ if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m_keep; goto lab1; }
+ z->bra = z->c; /* ], line 126 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 126 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 126 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab1:
+ ;
+ }
+ break;
+ case 7:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 135 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 135 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 136 */
+ z->ket = z->c; /* [, line 137 */
+ if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m_keep; goto lab2; }
+ among_var = find_among_b(z, a_4, 3); /* substring, line 137 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab2; }
+ z->bra = z->c; /* ], line 137 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab2; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 140 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 140 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab2:
+ ;
+ }
+ break;
+ case 8:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 147 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 147 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 148 */
+ z->ket = z->c; /* [, line 149 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab3; }
+ among_var = find_among_b(z, a_5, 3); /* substring, line 149 */
+ if (!(among_var)) { z->c = z->l - m_keep; goto lab3; }
+ z->bra = z->c; /* ], line 149 */
+ switch(among_var) {
+ case 0: { z->c = z->l - m_keep; goto lab3; }
+ case 1:
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 152 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 152 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ lab3:
+ ;
+ }
+ break;
+ case 9:
+ { int ret = r_R2(z);
+ if (ret == 0) return 0; /* call R2, line 159 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 159 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 160 */
+ z->ket = z->c; /* [, line 161 */
+ if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m_keep; goto lab4; }
+ z->bra = z->c; /* ], line 161 */
+ { int ret = r_R2(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call R2, line 161 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 161 */
+ if (ret < 0) return ret;
+ }
+ lab4:
+ ;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_y_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 168 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 168 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 168 */
+ among_var = find_among_b(z, a_7, 12); /* substring, line 168 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 168 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ if (!(eq_s_b(z, 1, s_17))) return 0;
+ { int ret = slice_del(z); /* delete, line 171 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_verb_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 176 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 176 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 176 */
+ among_var = find_among_b(z, a_8, 96); /* substring, line 176 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 176 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 179 */
+ if (!(eq_s_b(z, 1, s_18))) { z->c = z->l - m_keep; goto lab0; }
+ { int m_test = z->l - z->c; /* test, line 179 */
+ if (!(eq_s_b(z, 1, s_19))) { z->c = z->l - m_keep; goto lab0; }
+ z->c = z->l - m_test;
+ }
+ lab0:
+ ;
+ }
+ z->bra = z->c; /* ], line 179 */
+ { int ret = slice_del(z); /* delete, line 179 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_del(z); /* delete, line 200 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_residual_suffix(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 205 */
+ among_var = find_among_b(z, a_9, 8); /* substring, line 205 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 205 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 208 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 208 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = r_RV(z);
+ if (ret == 0) return 0; /* call RV, line 210 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 210 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 210 */
+ z->ket = z->c; /* [, line 210 */
+ if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m_keep; goto lab0; }
+ z->bra = z->c; /* ], line 210 */
+ { int m_test = z->l - z->c; /* test, line 210 */
+ if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m_keep; goto lab0; }
+ z->c = z->l - m_test;
+ }
+ { int ret = r_RV(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 210 */
+ if (ret < 0) return ret;
+ }
+ { int ret = slice_del(z); /* delete, line 210 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ ;
+ }
+ break;
+ }
+ return 1;
+}
+
+extern int spanish_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 216 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 216 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 217 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 218 */
+ { int ret = r_attached_pronoun(z);
+ if (ret == 0) goto lab1; /* call attached_pronoun, line 218 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 219 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 219 */
+ { int ret = r_standard_suffix(z);
+ if (ret == 0) goto lab4; /* call standard_suffix, line 219 */
+ if (ret < 0) return ret;
+ }
+ goto lab3;
+ lab4:
+ z->c = z->l - m4;
+ { int ret = r_y_verb_suffix(z);
+ if (ret == 0) goto lab5; /* call y_verb_suffix, line 220 */
+ if (ret < 0) return ret;
+ }
+ goto lab3;
+ lab5:
+ z->c = z->l - m4;
+ { int ret = r_verb_suffix(z);
+ if (ret == 0) goto lab2; /* call verb_suffix, line 221 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab3:
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* do, line 223 */
+ { int ret = r_residual_suffix(z);
+ if (ret == 0) goto lab6; /* call residual_suffix, line 223 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ z->c = z->l - m5;
+ }
+ z->c = z->lb;
+ { int c6 = z->c; /* do, line 225 */
+ { int ret = r_postlude(z);
+ if (ret == 0) goto lab7; /* call postlude, line 225 */
+ if (ret < 0) return ret;
+ }
+ lab7:
+ z->c = c6;
+ }
+ return 1;
+}
+
+extern struct SN_env * spanish_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); }
+
+extern void spanish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c b/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c
new file mode 100644
index 00000000000..1372cec1eeb
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c
@@ -0,0 +1,309 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int swedish_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_other_suffix(struct SN_env * z);
+static int r_consonant_pair(struct SN_env * z);
+static int r_main_suffix(struct SN_env * z);
+static int r_mark_regions(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * swedish_UTF_8_create_env(void);
+extern void swedish_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[1] = { 'a' };
+static const symbol s_0_1[4] = { 'a', 'r', 'n', 'a' };
+static const symbol s_0_2[4] = { 'e', 'r', 'n', 'a' };
+static const symbol s_0_3[7] = { 'h', 'e', 't', 'e', 'r', 'n', 'a' };
+static const symbol s_0_4[4] = { 'o', 'r', 'n', 'a' };
+static const symbol s_0_5[2] = { 'a', 'd' };
+static const symbol s_0_6[1] = { 'e' };
+static const symbol s_0_7[3] = { 'a', 'd', 'e' };
+static const symbol s_0_8[4] = { 'a', 'n', 'd', 'e' };
+static const symbol s_0_9[4] = { 'a', 'r', 'n', 'e' };
+static const symbol s_0_10[3] = { 'a', 'r', 'e' };
+static const symbol s_0_11[4] = { 'a', 's', 't', 'e' };
+static const symbol s_0_12[2] = { 'e', 'n' };
+static const symbol s_0_13[5] = { 'a', 'n', 'd', 'e', 'n' };
+static const symbol s_0_14[4] = { 'a', 'r', 'e', 'n' };
+static const symbol s_0_15[5] = { 'h', 'e', 't', 'e', 'n' };
+static const symbol s_0_16[3] = { 'e', 'r', 'n' };
+static const symbol s_0_17[2] = { 'a', 'r' };
+static const symbol s_0_18[2] = { 'e', 'r' };
+static const symbol s_0_19[5] = { 'h', 'e', 't', 'e', 'r' };
+static const symbol s_0_20[2] = { 'o', 'r' };
+static const symbol s_0_21[1] = { 's' };
+static const symbol s_0_22[2] = { 'a', 's' };
+static const symbol s_0_23[5] = { 'a', 'r', 'n', 'a', 's' };
+static const symbol s_0_24[5] = { 'e', 'r', 'n', 'a', 's' };
+static const symbol s_0_25[5] = { 'o', 'r', 'n', 'a', 's' };
+static const symbol s_0_26[2] = { 'e', 's' };
+static const symbol s_0_27[4] = { 'a', 'd', 'e', 's' };
+static const symbol s_0_28[5] = { 'a', 'n', 'd', 'e', 's' };
+static const symbol s_0_29[3] = { 'e', 'n', 's' };
+static const symbol s_0_30[5] = { 'a', 'r', 'e', 'n', 's' };
+static const symbol s_0_31[6] = { 'h', 'e', 't', 'e', 'n', 's' };
+static const symbol s_0_32[4] = { 'e', 'r', 'n', 's' };
+static const symbol s_0_33[2] = { 'a', 't' };
+static const symbol s_0_34[5] = { 'a', 'n', 'd', 'e', 't' };
+static const symbol s_0_35[3] = { 'h', 'e', 't' };
+static const symbol s_0_36[3] = { 'a', 's', 't' };
+
+static const struct among a_0[37] =
+{
+/* 0 */ { 1, s_0_0, -1, 1, 0},
+/* 1 */ { 4, s_0_1, 0, 1, 0},
+/* 2 */ { 4, s_0_2, 0, 1, 0},
+/* 3 */ { 7, s_0_3, 2, 1, 0},
+/* 4 */ { 4, s_0_4, 0, 1, 0},
+/* 5 */ { 2, s_0_5, -1, 1, 0},
+/* 6 */ { 1, s_0_6, -1, 1, 0},
+/* 7 */ { 3, s_0_7, 6, 1, 0},
+/* 8 */ { 4, s_0_8, 6, 1, 0},
+/* 9 */ { 4, s_0_9, 6, 1, 0},
+/* 10 */ { 3, s_0_10, 6, 1, 0},
+/* 11 */ { 4, s_0_11, 6, 1, 0},
+/* 12 */ { 2, s_0_12, -1, 1, 0},
+/* 13 */ { 5, s_0_13, 12, 1, 0},
+/* 14 */ { 4, s_0_14, 12, 1, 0},
+/* 15 */ { 5, s_0_15, 12, 1, 0},
+/* 16 */ { 3, s_0_16, -1, 1, 0},
+/* 17 */ { 2, s_0_17, -1, 1, 0},
+/* 18 */ { 2, s_0_18, -1, 1, 0},
+/* 19 */ { 5, s_0_19, 18, 1, 0},
+/* 20 */ { 2, s_0_20, -1, 1, 0},
+/* 21 */ { 1, s_0_21, -1, 2, 0},
+/* 22 */ { 2, s_0_22, 21, 1, 0},
+/* 23 */ { 5, s_0_23, 22, 1, 0},
+/* 24 */ { 5, s_0_24, 22, 1, 0},
+/* 25 */ { 5, s_0_25, 22, 1, 0},
+/* 26 */ { 2, s_0_26, 21, 1, 0},
+/* 27 */ { 4, s_0_27, 26, 1, 0},
+/* 28 */ { 5, s_0_28, 26, 1, 0},
+/* 29 */ { 3, s_0_29, 21, 1, 0},
+/* 30 */ { 5, s_0_30, 29, 1, 0},
+/* 31 */ { 6, s_0_31, 29, 1, 0},
+/* 32 */ { 4, s_0_32, 21, 1, 0},
+/* 33 */ { 2, s_0_33, -1, 1, 0},
+/* 34 */ { 5, s_0_34, -1, 1, 0},
+/* 35 */ { 3, s_0_35, -1, 1, 0},
+/* 36 */ { 3, s_0_36, -1, 1, 0}
+};
+
+static const symbol s_1_0[2] = { 'd', 'd' };
+static const symbol s_1_1[2] = { 'g', 'd' };
+static const symbol s_1_2[2] = { 'n', 'n' };
+static const symbol s_1_3[2] = { 'd', 't' };
+static const symbol s_1_4[2] = { 'g', 't' };
+static const symbol s_1_5[2] = { 'k', 't' };
+static const symbol s_1_6[2] = { 't', 't' };
+
+static const struct among a_1[7] =
+{
+/* 0 */ { 2, s_1_0, -1, -1, 0},
+/* 1 */ { 2, s_1_1, -1, -1, 0},
+/* 2 */ { 2, s_1_2, -1, -1, 0},
+/* 3 */ { 2, s_1_3, -1, -1, 0},
+/* 4 */ { 2, s_1_4, -1, -1, 0},
+/* 5 */ { 2, s_1_5, -1, -1, 0},
+/* 6 */ { 2, s_1_6, -1, -1, 0}
+};
+
+static const symbol s_2_0[2] = { 'i', 'g' };
+static const symbol s_2_1[3] = { 'l', 'i', 'g' };
+static const symbol s_2_2[3] = { 'e', 'l', 's' };
+static const symbol s_2_3[5] = { 'f', 'u', 'l', 'l', 't' };
+static const symbol s_2_4[5] = { 'l', 0xC3, 0xB6, 's', 't' };
+
+static const struct among a_2[5] =
+{
+/* 0 */ { 2, s_2_0, -1, 1, 0},
+/* 1 */ { 3, s_2_1, 0, 1, 0},
+/* 2 */ { 3, s_2_2, -1, 1, 0},
+/* 3 */ { 5, s_2_3, -1, 3, 0},
+/* 4 */ { 5, s_2_4, -1, 2, 0}
+};
+
+static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32 };
+
+static const unsigned char g_s_ending[] = { 119, 127, 149 };
+
+static const symbol s_0[] = { 'l', 0xC3, 0xB6, 's' };
+static const symbol s_1[] = { 'f', 'u', 'l', 'l' };
+
+static int r_mark_regions(struct SN_env * z) {
+ z->I[0] = z->l;
+ { int c_test = z->c; /* test, line 29 */
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3);
+ if (ret < 0) return 0;
+ z->c = ret; /* hop, line 29 */
+ }
+ z->I[1] = z->c; /* setmark x, line 29 */
+ z->c = c_test;
+ }
+ if (out_grouping_U(z, g_v, 97, 246, 1) < 0) return 0; /* goto */ /* grouping v, line 30 */
+ { /* gopast */ /* non v, line 30 */
+ int ret = in_grouping_U(z, g_v, 97, 246, 1);
+ if (ret < 0) return 0;
+ z->c += ret;
+ }
+ z->I[0] = z->c; /* setmark p1, line 30 */
+ /* try, line 31 */
+ if (!(z->I[0] < z->I[1])) goto lab0;
+ z->I[0] = z->I[1];
+lab0:
+ return 1;
+}
+
+static int r_main_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 37 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 37 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 37 */
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_0, 37); /* substring, line 37 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 37 */
+ z->lb = mlimit;
+ }
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_del(z); /* delete, line 44 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ if (in_grouping_b_U(z, g_s_ending, 98, 121, 0)) return 0;
+ { int ret = slice_del(z); /* delete, line 46 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_consonant_pair(struct SN_env * z) {
+ { int mlimit; /* setlimit, line 50 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 50 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* and, line 52 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ if (!(find_among_b(z, a_1, 7))) { z->lb = mlimit; return 0; } /* among, line 51 */
+ z->c = z->l - m2;
+ z->ket = z->c; /* [, line 52 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) { z->lb = mlimit; return 0; }
+ z->c = ret; /* next, line 52 */
+ }
+ z->bra = z->c; /* ], line 52 */
+ { int ret = slice_del(z); /* delete, line 52 */
+ if (ret < 0) return ret;
+ }
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+static int r_other_suffix(struct SN_env * z) {
+ int among_var;
+ { int mlimit; /* setlimit, line 55 */
+ int m1 = z->l - z->c; (void)m1;
+ if (z->c < z->I[0]) return 0;
+ z->c = z->I[0]; /* tomark, line 55 */
+ mlimit = z->lb; z->lb = z->c;
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 56 */
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; }
+ among_var = find_among_b(z, a_2, 5); /* substring, line 56 */
+ if (!(among_var)) { z->lb = mlimit; return 0; }
+ z->bra = z->c; /* ], line 56 */
+ switch(among_var) {
+ case 0: { z->lb = mlimit; return 0; }
+ case 1:
+ { int ret = slice_del(z); /* delete, line 57 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 4, s_0); /* <-, line 58 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 4, s_1); /* <-, line 59 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ z->lb = mlimit;
+ }
+ return 1;
+}
+
+extern int swedish_UTF_8_stem(struct SN_env * z) {
+ { int c1 = z->c; /* do, line 66 */
+ { int ret = r_mark_regions(z);
+ if (ret == 0) goto lab0; /* call mark_regions, line 66 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 67 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 68 */
+ { int ret = r_main_suffix(z);
+ if (ret == 0) goto lab1; /* call main_suffix, line 68 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 69 */
+ { int ret = r_consonant_pair(z);
+ if (ret == 0) goto lab2; /* call consonant_pair, line 69 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ { int m4 = z->l - z->c; (void)m4; /* do, line 70 */
+ { int ret = r_other_suffix(z);
+ if (ret == 0) goto lab3; /* call other_suffix, line 70 */
+ if (ret < 0) return ret;
+ }
+ lab3:
+ z->c = z->l - m4;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern struct SN_env * swedish_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); }
+
+extern void swedish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c b/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c
new file mode 100644
index 00000000000..587351d126f
--- /dev/null
+++ b/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c
@@ -0,0 +1,2205 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#include "header.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int turkish_UTF_8_stem(struct SN_env * z);
+#ifdef __cplusplus
+}
+#endif
+static int r_stem_suffix_chain_before_ki(struct SN_env * z);
+static int r_stem_noun_suffixes(struct SN_env * z);
+static int r_stem_nominal_verb_suffixes(struct SN_env * z);
+static int r_postlude(struct SN_env * z);
+static int r_post_process_last_consonants(struct SN_env * z);
+static int r_more_than_one_syllable_word(struct SN_env * z);
+static int r_mark_suffix_with_optional_s_consonant(struct SN_env * z);
+static int r_mark_suffix_with_optional_n_consonant(struct SN_env * z);
+static int r_mark_suffix_with_optional_U_vowel(struct SN_env * z);
+static int r_mark_suffix_with_optional_y_consonant(struct SN_env * z);
+static int r_mark_ysA(struct SN_env * z);
+static int r_mark_ymUs_(struct SN_env * z);
+static int r_mark_yken(struct SN_env * z);
+static int r_mark_yDU(struct SN_env * z);
+static int r_mark_yUz(struct SN_env * z);
+static int r_mark_yUm(struct SN_env * z);
+static int r_mark_yU(struct SN_env * z);
+static int r_mark_ylA(struct SN_env * z);
+static int r_mark_yA(struct SN_env * z);
+static int r_mark_possessives(struct SN_env * z);
+static int r_mark_sUnUz(struct SN_env * z);
+static int r_mark_sUn(struct SN_env * z);
+static int r_mark_sU(struct SN_env * z);
+static int r_mark_nUz(struct SN_env * z);
+static int r_mark_nUn(struct SN_env * z);
+static int r_mark_nU(struct SN_env * z);
+static int r_mark_ndAn(struct SN_env * z);
+static int r_mark_ndA(struct SN_env * z);
+static int r_mark_ncA(struct SN_env * z);
+static int r_mark_nA(struct SN_env * z);
+static int r_mark_lArI(struct SN_env * z);
+static int r_mark_lAr(struct SN_env * z);
+static int r_mark_ki(struct SN_env * z);
+static int r_mark_DUr(struct SN_env * z);
+static int r_mark_DAn(struct SN_env * z);
+static int r_mark_DA(struct SN_env * z);
+static int r_mark_cAsInA(struct SN_env * z);
+static int r_is_reserved_word(struct SN_env * z);
+static int r_check_vowel_harmony(struct SN_env * z);
+static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern struct SN_env * turkish_UTF_8_create_env(void);
+extern void turkish_UTF_8_close_env(struct SN_env * z);
+
+
+#ifdef __cplusplus
+}
+#endif
+static const symbol s_0_0[1] = { 'm' };
+static const symbol s_0_1[1] = { 'n' };
+static const symbol s_0_2[3] = { 'm', 'i', 'z' };
+static const symbol s_0_3[3] = { 'n', 'i', 'z' };
+static const symbol s_0_4[3] = { 'm', 'u', 'z' };
+static const symbol s_0_5[3] = { 'n', 'u', 'z' };
+static const symbol s_0_6[4] = { 'm', 0xC4, 0xB1, 'z' };
+static const symbol s_0_7[4] = { 'n', 0xC4, 0xB1, 'z' };
+static const symbol s_0_8[4] = { 'm', 0xC3, 0xBC, 'z' };
+static const symbol s_0_9[4] = { 'n', 0xC3, 0xBC, 'z' };
+
+static const struct among a_0[10] =
+{
+/* 0 */ { 1, s_0_0, -1, -1, 0},
+/* 1 */ { 1, s_0_1, -1, -1, 0},
+/* 2 */ { 3, s_0_2, -1, -1, 0},
+/* 3 */ { 3, s_0_3, -1, -1, 0},
+/* 4 */ { 3, s_0_4, -1, -1, 0},
+/* 5 */ { 3, s_0_5, -1, -1, 0},
+/* 6 */ { 4, s_0_6, -1, -1, 0},
+/* 7 */ { 4, s_0_7, -1, -1, 0},
+/* 8 */ { 4, s_0_8, -1, -1, 0},
+/* 9 */ { 4, s_0_9, -1, -1, 0}
+};
+
+static const symbol s_1_0[4] = { 'l', 'e', 'r', 'i' };
+static const symbol s_1_1[5] = { 'l', 'a', 'r', 0xC4, 0xB1 };
+
+static const struct among a_1[2] =
+{
+/* 0 */ { 4, s_1_0, -1, -1, 0},
+/* 1 */ { 5, s_1_1, -1, -1, 0}
+};
+
+static const symbol s_2_0[2] = { 'n', 'i' };
+static const symbol s_2_1[2] = { 'n', 'u' };
+static const symbol s_2_2[3] = { 'n', 0xC4, 0xB1 };
+static const symbol s_2_3[3] = { 'n', 0xC3, 0xBC };
+
+static const struct among a_2[4] =
+{
+/* 0 */ { 2, s_2_0, -1, -1, 0},
+/* 1 */ { 2, s_2_1, -1, -1, 0},
+/* 2 */ { 3, s_2_2, -1, -1, 0},
+/* 3 */ { 3, s_2_3, -1, -1, 0}
+};
+
+static const symbol s_3_0[2] = { 'i', 'n' };
+static const symbol s_3_1[2] = { 'u', 'n' };
+static const symbol s_3_2[3] = { 0xC4, 0xB1, 'n' };
+static const symbol s_3_3[3] = { 0xC3, 0xBC, 'n' };
+
+static const struct among a_3[4] =
+{
+/* 0 */ { 2, s_3_0, -1, -1, 0},
+/* 1 */ { 2, s_3_1, -1, -1, 0},
+/* 2 */ { 3, s_3_2, -1, -1, 0},
+/* 3 */ { 3, s_3_3, -1, -1, 0}
+};
+
+static const symbol s_4_0[1] = { 'a' };
+static const symbol s_4_1[1] = { 'e' };
+
+static const struct among a_4[2] =
+{
+/* 0 */ { 1, s_4_0, -1, -1, 0},
+/* 1 */ { 1, s_4_1, -1, -1, 0}
+};
+
+static const symbol s_5_0[2] = { 'n', 'a' };
+static const symbol s_5_1[2] = { 'n', 'e' };
+
+static const struct among a_5[2] =
+{
+/* 0 */ { 2, s_5_0, -1, -1, 0},
+/* 1 */ { 2, s_5_1, -1, -1, 0}
+};
+
+static const symbol s_6_0[2] = { 'd', 'a' };
+static const symbol s_6_1[2] = { 't', 'a' };
+static const symbol s_6_2[2] = { 'd', 'e' };
+static const symbol s_6_3[2] = { 't', 'e' };
+
+static const struct among a_6[4] =
+{
+/* 0 */ { 2, s_6_0, -1, -1, 0},
+/* 1 */ { 2, s_6_1, -1, -1, 0},
+/* 2 */ { 2, s_6_2, -1, -1, 0},
+/* 3 */ { 2, s_6_3, -1, -1, 0}
+};
+
+static const symbol s_7_0[3] = { 'n', 'd', 'a' };
+static const symbol s_7_1[3] = { 'n', 'd', 'e' };
+
+static const struct among a_7[2] =
+{
+/* 0 */ { 3, s_7_0, -1, -1, 0},
+/* 1 */ { 3, s_7_1, -1, -1, 0}
+};
+
+static const symbol s_8_0[3] = { 'd', 'a', 'n' };
+static const symbol s_8_1[3] = { 't', 'a', 'n' };
+static const symbol s_8_2[3] = { 'd', 'e', 'n' };
+static const symbol s_8_3[3] = { 't', 'e', 'n' };
+
+static const struct among a_8[4] =
+{
+/* 0 */ { 3, s_8_0, -1, -1, 0},
+/* 1 */ { 3, s_8_1, -1, -1, 0},
+/* 2 */ { 3, s_8_2, -1, -1, 0},
+/* 3 */ { 3, s_8_3, -1, -1, 0}
+};
+
+static const symbol s_9_0[4] = { 'n', 'd', 'a', 'n' };
+static const symbol s_9_1[4] = { 'n', 'd', 'e', 'n' };
+
+static const struct among a_9[2] =
+{
+/* 0 */ { 4, s_9_0, -1, -1, 0},
+/* 1 */ { 4, s_9_1, -1, -1, 0}
+};
+
+static const symbol s_10_0[2] = { 'l', 'a' };
+static const symbol s_10_1[2] = { 'l', 'e' };
+
+static const struct among a_10[2] =
+{
+/* 0 */ { 2, s_10_0, -1, -1, 0},
+/* 1 */ { 2, s_10_1, -1, -1, 0}
+};
+
+static const symbol s_11_0[2] = { 'c', 'a' };
+static const symbol s_11_1[2] = { 'c', 'e' };
+
+static const struct among a_11[2] =
+{
+/* 0 */ { 2, s_11_0, -1, -1, 0},
+/* 1 */ { 2, s_11_1, -1, -1, 0}
+};
+
+static const symbol s_12_0[2] = { 'i', 'm' };
+static const symbol s_12_1[2] = { 'u', 'm' };
+static const symbol s_12_2[3] = { 0xC4, 0xB1, 'm' };
+static const symbol s_12_3[3] = { 0xC3, 0xBC, 'm' };
+
+static const struct among a_12[4] =
+{
+/* 0 */ { 2, s_12_0, -1, -1, 0},
+/* 1 */ { 2, s_12_1, -1, -1, 0},
+/* 2 */ { 3, s_12_2, -1, -1, 0},
+/* 3 */ { 3, s_12_3, -1, -1, 0}
+};
+
+static const symbol s_13_0[3] = { 's', 'i', 'n' };
+static const symbol s_13_1[3] = { 's', 'u', 'n' };
+static const symbol s_13_2[4] = { 's', 0xC4, 0xB1, 'n' };
+static const symbol s_13_3[4] = { 's', 0xC3, 0xBC, 'n' };
+
+static const struct among a_13[4] =
+{
+/* 0 */ { 3, s_13_0, -1, -1, 0},
+/* 1 */ { 3, s_13_1, -1, -1, 0},
+/* 2 */ { 4, s_13_2, -1, -1, 0},
+/* 3 */ { 4, s_13_3, -1, -1, 0}
+};
+
+static const symbol s_14_0[2] = { 'i', 'z' };
+static const symbol s_14_1[2] = { 'u', 'z' };
+static const symbol s_14_2[3] = { 0xC4, 0xB1, 'z' };
+static const symbol s_14_3[3] = { 0xC3, 0xBC, 'z' };
+
+static const struct among a_14[4] =
+{
+/* 0 */ { 2, s_14_0, -1, -1, 0},
+/* 1 */ { 2, s_14_1, -1, -1, 0},
+/* 2 */ { 3, s_14_2, -1, -1, 0},
+/* 3 */ { 3, s_14_3, -1, -1, 0}
+};
+
+static const symbol s_15_0[5] = { 's', 'i', 'n', 'i', 'z' };
+static const symbol s_15_1[5] = { 's', 'u', 'n', 'u', 'z' };
+static const symbol s_15_2[7] = { 's', 0xC4, 0xB1, 'n', 0xC4, 0xB1, 'z' };
+static const symbol s_15_3[7] = { 's', 0xC3, 0xBC, 'n', 0xC3, 0xBC, 'z' };
+
+static const struct among a_15[4] =
+{
+/* 0 */ { 5, s_15_0, -1, -1, 0},
+/* 1 */ { 5, s_15_1, -1, -1, 0},
+/* 2 */ { 7, s_15_2, -1, -1, 0},
+/* 3 */ { 7, s_15_3, -1, -1, 0}
+};
+
+static const symbol s_16_0[3] = { 'l', 'a', 'r' };
+static const symbol s_16_1[3] = { 'l', 'e', 'r' };
+
+static const struct among a_16[2] =
+{
+/* 0 */ { 3, s_16_0, -1, -1, 0},
+/* 1 */ { 3, s_16_1, -1, -1, 0}
+};
+
+static const symbol s_17_0[3] = { 'n', 'i', 'z' };
+static const symbol s_17_1[3] = { 'n', 'u', 'z' };
+static const symbol s_17_2[4] = { 'n', 0xC4, 0xB1, 'z' };
+static const symbol s_17_3[4] = { 'n', 0xC3, 0xBC, 'z' };
+
+static const struct among a_17[4] =
+{
+/* 0 */ { 3, s_17_0, -1, -1, 0},
+/* 1 */ { 3, s_17_1, -1, -1, 0},
+/* 2 */ { 4, s_17_2, -1, -1, 0},
+/* 3 */ { 4, s_17_3, -1, -1, 0}
+};
+
+static const symbol s_18_0[3] = { 'd', 'i', 'r' };
+static const symbol s_18_1[3] = { 't', 'i', 'r' };
+static const symbol s_18_2[3] = { 'd', 'u', 'r' };
+static const symbol s_18_3[3] = { 't', 'u', 'r' };
+static const symbol s_18_4[4] = { 'd', 0xC4, 0xB1, 'r' };
+static const symbol s_18_5[4] = { 't', 0xC4, 0xB1, 'r' };
+static const symbol s_18_6[4] = { 'd', 0xC3, 0xBC, 'r' };
+static const symbol s_18_7[4] = { 't', 0xC3, 0xBC, 'r' };
+
+static const struct among a_18[8] =
+{
+/* 0 */ { 3, s_18_0, -1, -1, 0},
+/* 1 */ { 3, s_18_1, -1, -1, 0},
+/* 2 */ { 3, s_18_2, -1, -1, 0},
+/* 3 */ { 3, s_18_3, -1, -1, 0},
+/* 4 */ { 4, s_18_4, -1, -1, 0},
+/* 5 */ { 4, s_18_5, -1, -1, 0},
+/* 6 */ { 4, s_18_6, -1, -1, 0},
+/* 7 */ { 4, s_18_7, -1, -1, 0}
+};
+
+static const symbol s_19_0[7] = { 'c', 'a', 's', 0xC4, 0xB1, 'n', 'a' };
+static const symbol s_19_1[6] = { 'c', 'e', 's', 'i', 'n', 'e' };
+
+static const struct among a_19[2] =
+{
+/* 0 */ { 7, s_19_0, -1, -1, 0},
+/* 1 */ { 6, s_19_1, -1, -1, 0}
+};
+
+static const symbol s_20_0[2] = { 'd', 'i' };
+static const symbol s_20_1[2] = { 't', 'i' };
+static const symbol s_20_2[3] = { 'd', 'i', 'k' };
+static const symbol s_20_3[3] = { 't', 'i', 'k' };
+static const symbol s_20_4[3] = { 'd', 'u', 'k' };
+static const symbol s_20_5[3] = { 't', 'u', 'k' };
+static const symbol s_20_6[4] = { 'd', 0xC4, 0xB1, 'k' };
+static const symbol s_20_7[4] = { 't', 0xC4, 0xB1, 'k' };
+static const symbol s_20_8[4] = { 'd', 0xC3, 0xBC, 'k' };
+static const symbol s_20_9[4] = { 't', 0xC3, 0xBC, 'k' };
+static const symbol s_20_10[3] = { 'd', 'i', 'm' };
+static const symbol s_20_11[3] = { 't', 'i', 'm' };
+static const symbol s_20_12[3] = { 'd', 'u', 'm' };
+static const symbol s_20_13[3] = { 't', 'u', 'm' };
+static const symbol s_20_14[4] = { 'd', 0xC4, 0xB1, 'm' };
+static const symbol s_20_15[4] = { 't', 0xC4, 0xB1, 'm' };
+static const symbol s_20_16[4] = { 'd', 0xC3, 0xBC, 'm' };
+static const symbol s_20_17[4] = { 't', 0xC3, 0xBC, 'm' };
+static const symbol s_20_18[3] = { 'd', 'i', 'n' };
+static const symbol s_20_19[3] = { 't', 'i', 'n' };
+static const symbol s_20_20[3] = { 'd', 'u', 'n' };
+static const symbol s_20_21[3] = { 't', 'u', 'n' };
+static const symbol s_20_22[4] = { 'd', 0xC4, 0xB1, 'n' };
+static const symbol s_20_23[4] = { 't', 0xC4, 0xB1, 'n' };
+static const symbol s_20_24[4] = { 'd', 0xC3, 0xBC, 'n' };
+static const symbol s_20_25[4] = { 't', 0xC3, 0xBC, 'n' };
+static const symbol s_20_26[2] = { 'd', 'u' };
+static const symbol s_20_27[2] = { 't', 'u' };
+static const symbol s_20_28[3] = { 'd', 0xC4, 0xB1 };
+static const symbol s_20_29[3] = { 't', 0xC4, 0xB1 };
+static const symbol s_20_30[3] = { 'd', 0xC3, 0xBC };
+static const symbol s_20_31[3] = { 't', 0xC3, 0xBC };
+
+static const struct among a_20[32] =
+{
+/* 0 */ { 2, s_20_0, -1, -1, 0},
+/* 1 */ { 2, s_20_1, -1, -1, 0},
+/* 2 */ { 3, s_20_2, -1, -1, 0},
+/* 3 */ { 3, s_20_3, -1, -1, 0},
+/* 4 */ { 3, s_20_4, -1, -1, 0},
+/* 5 */ { 3, s_20_5, -1, -1, 0},
+/* 6 */ { 4, s_20_6, -1, -1, 0},
+/* 7 */ { 4, s_20_7, -1, -1, 0},
+/* 8 */ { 4, s_20_8, -1, -1, 0},
+/* 9 */ { 4, s_20_9, -1, -1, 0},
+/* 10 */ { 3, s_20_10, -1, -1, 0},
+/* 11 */ { 3, s_20_11, -1, -1, 0},
+/* 12 */ { 3, s_20_12, -1, -1, 0},
+/* 13 */ { 3, s_20_13, -1, -1, 0},
+/* 14 */ { 4, s_20_14, -1, -1, 0},
+/* 15 */ { 4, s_20_15, -1, -1, 0},
+/* 16 */ { 4, s_20_16, -1, -1, 0},
+/* 17 */ { 4, s_20_17, -1, -1, 0},
+/* 18 */ { 3, s_20_18, -1, -1, 0},
+/* 19 */ { 3, s_20_19, -1, -1, 0},
+/* 20 */ { 3, s_20_20, -1, -1, 0},
+/* 21 */ { 3, s_20_21, -1, -1, 0},
+/* 22 */ { 4, s_20_22, -1, -1, 0},
+/* 23 */ { 4, s_20_23, -1, -1, 0},
+/* 24 */ { 4, s_20_24, -1, -1, 0},
+/* 25 */ { 4, s_20_25, -1, -1, 0},
+/* 26 */ { 2, s_20_26, -1, -1, 0},
+/* 27 */ { 2, s_20_27, -1, -1, 0},
+/* 28 */ { 3, s_20_28, -1, -1, 0},
+/* 29 */ { 3, s_20_29, -1, -1, 0},
+/* 30 */ { 3, s_20_30, -1, -1, 0},
+/* 31 */ { 3, s_20_31, -1, -1, 0}
+};
+
+static const symbol s_21_0[2] = { 's', 'a' };
+static const symbol s_21_1[2] = { 's', 'e' };
+static const symbol s_21_2[3] = { 's', 'a', 'k' };
+static const symbol s_21_3[3] = { 's', 'e', 'k' };
+static const symbol s_21_4[3] = { 's', 'a', 'm' };
+static const symbol s_21_5[3] = { 's', 'e', 'm' };
+static const symbol s_21_6[3] = { 's', 'a', 'n' };
+static const symbol s_21_7[3] = { 's', 'e', 'n' };
+
+static const struct among a_21[8] =
+{
+/* 0 */ { 2, s_21_0, -1, -1, 0},
+/* 1 */ { 2, s_21_1, -1, -1, 0},
+/* 2 */ { 3, s_21_2, -1, -1, 0},
+/* 3 */ { 3, s_21_3, -1, -1, 0},
+/* 4 */ { 3, s_21_4, -1, -1, 0},
+/* 5 */ { 3, s_21_5, -1, -1, 0},
+/* 6 */ { 3, s_21_6, -1, -1, 0},
+/* 7 */ { 3, s_21_7, -1, -1, 0}
+};
+
+static const symbol s_22_0[4] = { 'm', 'i', 0xC5, 0x9F };
+static const symbol s_22_1[4] = { 'm', 'u', 0xC5, 0x9F };
+static const symbol s_22_2[5] = { 'm', 0xC4, 0xB1, 0xC5, 0x9F };
+static const symbol s_22_3[5] = { 'm', 0xC3, 0xBC, 0xC5, 0x9F };
+
+static const struct among a_22[4] =
+{
+/* 0 */ { 4, s_22_0, -1, -1, 0},
+/* 1 */ { 4, s_22_1, -1, -1, 0},
+/* 2 */ { 5, s_22_2, -1, -1, 0},
+/* 3 */ { 5, s_22_3, -1, -1, 0}
+};
+
+static const symbol s_23_0[1] = { 'b' };
+static const symbol s_23_1[1] = { 'c' };
+static const symbol s_23_2[1] = { 'd' };
+static const symbol s_23_3[2] = { 0xC4, 0x9F };
+
+static const struct among a_23[4] =
+{
+/* 0 */ { 1, s_23_0, -1, 1, 0},
+/* 1 */ { 1, s_23_1, -1, 2, 0},
+/* 2 */ { 1, s_23_2, -1, 3, 0},
+/* 3 */ { 2, s_23_3, -1, 4, 0}
+};
+
+static const unsigned char g_vowel[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 0, 0, 0, 1 };
+
+static const unsigned char g_U[] = { 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1 };
+
+static const unsigned char g_vowel1[] = { 1, 64, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+static const unsigned char g_vowel2[] = { 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130 };
+
+static const unsigned char g_vowel3[] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+static const unsigned char g_vowel4[] = { 17 };
+
+static const unsigned char g_vowel5[] = { 65 };
+
+static const unsigned char g_vowel6[] = { 65 };
+
+static const symbol s_0[] = { 'a' };
+static const symbol s_1[] = { 'e' };
+static const symbol s_2[] = { 0xC4, 0xB1 };
+static const symbol s_3[] = { 'i' };
+static const symbol s_4[] = { 'o' };
+static const symbol s_5[] = { 0xC3, 0xB6 };
+static const symbol s_6[] = { 'u' };
+static const symbol s_7[] = { 0xC3, 0xBC };
+static const symbol s_8[] = { 'n' };
+static const symbol s_9[] = { 'n' };
+static const symbol s_10[] = { 's' };
+static const symbol s_11[] = { 's' };
+static const symbol s_12[] = { 'y' };
+static const symbol s_13[] = { 'y' };
+static const symbol s_14[] = { 'k', 'i' };
+static const symbol s_15[] = { 'k', 'e', 'n' };
+static const symbol s_16[] = { 'p' };
+static const symbol s_17[] = { 0xC3, 0xA7 };
+static const symbol s_18[] = { 't' };
+static const symbol s_19[] = { 'k' };
+static const symbol s_20[] = { 'd' };
+static const symbol s_21[] = { 'g' };
+static const symbol s_22[] = { 'a' };
+static const symbol s_23[] = { 0xC4, 0xB1 };
+static const symbol s_24[] = { 0xC4, 0xB1 };
+static const symbol s_25[] = { 'e' };
+static const symbol s_26[] = { 'i' };
+static const symbol s_27[] = { 'i' };
+static const symbol s_28[] = { 'o' };
+static const symbol s_29[] = { 'u' };
+static const symbol s_30[] = { 'u' };
+static const symbol s_31[] = { 0xC3, 0xB6 };
+static const symbol s_32[] = { 0xC3, 0xBC };
+static const symbol s_33[] = { 0xC3, 0xBC };
+static const symbol s_34[] = { 'a', 'd' };
+static const symbol s_35[] = { 's', 'o', 'y', 'a', 'd' };
+
+static int r_check_vowel_harmony(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 112 */
+ if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; /* goto */ /* grouping vowel, line 114 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 116 */
+ if (!(eq_s_b(z, 1, s_0))) goto lab1;
+ if (out_grouping_b_U(z, g_vowel1, 97, 305, 1) < 0) goto lab1; /* goto */ /* grouping vowel1, line 116 */
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_1))) goto lab2;
+ if (out_grouping_b_U(z, g_vowel2, 101, 252, 1) < 0) goto lab2; /* goto */ /* grouping vowel2, line 117 */
+ goto lab0;
+ lab2:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 2, s_2))) goto lab3;
+ if (out_grouping_b_U(z, g_vowel3, 97, 305, 1) < 0) goto lab3; /* goto */ /* grouping vowel3, line 118 */
+ goto lab0;
+ lab3:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_3))) goto lab4;
+ if (out_grouping_b_U(z, g_vowel4, 101, 105, 1) < 0) goto lab4; /* goto */ /* grouping vowel4, line 119 */
+ goto lab0;
+ lab4:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_4))) goto lab5;
+ if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab5; /* goto */ /* grouping vowel5, line 120 */
+ goto lab0;
+ lab5:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 2, s_5))) goto lab6;
+ if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) goto lab6; /* goto */ /* grouping vowel6, line 121 */
+ goto lab0;
+ lab6:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_6))) goto lab7;
+ if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab7; /* goto */ /* grouping vowel5, line 122 */
+ goto lab0;
+ lab7:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 2, s_7))) return 0;
+ if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) return 0; /* goto */ /* grouping vowel6, line 123 */
+ }
+ lab0:
+ z->c = z->l - m_test;
+ }
+ return 1;
+}
+
+static int r_mark_suffix_with_optional_n_consonant(struct SN_env * z) {
+ { int m1 = z->l - z->c; (void)m1; /* or, line 134 */
+ { int m_test = z->l - z->c; /* test, line 133 */
+ if (!(eq_s_b(z, 1, s_8))) goto lab1;
+ z->c = z->l - m_test;
+ }
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) goto lab1;
+ z->c = ret; /* next, line 133 */
+ }
+ { int m_test = z->l - z->c; /* test, line 133 */
+ if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1;
+ z->c = z->l - m_test;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* not, line 135 */
+ { int m_test = z->l - z->c; /* test, line 135 */
+ if (!(eq_s_b(z, 1, s_9))) goto lab2;
+ z->c = z->l - m_test;
+ }
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ { int m_test = z->l - z->c; /* test, line 135 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 135 */
+ }
+ { int m_test = z->l - z->c; /* test, line 135 */
+ if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0;
+ z->c = z->l - m_test;
+ }
+ z->c = z->l - m_test;
+ }
+ }
+lab0:
+ return 1;
+}
+
+static int r_mark_suffix_with_optional_s_consonant(struct SN_env * z) {
+ { int m1 = z->l - z->c; (void)m1; /* or, line 145 */
+ { int m_test = z->l - z->c; /* test, line 144 */
+ if (!(eq_s_b(z, 1, s_10))) goto lab1;
+ z->c = z->l - m_test;
+ }
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) goto lab1;
+ z->c = ret; /* next, line 144 */
+ }
+ { int m_test = z->l - z->c; /* test, line 144 */
+ if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1;
+ z->c = z->l - m_test;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* not, line 146 */
+ { int m_test = z->l - z->c; /* test, line 146 */
+ if (!(eq_s_b(z, 1, s_11))) goto lab2;
+ z->c = z->l - m_test;
+ }
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ { int m_test = z->l - z->c; /* test, line 146 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 146 */
+ }
+ { int m_test = z->l - z->c; /* test, line 146 */
+ if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0;
+ z->c = z->l - m_test;
+ }
+ z->c = z->l - m_test;
+ }
+ }
+lab0:
+ return 1;
+}
+
+static int r_mark_suffix_with_optional_y_consonant(struct SN_env * z) {
+ { int m1 = z->l - z->c; (void)m1; /* or, line 155 */
+ { int m_test = z->l - z->c; /* test, line 154 */
+ if (!(eq_s_b(z, 1, s_12))) goto lab1;
+ z->c = z->l - m_test;
+ }
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) goto lab1;
+ z->c = ret; /* next, line 154 */
+ }
+ { int m_test = z->l - z->c; /* test, line 154 */
+ if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1;
+ z->c = z->l - m_test;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* not, line 156 */
+ { int m_test = z->l - z->c; /* test, line 156 */
+ if (!(eq_s_b(z, 1, s_13))) goto lab2;
+ z->c = z->l - m_test;
+ }
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ { int m_test = z->l - z->c; /* test, line 156 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 156 */
+ }
+ { int m_test = z->l - z->c; /* test, line 156 */
+ if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0;
+ z->c = z->l - m_test;
+ }
+ z->c = z->l - m_test;
+ }
+ }
+lab0:
+ return 1;
+}
+
+static int r_mark_suffix_with_optional_U_vowel(struct SN_env * z) {
+ { int m1 = z->l - z->c; (void)m1; /* or, line 161 */
+ { int m_test = z->l - z->c; /* test, line 160 */
+ if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab1;
+ z->c = z->l - m_test;
+ }
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) goto lab1;
+ z->c = ret; /* next, line 160 */
+ }
+ { int m_test = z->l - z->c; /* test, line 160 */
+ if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1;
+ z->c = z->l - m_test;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int m2 = z->l - z->c; (void)m2; /* not, line 162 */
+ { int m_test = z->l - z->c; /* test, line 162 */
+ if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab2;
+ z->c = z->l - m_test;
+ }
+ return 0;
+ lab2:
+ z->c = z->l - m2;
+ }
+ { int m_test = z->l - z->c; /* test, line 162 */
+ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1);
+ if (ret < 0) return 0;
+ z->c = ret; /* next, line 162 */
+ }
+ { int m_test = z->l - z->c; /* test, line 162 */
+ if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0;
+ z->c = z->l - m_test;
+ }
+ z->c = z->l - m_test;
+ }
+ }
+lab0:
+ return 1;
+}
+
+static int r_mark_possessives(struct SN_env * z) {
+ if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((67133440 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_0, 10))) return 0; /* among, line 167 */
+ { int ret = r_mark_suffix_with_optional_U_vowel(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_U_vowel, line 169 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_sU(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 173 */
+ if (ret < 0) return ret;
+ }
+ if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0;
+ { int ret = r_mark_suffix_with_optional_s_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_s_consonant, line 175 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_lArI(struct SN_env * z) {
+ if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 177)) return 0;
+ if (!(find_among_b(z, a_1, 2))) return 0; /* among, line 179 */
+ return 1;
+}
+
+static int r_mark_yU(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 183 */
+ if (ret < 0) return ret;
+ }
+ if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0;
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 185 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_nU(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 189 */
+ if (ret < 0) return ret;
+ }
+ if (!(find_among_b(z, a_2, 4))) return 0; /* among, line 190 */
+ return 1;
+}
+
+static int r_mark_nUn(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 194 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 110) return 0;
+ if (!(find_among_b(z, a_3, 4))) return 0; /* among, line 195 */
+ { int ret = r_mark_suffix_with_optional_n_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_n_consonant, line 196 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_yA(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 200 */
+ if (ret < 0) return ret;
+ }
+ if (z->c <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0;
+ if (!(find_among_b(z, a_4, 2))) return 0; /* among, line 201 */
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 202 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_nA(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 206 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0;
+ if (!(find_among_b(z, a_5, 2))) return 0; /* among, line 207 */
+ return 1;
+}
+
+static int r_mark_DA(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 211 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0;
+ if (!(find_among_b(z, a_6, 4))) return 0; /* among, line 212 */
+ return 1;
+}
+
+static int r_mark_ndA(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 216 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0;
+ if (!(find_among_b(z, a_7, 2))) return 0; /* among, line 217 */
+ return 1;
+}
+
+static int r_mark_DAn(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 221 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0;
+ if (!(find_among_b(z, a_8, 4))) return 0; /* among, line 222 */
+ return 1;
+}
+
+static int r_mark_ndAn(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 226 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 3 <= z->lb || z->p[z->c - 1] != 110) return 0;
+ if (!(find_among_b(z, a_9, 2))) return 0; /* among, line 227 */
+ return 1;
+}
+
+static int r_mark_ylA(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 231 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0;
+ if (!(find_among_b(z, a_10, 2))) return 0; /* among, line 232 */
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 233 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_ki(struct SN_env * z) {
+ if (!(eq_s_b(z, 2, s_14))) return 0;
+ return 1;
+}
+
+static int r_mark_ncA(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 241 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0;
+ if (!(find_among_b(z, a_11, 2))) return 0; /* among, line 242 */
+ { int ret = r_mark_suffix_with_optional_n_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_n_consonant, line 243 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_yUm(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 247 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 109) return 0;
+ if (!(find_among_b(z, a_12, 4))) return 0; /* among, line 248 */
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 249 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_sUn(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 253 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0;
+ if (!(find_among_b(z, a_13, 4))) return 0; /* among, line 254 */
+ return 1;
+}
+
+static int r_mark_yUz(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 258 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] != 122) return 0;
+ if (!(find_among_b(z, a_14, 4))) return 0; /* among, line 259 */
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 260 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_sUnUz(struct SN_env * z) {
+ if (z->c - 4 <= z->lb || z->p[z->c - 1] != 122) return 0;
+ if (!(find_among_b(z, a_15, 4))) return 0; /* among, line 264 */
+ return 1;
+}
+
+static int r_mark_lAr(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 268 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0;
+ if (!(find_among_b(z, a_16, 2))) return 0; /* among, line 269 */
+ return 1;
+}
+
+static int r_mark_nUz(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 273 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 122) return 0;
+ if (!(find_among_b(z, a_17, 4))) return 0; /* among, line 274 */
+ return 1;
+}
+
+static int r_mark_DUr(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 278 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0;
+ if (!(find_among_b(z, a_18, 8))) return 0; /* among, line 279 */
+ return 1;
+}
+
+static int r_mark_cAsInA(struct SN_env * z) {
+ if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0;
+ if (!(find_among_b(z, a_19, 2))) return 0; /* among, line 283 */
+ return 1;
+}
+
+static int r_mark_yDU(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 287 */
+ if (ret < 0) return ret;
+ }
+ if (!(find_among_b(z, a_20, 32))) return 0; /* among, line 288 */
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 292 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_ysA(struct SN_env * z) {
+ if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((26658 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0;
+ if (!(find_among_b(z, a_21, 8))) return 0; /* among, line 297 */
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 298 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_ymUs_(struct SN_env * z) {
+ { int ret = r_check_vowel_harmony(z);
+ if (ret == 0) return 0; /* call check_vowel_harmony, line 302 */
+ if (ret < 0) return ret;
+ }
+ if (z->c - 3 <= z->lb || z->p[z->c - 1] != 159) return 0;
+ if (!(find_among_b(z, a_22, 4))) return 0; /* among, line 303 */
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 304 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_mark_yken(struct SN_env * z) {
+ if (!(eq_s_b(z, 3, s_15))) return 0;
+ { int ret = r_mark_suffix_with_optional_y_consonant(z);
+ if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 308 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_stem_nominal_verb_suffixes(struct SN_env * z) {
+ z->ket = z->c; /* [, line 312 */
+ z->B[0] = 1; /* set continue_stemming_noun_suffixes, line 313 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 315 */
+ { int m2 = z->l - z->c; (void)m2; /* or, line 314 */
+ { int ret = r_mark_ymUs_(z);
+ if (ret == 0) goto lab3; /* call mark_ymUs_, line 314 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab3:
+ z->c = z->l - m2;
+ { int ret = r_mark_yDU(z);
+ if (ret == 0) goto lab4; /* call mark_yDU, line 314 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab4:
+ z->c = z->l - m2;
+ { int ret = r_mark_ysA(z);
+ if (ret == 0) goto lab5; /* call mark_ysA, line 314 */
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab5:
+ z->c = z->l - m2;
+ { int ret = r_mark_yken(z);
+ if (ret == 0) goto lab1; /* call mark_yken, line 314 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab2:
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int ret = r_mark_cAsInA(z);
+ if (ret == 0) goto lab6; /* call mark_cAsInA, line 316 */
+ if (ret < 0) return ret;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* or, line 316 */
+ { int ret = r_mark_sUnUz(z);
+ if (ret == 0) goto lab8; /* call mark_sUnUz, line 316 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab8:
+ z->c = z->l - m3;
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) goto lab9; /* call mark_lAr, line 316 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab9:
+ z->c = z->l - m3;
+ { int ret = r_mark_yUm(z);
+ if (ret == 0) goto lab10; /* call mark_yUm, line 316 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab10:
+ z->c = z->l - m3;
+ { int ret = r_mark_sUn(z);
+ if (ret == 0) goto lab11; /* call mark_sUn, line 316 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab11:
+ z->c = z->l - m3;
+ { int ret = r_mark_yUz(z);
+ if (ret == 0) goto lab12; /* call mark_yUz, line 316 */
+ if (ret < 0) return ret;
+ }
+ goto lab7;
+ lab12:
+ z->c = z->l - m3;
+ }
+ lab7:
+ { int ret = r_mark_ymUs_(z);
+ if (ret == 0) goto lab6; /* call mark_ymUs_, line 316 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab6:
+ z->c = z->l - m1;
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) goto lab13; /* call mark_lAr, line 319 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 319 */
+ { int ret = slice_del(z); /* delete, line 319 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 319 */
+ z->ket = z->c; /* [, line 319 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 319 */
+ { int ret = r_mark_DUr(z);
+ if (ret == 0) goto lab16; /* call mark_DUr, line 319 */
+ if (ret < 0) return ret;
+ }
+ goto lab15;
+ lab16:
+ z->c = z->l - m4;
+ { int ret = r_mark_yDU(z);
+ if (ret == 0) goto lab17; /* call mark_yDU, line 319 */
+ if (ret < 0) return ret;
+ }
+ goto lab15;
+ lab17:
+ z->c = z->l - m4;
+ { int ret = r_mark_ysA(z);
+ if (ret == 0) goto lab18; /* call mark_ysA, line 319 */
+ if (ret < 0) return ret;
+ }
+ goto lab15;
+ lab18:
+ z->c = z->l - m4;
+ { int ret = r_mark_ymUs_(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab14; } /* call mark_ymUs_, line 319 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab15:
+ lab14:
+ ;
+ }
+ z->B[0] = 0; /* unset continue_stemming_noun_suffixes, line 320 */
+ goto lab0;
+ lab13:
+ z->c = z->l - m1;
+ { int ret = r_mark_nUz(z);
+ if (ret == 0) goto lab19; /* call mark_nUz, line 323 */
+ if (ret < 0) return ret;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* or, line 323 */
+ { int ret = r_mark_yDU(z);
+ if (ret == 0) goto lab21; /* call mark_yDU, line 323 */
+ if (ret < 0) return ret;
+ }
+ goto lab20;
+ lab21:
+ z->c = z->l - m5;
+ { int ret = r_mark_ysA(z);
+ if (ret == 0) goto lab19; /* call mark_ysA, line 323 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab20:
+ goto lab0;
+ lab19:
+ z->c = z->l - m1;
+ { int m6 = z->l - z->c; (void)m6; /* or, line 325 */
+ { int ret = r_mark_sUnUz(z);
+ if (ret == 0) goto lab24; /* call mark_sUnUz, line 325 */
+ if (ret < 0) return ret;
+ }
+ goto lab23;
+ lab24:
+ z->c = z->l - m6;
+ { int ret = r_mark_yUz(z);
+ if (ret == 0) goto lab25; /* call mark_yUz, line 325 */
+ if (ret < 0) return ret;
+ }
+ goto lab23;
+ lab25:
+ z->c = z->l - m6;
+ { int ret = r_mark_sUn(z);
+ if (ret == 0) goto lab26; /* call mark_sUn, line 325 */
+ if (ret < 0) return ret;
+ }
+ goto lab23;
+ lab26:
+ z->c = z->l - m6;
+ { int ret = r_mark_yUm(z);
+ if (ret == 0) goto lab22; /* call mark_yUm, line 325 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab23:
+ z->bra = z->c; /* ], line 325 */
+ { int ret = slice_del(z); /* delete, line 325 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 325 */
+ z->ket = z->c; /* [, line 325 */
+ { int ret = r_mark_ymUs_(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab27; } /* call mark_ymUs_, line 325 */
+ if (ret < 0) return ret;
+ }
+ lab27:
+ ;
+ }
+ goto lab0;
+ lab22:
+ z->c = z->l - m1;
+ { int ret = r_mark_DUr(z);
+ if (ret == 0) return 0; /* call mark_DUr, line 327 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 327 */
+ { int ret = slice_del(z); /* delete, line 327 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 327 */
+ z->ket = z->c; /* [, line 327 */
+ { int m7 = z->l - z->c; (void)m7; /* or, line 327 */
+ { int ret = r_mark_sUnUz(z);
+ if (ret == 0) goto lab30; /* call mark_sUnUz, line 327 */
+ if (ret < 0) return ret;
+ }
+ goto lab29;
+ lab30:
+ z->c = z->l - m7;
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) goto lab31; /* call mark_lAr, line 327 */
+ if (ret < 0) return ret;
+ }
+ goto lab29;
+ lab31:
+ z->c = z->l - m7;
+ { int ret = r_mark_yUm(z);
+ if (ret == 0) goto lab32; /* call mark_yUm, line 327 */
+ if (ret < 0) return ret;
+ }
+ goto lab29;
+ lab32:
+ z->c = z->l - m7;
+ { int ret = r_mark_sUn(z);
+ if (ret == 0) goto lab33; /* call mark_sUn, line 327 */
+ if (ret < 0) return ret;
+ }
+ goto lab29;
+ lab33:
+ z->c = z->l - m7;
+ { int ret = r_mark_yUz(z);
+ if (ret == 0) goto lab34; /* call mark_yUz, line 327 */
+ if (ret < 0) return ret;
+ }
+ goto lab29;
+ lab34:
+ z->c = z->l - m7;
+ }
+ lab29:
+ { int ret = r_mark_ymUs_(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab28; } /* call mark_ymUs_, line 327 */
+ if (ret < 0) return ret;
+ }
+ lab28:
+ ;
+ }
+ }
+lab0:
+ z->bra = z->c; /* ], line 328 */
+ { int ret = slice_del(z); /* delete, line 328 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+static int r_stem_suffix_chain_before_ki(struct SN_env * z) {
+ z->ket = z->c; /* [, line 333 */
+ { int ret = r_mark_ki(z);
+ if (ret == 0) return 0; /* call mark_ki, line 334 */
+ if (ret < 0) return ret;
+ }
+ { int m1 = z->l - z->c; (void)m1; /* or, line 342 */
+ { int ret = r_mark_DA(z);
+ if (ret == 0) goto lab1; /* call mark_DA, line 336 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 336 */
+ { int ret = slice_del(z); /* delete, line 336 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 336 */
+ z->ket = z->c; /* [, line 336 */
+ { int m2 = z->l - z->c; (void)m2; /* or, line 338 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) goto lab4; /* call mark_lAr, line 337 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 337 */
+ { int ret = slice_del(z); /* delete, line 337 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 337 */
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab5; } /* call stem_suffix_chain_before_ki, line 337 */
+ if (ret < 0) return ret;
+ }
+ lab5:
+ ;
+ }
+ goto lab3;
+ lab4:
+ z->c = z->l - m2;
+ { int ret = r_mark_possessives(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call mark_possessives, line 339 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 339 */
+ { int ret = slice_del(z); /* delete, line 339 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 339 */
+ z->ket = z->c; /* [, line 339 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call mark_lAr, line 339 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 339 */
+ { int ret = slice_del(z); /* delete, line 339 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call stem_suffix_chain_before_ki, line 339 */
+ if (ret < 0) return ret;
+ }
+ lab6:
+ ;
+ }
+ }
+ lab3:
+ lab2:
+ ;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ { int ret = r_mark_nUn(z);
+ if (ret == 0) goto lab7; /* call mark_nUn, line 343 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 343 */
+ { int ret = slice_del(z); /* delete, line 343 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 343 */
+ z->ket = z->c; /* [, line 343 */
+ { int m3 = z->l - z->c; (void)m3; /* or, line 345 */
+ { int ret = r_mark_lArI(z);
+ if (ret == 0) goto lab10; /* call mark_lArI, line 344 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 344 */
+ { int ret = slice_del(z); /* delete, line 344 */
+ if (ret < 0) return ret;
+ }
+ goto lab9;
+ lab10:
+ z->c = z->l - m3;
+ z->ket = z->c; /* [, line 346 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 346 */
+ { int ret = r_mark_possessives(z);
+ if (ret == 0) goto lab13; /* call mark_possessives, line 346 */
+ if (ret < 0) return ret;
+ }
+ goto lab12;
+ lab13:
+ z->c = z->l - m4;
+ { int ret = r_mark_sU(z);
+ if (ret == 0) goto lab11; /* call mark_sU, line 346 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab12:
+ z->bra = z->c; /* ], line 346 */
+ { int ret = slice_del(z); /* delete, line 346 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 346 */
+ z->ket = z->c; /* [, line 346 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab14; } /* call mark_lAr, line 346 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 346 */
+ { int ret = slice_del(z); /* delete, line 346 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab14; } /* call stem_suffix_chain_before_ki, line 346 */
+ if (ret < 0) return ret;
+ }
+ lab14:
+ ;
+ }
+ goto lab9;
+ lab11:
+ z->c = z->l - m3;
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab8; } /* call stem_suffix_chain_before_ki, line 348 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab9:
+ lab8:
+ ;
+ }
+ goto lab0;
+ lab7:
+ z->c = z->l - m1;
+ { int ret = r_mark_ndA(z);
+ if (ret == 0) return 0; /* call mark_ndA, line 351 */
+ if (ret < 0) return ret;
+ }
+ { int m5 = z->l - z->c; (void)m5; /* or, line 353 */
+ { int ret = r_mark_lArI(z);
+ if (ret == 0) goto lab16; /* call mark_lArI, line 352 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 352 */
+ { int ret = slice_del(z); /* delete, line 352 */
+ if (ret < 0) return ret;
+ }
+ goto lab15;
+ lab16:
+ z->c = z->l - m5;
+ { int ret = r_mark_sU(z);
+ if (ret == 0) goto lab17; /* call mark_sU, line 354 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 354 */
+ { int ret = slice_del(z); /* delete, line 354 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 354 */
+ z->ket = z->c; /* [, line 354 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab18; } /* call mark_lAr, line 354 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 354 */
+ { int ret = slice_del(z); /* delete, line 354 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab18; } /* call stem_suffix_chain_before_ki, line 354 */
+ if (ret < 0) return ret;
+ }
+ lab18:
+ ;
+ }
+ goto lab15;
+ lab17:
+ z->c = z->l - m5;
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) return 0; /* call stem_suffix_chain_before_ki, line 356 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab15:
+ ;
+ }
+lab0:
+ return 1;
+}
+
+static int r_stem_noun_suffixes(struct SN_env * z) {
+ { int m1 = z->l - z->c; (void)m1; /* or, line 363 */
+ z->ket = z->c; /* [, line 362 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) goto lab1; /* call mark_lAr, line 362 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 362 */
+ { int ret = slice_del(z); /* delete, line 362 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 362 */
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call stem_suffix_chain_before_ki, line 362 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ ;
+ }
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 364 */
+ { int ret = r_mark_ncA(z);
+ if (ret == 0) goto lab3; /* call mark_ncA, line 364 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 364 */
+ { int ret = slice_del(z); /* delete, line 364 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 365 */
+ { int m2 = z->l - z->c; (void)m2; /* or, line 367 */
+ z->ket = z->c; /* [, line 366 */
+ { int ret = r_mark_lArI(z);
+ if (ret == 0) goto lab6; /* call mark_lArI, line 366 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 366 */
+ { int ret = slice_del(z); /* delete, line 366 */
+ if (ret < 0) return ret;
+ }
+ goto lab5;
+ lab6:
+ z->c = z->l - m2;
+ z->ket = z->c; /* [, line 368 */
+ { int m3 = z->l - z->c; (void)m3; /* or, line 368 */
+ { int ret = r_mark_possessives(z);
+ if (ret == 0) goto lab9; /* call mark_possessives, line 368 */
+ if (ret < 0) return ret;
+ }
+ goto lab8;
+ lab9:
+ z->c = z->l - m3;
+ { int ret = r_mark_sU(z);
+ if (ret == 0) goto lab7; /* call mark_sU, line 368 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab8:
+ z->bra = z->c; /* ], line 368 */
+ { int ret = slice_del(z); /* delete, line 368 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 368 */
+ z->ket = z->c; /* [, line 368 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab10; } /* call mark_lAr, line 368 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 368 */
+ { int ret = slice_del(z); /* delete, line 368 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab10; } /* call stem_suffix_chain_before_ki, line 368 */
+ if (ret < 0) return ret;
+ }
+ lab10:
+ ;
+ }
+ goto lab5;
+ lab7:
+ z->c = z->l - m2;
+ z->ket = z->c; /* [, line 370 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call mark_lAr, line 370 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 370 */
+ { int ret = slice_del(z); /* delete, line 370 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call stem_suffix_chain_before_ki, line 370 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab5:
+ lab4:
+ ;
+ }
+ goto lab0;
+ lab3:
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 374 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 374 */
+ { int ret = r_mark_ndA(z);
+ if (ret == 0) goto lab13; /* call mark_ndA, line 374 */
+ if (ret < 0) return ret;
+ }
+ goto lab12;
+ lab13:
+ z->c = z->l - m4;
+ { int ret = r_mark_nA(z);
+ if (ret == 0) goto lab11; /* call mark_nA, line 374 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab12:
+ { int m5 = z->l - z->c; (void)m5; /* or, line 377 */
+ { int ret = r_mark_lArI(z);
+ if (ret == 0) goto lab15; /* call mark_lArI, line 376 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 376 */
+ { int ret = slice_del(z); /* delete, line 376 */
+ if (ret < 0) return ret;
+ }
+ goto lab14;
+ lab15:
+ z->c = z->l - m5;
+ { int ret = r_mark_sU(z);
+ if (ret == 0) goto lab16; /* call mark_sU, line 378 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 378 */
+ { int ret = slice_del(z); /* delete, line 378 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 378 */
+ z->ket = z->c; /* [, line 378 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab17; } /* call mark_lAr, line 378 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 378 */
+ { int ret = slice_del(z); /* delete, line 378 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab17; } /* call stem_suffix_chain_before_ki, line 378 */
+ if (ret < 0) return ret;
+ }
+ lab17:
+ ;
+ }
+ goto lab14;
+ lab16:
+ z->c = z->l - m5;
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) goto lab11; /* call stem_suffix_chain_before_ki, line 380 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab14:
+ goto lab0;
+ lab11:
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 384 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 384 */
+ { int ret = r_mark_ndAn(z);
+ if (ret == 0) goto lab20; /* call mark_ndAn, line 384 */
+ if (ret < 0) return ret;
+ }
+ goto lab19;
+ lab20:
+ z->c = z->l - m6;
+ { int ret = r_mark_nU(z);
+ if (ret == 0) goto lab18; /* call mark_nU, line 384 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab19:
+ { int m7 = z->l - z->c; (void)m7; /* or, line 384 */
+ { int ret = r_mark_sU(z);
+ if (ret == 0) goto lab22; /* call mark_sU, line 384 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 384 */
+ { int ret = slice_del(z); /* delete, line 384 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 384 */
+ z->ket = z->c; /* [, line 384 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab23; } /* call mark_lAr, line 384 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 384 */
+ { int ret = slice_del(z); /* delete, line 384 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab23; } /* call stem_suffix_chain_before_ki, line 384 */
+ if (ret < 0) return ret;
+ }
+ lab23:
+ ;
+ }
+ goto lab21;
+ lab22:
+ z->c = z->l - m7;
+ { int ret = r_mark_lArI(z);
+ if (ret == 0) goto lab18; /* call mark_lArI, line 384 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab21:
+ goto lab0;
+ lab18:
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 386 */
+ { int ret = r_mark_DAn(z);
+ if (ret == 0) goto lab24; /* call mark_DAn, line 386 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 386 */
+ { int ret = slice_del(z); /* delete, line 386 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 386 */
+ z->ket = z->c; /* [, line 386 */
+ { int m8 = z->l - z->c; (void)m8; /* or, line 389 */
+ { int ret = r_mark_possessives(z);
+ if (ret == 0) goto lab27; /* call mark_possessives, line 388 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 388 */
+ { int ret = slice_del(z); /* delete, line 388 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 388 */
+ z->ket = z->c; /* [, line 388 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab28; } /* call mark_lAr, line 388 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 388 */
+ { int ret = slice_del(z); /* delete, line 388 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab28; } /* call stem_suffix_chain_before_ki, line 388 */
+ if (ret < 0) return ret;
+ }
+ lab28:
+ ;
+ }
+ goto lab26;
+ lab27:
+ z->c = z->l - m8;
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) goto lab29; /* call mark_lAr, line 390 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 390 */
+ { int ret = slice_del(z); /* delete, line 390 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 390 */
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab30; } /* call stem_suffix_chain_before_ki, line 390 */
+ if (ret < 0) return ret;
+ }
+ lab30:
+ ;
+ }
+ goto lab26;
+ lab29:
+ z->c = z->l - m8;
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab25; } /* call stem_suffix_chain_before_ki, line 392 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab26:
+ lab25:
+ ;
+ }
+ goto lab0;
+ lab24:
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 396 */
+ { int m9 = z->l - z->c; (void)m9; /* or, line 396 */
+ { int ret = r_mark_nUn(z);
+ if (ret == 0) goto lab33; /* call mark_nUn, line 396 */
+ if (ret < 0) return ret;
+ }
+ goto lab32;
+ lab33:
+ z->c = z->l - m9;
+ { int ret = r_mark_ylA(z);
+ if (ret == 0) goto lab31; /* call mark_ylA, line 396 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab32:
+ z->bra = z->c; /* ], line 396 */
+ { int ret = slice_del(z); /* delete, line 396 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 397 */
+ { int m10 = z->l - z->c; (void)m10; /* or, line 399 */
+ z->ket = z->c; /* [, line 398 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) goto lab36; /* call mark_lAr, line 398 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 398 */
+ { int ret = slice_del(z); /* delete, line 398 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) goto lab36; /* call stem_suffix_chain_before_ki, line 398 */
+ if (ret < 0) return ret;
+ }
+ goto lab35;
+ lab36:
+ z->c = z->l - m10;
+ z->ket = z->c; /* [, line 400 */
+ { int m11 = z->l - z->c; (void)m11; /* or, line 400 */
+ { int ret = r_mark_possessives(z);
+ if (ret == 0) goto lab39; /* call mark_possessives, line 400 */
+ if (ret < 0) return ret;
+ }
+ goto lab38;
+ lab39:
+ z->c = z->l - m11;
+ { int ret = r_mark_sU(z);
+ if (ret == 0) goto lab37; /* call mark_sU, line 400 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab38:
+ z->bra = z->c; /* ], line 400 */
+ { int ret = slice_del(z); /* delete, line 400 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 400 */
+ z->ket = z->c; /* [, line 400 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab40; } /* call mark_lAr, line 400 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 400 */
+ { int ret = slice_del(z); /* delete, line 400 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab40; } /* call stem_suffix_chain_before_ki, line 400 */
+ if (ret < 0) return ret;
+ }
+ lab40:
+ ;
+ }
+ goto lab35;
+ lab37:
+ z->c = z->l - m10;
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab34; } /* call stem_suffix_chain_before_ki, line 402 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab35:
+ lab34:
+ ;
+ }
+ goto lab0;
+ lab31:
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 406 */
+ { int ret = r_mark_lArI(z);
+ if (ret == 0) goto lab41; /* call mark_lArI, line 406 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 406 */
+ { int ret = slice_del(z); /* delete, line 406 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab41:
+ z->c = z->l - m1;
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) goto lab42; /* call stem_suffix_chain_before_ki, line 408 */
+ if (ret < 0) return ret;
+ }
+ goto lab0;
+ lab42:
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 410 */
+ { int m12 = z->l - z->c; (void)m12; /* or, line 410 */
+ { int ret = r_mark_DA(z);
+ if (ret == 0) goto lab45; /* call mark_DA, line 410 */
+ if (ret < 0) return ret;
+ }
+ goto lab44;
+ lab45:
+ z->c = z->l - m12;
+ { int ret = r_mark_yU(z);
+ if (ret == 0) goto lab46; /* call mark_yU, line 410 */
+ if (ret < 0) return ret;
+ }
+ goto lab44;
+ lab46:
+ z->c = z->l - m12;
+ { int ret = r_mark_yA(z);
+ if (ret == 0) goto lab43; /* call mark_yA, line 410 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab44:
+ z->bra = z->c; /* ], line 410 */
+ { int ret = slice_del(z); /* delete, line 410 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 410 */
+ z->ket = z->c; /* [, line 410 */
+ { int m13 = z->l - z->c; (void)m13; /* or, line 410 */
+ { int ret = r_mark_possessives(z);
+ if (ret == 0) goto lab49; /* call mark_possessives, line 410 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 410 */
+ { int ret = slice_del(z); /* delete, line 410 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 410 */
+ z->ket = z->c; /* [, line 410 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab50; } /* call mark_lAr, line 410 */
+ if (ret < 0) return ret;
+ }
+ lab50:
+ ;
+ }
+ goto lab48;
+ lab49:
+ z->c = z->l - m13;
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab47; } /* call mark_lAr, line 410 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab48:
+ z->bra = z->c; /* ], line 410 */
+ { int ret = slice_del(z); /* delete, line 410 */
+ if (ret < 0) return ret;
+ }
+ z->ket = z->c; /* [, line 410 */
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab47; } /* call stem_suffix_chain_before_ki, line 410 */
+ if (ret < 0) return ret;
+ }
+ lab47:
+ ;
+ }
+ goto lab0;
+ lab43:
+ z->c = z->l - m1;
+ z->ket = z->c; /* [, line 412 */
+ { int m14 = z->l - z->c; (void)m14; /* or, line 412 */
+ { int ret = r_mark_possessives(z);
+ if (ret == 0) goto lab52; /* call mark_possessives, line 412 */
+ if (ret < 0) return ret;
+ }
+ goto lab51;
+ lab52:
+ z->c = z->l - m14;
+ { int ret = r_mark_sU(z);
+ if (ret == 0) return 0; /* call mark_sU, line 412 */
+ if (ret < 0) return ret;
+ }
+ }
+ lab51:
+ z->bra = z->c; /* ], line 412 */
+ { int ret = slice_del(z); /* delete, line 412 */
+ if (ret < 0) return ret;
+ }
+ { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 412 */
+ z->ket = z->c; /* [, line 412 */
+ { int ret = r_mark_lAr(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab53; } /* call mark_lAr, line 412 */
+ if (ret < 0) return ret;
+ }
+ z->bra = z->c; /* ], line 412 */
+ { int ret = slice_del(z); /* delete, line 412 */
+ if (ret < 0) return ret;
+ }
+ { int ret = r_stem_suffix_chain_before_ki(z);
+ if (ret == 0) { z->c = z->l - m_keep; goto lab53; } /* call stem_suffix_chain_before_ki, line 412 */
+ if (ret < 0) return ret;
+ }
+ lab53:
+ ;
+ }
+ }
+lab0:
+ return 1;
+}
+
+static int r_post_process_last_consonants(struct SN_env * z) {
+ int among_var;
+ z->ket = z->c; /* [, line 416 */
+ among_var = find_among_b(z, a_23, 4); /* substring, line 416 */
+ if (!(among_var)) return 0;
+ z->bra = z->c; /* ], line 416 */
+ switch(among_var) {
+ case 0: return 0;
+ case 1:
+ { int ret = slice_from_s(z, 1, s_16); /* <-, line 417 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 2:
+ { int ret = slice_from_s(z, 2, s_17); /* <-, line 418 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 3:
+ { int ret = slice_from_s(z, 1, s_18); /* <-, line 419 */
+ if (ret < 0) return ret;
+ }
+ break;
+ case 4:
+ { int ret = slice_from_s(z, 1, s_19); /* <-, line 420 */
+ if (ret < 0) return ret;
+ }
+ break;
+ }
+ return 1;
+}
+
+static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) {
+ { int m_test = z->l - z->c; /* test, line 431 */
+ { int m1 = z->l - z->c; (void)m1; /* or, line 431 */
+ if (!(eq_s_b(z, 1, s_20))) goto lab1;
+ goto lab0;
+ lab1:
+ z->c = z->l - m1;
+ if (!(eq_s_b(z, 1, s_21))) return 0;
+ }
+ lab0:
+ z->c = z->l - m_test;
+ }
+ { int m2 = z->l - z->c; (void)m2; /* or, line 433 */
+ { int m_test = z->l - z->c; /* test, line 432 */
+ if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab3; /* goto */ /* grouping vowel, line 432 */
+ { int m3 = z->l - z->c; (void)m3; /* or, line 432 */
+ if (!(eq_s_b(z, 1, s_22))) goto lab5;
+ goto lab4;
+ lab5:
+ z->c = z->l - m3;
+ if (!(eq_s_b(z, 2, s_23))) goto lab3;
+ }
+ lab4:
+ z->c = z->l - m_test;
+ }
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 2, s_24); /* <+, line 432 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab3:
+ z->c = z->l - m2;
+ { int m_test = z->l - z->c; /* test, line 434 */
+ if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab6; /* goto */ /* grouping vowel, line 434 */
+ { int m4 = z->l - z->c; (void)m4; /* or, line 434 */
+ if (!(eq_s_b(z, 1, s_25))) goto lab8;
+ goto lab7;
+ lab8:
+ z->c = z->l - m4;
+ if (!(eq_s_b(z, 1, s_26))) goto lab6;
+ }
+ lab7:
+ z->c = z->l - m_test;
+ }
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_27); /* <+, line 434 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab6:
+ z->c = z->l - m2;
+ { int m_test = z->l - z->c; /* test, line 436 */
+ if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab9; /* goto */ /* grouping vowel, line 436 */
+ { int m5 = z->l - z->c; (void)m5; /* or, line 436 */
+ if (!(eq_s_b(z, 1, s_28))) goto lab11;
+ goto lab10;
+ lab11:
+ z->c = z->l - m5;
+ if (!(eq_s_b(z, 1, s_29))) goto lab9;
+ }
+ lab10:
+ z->c = z->l - m_test;
+ }
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 1, s_30); /* <+, line 436 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ goto lab2;
+ lab9:
+ z->c = z->l - m2;
+ { int m_test = z->l - z->c; /* test, line 438 */
+ if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; /* goto */ /* grouping vowel, line 438 */
+ { int m6 = z->l - z->c; (void)m6; /* or, line 438 */
+ if (!(eq_s_b(z, 2, s_31))) goto lab13;
+ goto lab12;
+ lab13:
+ z->c = z->l - m6;
+ if (!(eq_s_b(z, 2, s_32))) return 0;
+ }
+ lab12:
+ z->c = z->l - m_test;
+ }
+ { int c_keep = z->c;
+ int ret = insert_s(z, z->c, z->c, 2, s_33); /* <+, line 438 */
+ z->c = c_keep;
+ if (ret < 0) return ret;
+ }
+ }
+lab2:
+ return 1;
+}
+
+static int r_more_than_one_syllable_word(struct SN_env * z) {
+ { int c_test = z->c; /* test, line 446 */
+ { int i = 2;
+ while(1) { /* atleast, line 446 */
+ int c1 = z->c;
+ { /* gopast */ /* grouping vowel, line 446 */
+ int ret = out_grouping_U(z, g_vowel, 97, 305, 1);
+ if (ret < 0) goto lab0;
+ z->c += ret;
+ }
+ i--;
+ continue;
+ lab0:
+ z->c = c1;
+ break;
+ }
+ if (i > 0) return 0;
+ }
+ z->c = c_test;
+ }
+ return 1;
+}
+
+static int r_is_reserved_word(struct SN_env * z) {
+ { int c1 = z->c; /* or, line 451 */
+ { int c_test = z->c; /* test, line 450 */
+ while(1) { /* gopast, line 450 */
+ if (!(eq_s(z, 2, s_34))) goto lab2;
+ break;
+ lab2:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) goto lab1;
+ z->c = ret; /* gopast, line 450 */
+ }
+ }
+ z->I[0] = 2;
+ if (!(z->I[0] == z->l)) goto lab1;
+ z->c = c_test;
+ }
+ goto lab0;
+ lab1:
+ z->c = c1;
+ { int c_test = z->c; /* test, line 452 */
+ while(1) { /* gopast, line 452 */
+ if (!(eq_s(z, 5, s_35))) goto lab3;
+ break;
+ lab3:
+ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1);
+ if (ret < 0) return 0;
+ z->c = ret; /* gopast, line 452 */
+ }
+ }
+ z->I[0] = 5;
+ if (!(z->I[0] == z->l)) return 0;
+ z->c = c_test;
+ }
+ }
+lab0:
+ return 1;
+}
+
+static int r_postlude(struct SN_env * z) {
+ { int c1 = z->c; /* not, line 456 */
+ { int ret = r_is_reserved_word(z);
+ if (ret == 0) goto lab0; /* call is_reserved_word, line 456 */
+ if (ret < 0) return ret;
+ }
+ return 0;
+ lab0:
+ z->c = c1;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 457 */
+
+ { int m2 = z->l - z->c; (void)m2; /* do, line 458 */
+ { int ret = r_append_U_to_stems_ending_with_d_or_g(z);
+ if (ret == 0) goto lab1; /* call append_U_to_stems_ending_with_d_or_g, line 458 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ { int m3 = z->l - z->c; (void)m3; /* do, line 459 */
+ { int ret = r_post_process_last_consonants(z);
+ if (ret == 0) goto lab2; /* call post_process_last_consonants, line 459 */
+ if (ret < 0) return ret;
+ }
+ lab2:
+ z->c = z->l - m3;
+ }
+ z->c = z->lb;
+ return 1;
+}
+
+extern int turkish_UTF_8_stem(struct SN_env * z) {
+ { int ret = r_more_than_one_syllable_word(z);
+ if (ret == 0) return 0; /* call more_than_one_syllable_word, line 465 */
+ if (ret < 0) return ret;
+ }
+ z->lb = z->c; z->c = z->l; /* backwards, line 467 */
+
+ { int m1 = z->l - z->c; (void)m1; /* do, line 468 */
+ { int ret = r_stem_nominal_verb_suffixes(z);
+ if (ret == 0) goto lab0; /* call stem_nominal_verb_suffixes, line 468 */
+ if (ret < 0) return ret;
+ }
+ lab0:
+ z->c = z->l - m1;
+ }
+ if (!(z->B[0])) return 0; /* Boolean test continue_stemming_noun_suffixes, line 469 */
+ { int m2 = z->l - z->c; (void)m2; /* do, line 470 */
+ { int ret = r_stem_noun_suffixes(z);
+ if (ret == 0) goto lab1; /* call stem_noun_suffixes, line 470 */
+ if (ret < 0) return ret;
+ }
+ lab1:
+ z->c = z->l - m2;
+ }
+ z->c = z->lb;
+ { int ret = r_postlude(z);
+ if (ret == 0) return 0; /* call postlude, line 473 */
+ if (ret < 0) return ret;
+ }
+ return 1;
+}
+
+extern struct SN_env * turkish_UTF_8_create_env(void) { return SN_create_env(0, 1, 1); }
+
+extern void turkish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); }
+
diff --git a/src/backend/snowball/libstemmer/utilities.c b/src/backend/snowball/libstemmer/utilities.c
new file mode 100644
index 00000000000..8c89af1cd5c
--- /dev/null
+++ b/src/backend/snowball/libstemmer/utilities.c
@@ -0,0 +1,473 @@
+#include "header.h"
+
+#define unless(C) if(!(C))
+
+#define CREATE_SIZE 1
+
+extern symbol * create_s(void) {
+ symbol * p;
+ void * mem = malloc(HEAD + (CREATE_SIZE + 1) * sizeof(symbol));
+ if (mem == NULL) return NULL;
+ p = (symbol *) (HEAD + (char *) mem);
+ CAPACITY(p) = CREATE_SIZE;
+ SET_SIZE(p, CREATE_SIZE);
+ return p;
+}
+
+extern void lose_s(symbol * p) {
+ if (p == NULL) return;
+ free((char *) p - HEAD);
+}
+
+/*
+ new_p = skip_utf8(p, c, lb, l, n); skips n characters forwards from p + c
+ if n +ve, or n characters backwards from p + c - 1 if n -ve. new_p is the new
+ position, or 0 on failure.
+
+ -- used to implement hop and next in the utf8 case.
+*/
+
+extern int skip_utf8(const symbol * p, int c, int lb, int l, int n) {
+ int b;
+ if (n >= 0) {
+ for (; n > 0; n--) {
+ if (c >= l) return -1;
+ b = p[c++];
+ if (b >= 0xC0) { /* 1100 0000 */
+ while (c < l) {
+ b = p[c];
+ if (b >= 0xC0 || b < 0x80) break;
+ /* break unless b is 10------ */
+ c++;
+ }
+ }
+ }
+ } else {
+ for (; n < 0; n++) {
+ if (c <= lb) return -1;
+ b = p[--c];
+ if (b >= 0x80) { /* 1000 0000 */
+ while (c > lb) {
+ b = p[c];
+ if (b >= 0xC0) break; /* 1100 0000 */
+ c--;
+ }
+ }
+ }
+ }
+ return c;
+}
+
+/* Code for character groupings: utf8 cases */
+
+static int get_utf8(const symbol * p, int c, int l, int * slot) {
+ int b0, b1;
+ if (c >= l) return 0;
+ b0 = p[c++];
+ if (b0 < 0xC0 || c == l) { /* 1100 0000 */
+ * slot = b0; return 1;
+ }
+ b1 = p[c++];
+ if (b0 < 0xE0 || c == l) { /* 1110 0000 */
+ * slot = (b0 & 0x1F) << 6 | (b1 & 0x3F); return 2;
+ }
+ * slot = (b0 & 0xF) << 12 | (b1 & 0x3F) << 6 | (p[c] & 0x3F); return 3;
+}
+
+static int get_b_utf8(const symbol * p, int c, int lb, int * slot) {
+ int b0, b1;
+ if (c <= lb) return 0;
+ b0 = p[--c];
+ if (b0 < 0x80 || c == lb) { /* 1000 0000 */
+ * slot = b0; return 1;
+ }
+ b1 = p[--c];
+ if (b1 >= 0xC0 || c == lb) { /* 1100 0000 */
+ * slot = (b1 & 0x1F) << 6 | (b0 & 0x3F); return 2;
+ }
+ * slot = (p[c] & 0xF) << 12 | (b1 & 0x3F) << 6 | (b0 & 0x3F); return 3;
+}
+
+extern int in_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
+ do {
+ int ch;
+ int w = get_utf8(z->p, z->c, z->l, & ch);
+ unless (w) return -1;
+ if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
+ return w;
+ z->c += w;
+ } while (repeat);
+ return 0;
+}
+
+extern int in_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
+ do {
+ int ch;
+ int w = get_b_utf8(z->p, z->c, z->lb, & ch);
+ unless (w) return -1;
+ if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
+ return w;
+ z->c -= w;
+ } while (repeat);
+ return 0;
+}
+
+extern int out_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
+ do {
+ int ch;
+ int w = get_utf8(z->p, z->c, z->l, & ch);
+ unless (w) return -1;
+ unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
+ return w;
+ z->c += w;
+ } while (repeat);
+ return 0;
+}
+
+extern int out_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
+ do {
+ int ch;
+ int w = get_b_utf8(z->p, z->c, z->lb, & ch);
+ unless (w) return -1;
+ unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
+ return w;
+ z->c -= w;
+ } while (repeat);
+ return 0;
+}
+
+/* Code for character groupings: non-utf8 cases */
+
+extern int in_grouping(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
+ do {
+ int ch;
+ if (z->c >= z->l) return -1;
+ ch = z->p[z->c];
+ if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
+ return 1;
+ z->c++;
+ } while (repeat);
+ return 0;
+}
+
+extern int in_grouping_b(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
+ do {
+ int ch;
+ if (z->c <= z->lb) return -1;
+ ch = z->p[z->c - 1];
+ if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
+ return 1;
+ z->c--;
+ } while (repeat);
+ return 0;
+}
+
+extern int out_grouping(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
+ do {
+ int ch;
+ if (z->c >= z->l) return -1;
+ ch = z->p[z->c];
+ unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
+ return 1;
+ z->c++;
+ } while (repeat);
+ return 0;
+}
+
+extern int out_grouping_b(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) {
+ do {
+ int ch;
+ if (z->c <= z->lb) return -1;
+ ch = z->p[z->c - 1];
+ unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)
+ return 1;
+ z->c--;
+ } while (repeat);
+ return 0;
+}
+
+extern int eq_s(struct SN_env * z, int s_size, const symbol * s) {
+ if (z->l - z->c < s_size || memcmp(z->p + z->c, s, s_size * sizeof(symbol)) != 0) return 0;
+ z->c += s_size; return 1;
+}
+
+extern int eq_s_b(struct SN_env * z, int s_size, const symbol * s) {
+ if (z->c - z->lb < s_size || memcmp(z->p + z->c - s_size, s, s_size * sizeof(symbol)) != 0) return 0;
+ z->c -= s_size; return 1;
+}
+
+extern int eq_v(struct SN_env * z, const symbol * p) {
+ return eq_s(z, SIZE(p), p);
+}
+
+extern int eq_v_b(struct SN_env * z, const symbol * p) {
+ return eq_s_b(z, SIZE(p), p);
+}
+
+extern int find_among(struct SN_env * z, const struct among * v, int v_size) {
+
+ int i = 0;
+ int j = v_size;
+
+ int c = z->c; int l = z->l;
+ symbol * q = z->p + c;
+
+ const struct among * w;
+
+ int common_i = 0;
+ int common_j = 0;
+
+ int first_key_inspected = 0;
+
+ while(1) {
+ int k = i + ((j - i) >> 1);
+ int diff = 0;
+ int common = common_i < common_j ? common_i : common_j; /* smaller */
+ w = v + k;
+ {
+ int i2; for (i2 = common; i2 < w->s_size; i2++) {
+ if (c + common == l) { diff = -1; break; }
+ diff = q[common] - w->s[i2];
+ if (diff != 0) break;
+ common++;
+ }
+ }
+ if (diff < 0) { j = k; common_j = common; }
+ else { i = k; common_i = common; }
+ if (j - i <= 1) {
+ if (i > 0) break; /* v->s has been inspected */
+ if (j == i) break; /* only one item in v */
+
+ /* - but now we need to go round once more to get
+ v->s inspected. This looks messy, but is actually
+ the optimal approach. */
+
+ if (first_key_inspected) break;
+ first_key_inspected = 1;
+ }
+ }
+ while(1) {
+ w = v + i;
+ if (common_i >= w->s_size) {
+ z->c = c + w->s_size;
+ if (w->function == 0) return w->result;
+ {
+ int res = w->function(z);
+ z->c = c + w->s_size;
+ if (res) return w->result;
+ }
+ }
+ i = w->substring_i;
+ if (i < 0) return 0;
+ }
+}
+
+/* find_among_b is for backwards processing. Same comments apply */
+
+extern int find_among_b(struct SN_env * z, const struct among * v, int v_size) {
+
+ int i = 0;
+ int j = v_size;
+
+ int c = z->c; int lb = z->lb;
+ symbol * q = z->p + c - 1;
+
+ const struct among * w;
+
+ int common_i = 0;
+ int common_j = 0;
+
+ int first_key_inspected = 0;
+
+ while(1) {
+ int k = i + ((j - i) >> 1);
+ int diff = 0;
+ int common = common_i < common_j ? common_i : common_j;
+ w = v + k;
+ {
+ int i2; for (i2 = w->s_size - 1 - common; i2 >= 0; i2--) {
+ if (c - common == lb) { diff = -1; break; }
+ diff = q[- common] - w->s[i2];
+ if (diff != 0) break;
+ common++;
+ }
+ }
+ if (diff < 0) { j = k; common_j = common; }
+ else { i = k; common_i = common; }
+ if (j - i <= 1) {
+ if (i > 0) break;
+ if (j == i) break;
+ if (first_key_inspected) break;
+ first_key_inspected = 1;
+ }
+ }
+ while(1) {
+ w = v + i;
+ if (common_i >= w->s_size) {
+ z->c = c - w->s_size;
+ if (w->function == 0) return w->result;
+ {
+ int res = w->function(z);
+ z->c = c - w->s_size;
+ if (res) return w->result;
+ }
+ }
+ i = w->substring_i;
+ if (i < 0) return 0;
+ }
+}
+
+
+/* Increase the size of the buffer pointed to by p to at least n symbols.
+ * If insufficient memory, returns NULL and frees the old buffer.
+ */
+static symbol * increase_size(symbol * p, int n) {
+ symbol * q;
+ int new_size = n + 20;
+ void * mem = realloc((char *) p - HEAD,
+ HEAD + (new_size + 1) * sizeof(symbol));
+ if (mem == NULL) {
+ lose_s(p);
+ return NULL;
+ }
+ q = (symbol *) (HEAD + (char *)mem);
+ CAPACITY(q) = new_size;
+ return q;
+}
+
+/* to replace symbols between c_bra and c_ket in z->p by the
+ s_size symbols at s.
+ Returns 0 on success, -1 on error.
+ Also, frees z->p (and sets it to NULL) on error.
+*/
+extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s, int * adjptr)
+{
+ int adjustment;
+ int len;
+ if (z->p == NULL) {
+ z->p = create_s();
+ if (z->p == NULL) return -1;
+ }
+ adjustment = s_size - (c_ket - c_bra);
+ len = SIZE(z->p);
+ if (adjustment != 0) {
+ if (adjustment + len > CAPACITY(z->p)) {
+ z->p = increase_size(z->p, adjustment + len);
+ if (z->p == NULL) return -1;
+ }
+ memmove(z->p + c_ket + adjustment,
+ z->p + c_ket,
+ (len - c_ket) * sizeof(symbol));
+ SET_SIZE(z->p, adjustment + len);
+ z->l += adjustment;
+ if (z->c >= c_ket)
+ z->c += adjustment;
+ else
+ if (z->c > c_bra)
+ z->c = c_bra;
+ }
+ unless (s_size == 0) memmove(z->p + c_bra, s, s_size * sizeof(symbol));
+ if (adjptr != NULL)
+ *adjptr = adjustment;
+ return 0;
+}
+
+static int slice_check(struct SN_env * z) {
+
+ if (z->bra < 0 ||
+ z->bra > z->ket ||
+ z->ket > z->l ||
+ z->p == NULL ||
+ z->l > SIZE(z->p)) /* this line could be removed */
+ {
+#if 0
+ fprintf(stderr, "faulty slice operation:\n");
+ debug(z, -1, 0);
+#endif
+ return -1;
+ }
+ return 0;
+}
+
+extern int slice_from_s(struct SN_env * z, int s_size, const symbol * s) {
+ if (slice_check(z)) return -1;
+ return replace_s(z, z->bra, z->ket, s_size, s, NULL);
+}
+
+extern int slice_from_v(struct SN_env * z, const symbol * p) {
+ return slice_from_s(z, SIZE(p), p);
+}
+
+extern int slice_del(struct SN_env * z) {
+ return slice_from_s(z, 0, 0);
+}
+
+extern int insert_s(struct SN_env * z, int bra, int ket, int s_size, const symbol * s) {
+ int adjustment;
+ if (replace_s(z, bra, ket, s_size, s, &adjustment))
+ return -1;
+ if (bra <= z->bra) z->bra += adjustment;
+ if (bra <= z->ket) z->ket += adjustment;
+ return 0;
+}
+
+extern int insert_v(struct SN_env * z, int bra, int ket, const symbol * p) {
+ int adjustment;
+ if (replace_s(z, bra, ket, SIZE(p), p, &adjustment))
+ return -1;
+ if (bra <= z->bra) z->bra += adjustment;
+ if (bra <= z->ket) z->ket += adjustment;
+ return 0;
+}
+
+extern symbol * slice_to(struct SN_env * z, symbol * p) {
+ if (slice_check(z)) {
+ lose_s(p);
+ return NULL;
+ }
+ {
+ int len = z->ket - z->bra;
+ if (CAPACITY(p) < len) {
+ p = increase_size(p, len);
+ if (p == NULL)
+ return NULL;
+ }
+ memmove(p, z->p + z->bra, len * sizeof(symbol));
+ SET_SIZE(p, len);
+ }
+ return p;
+}
+
+extern symbol * assign_to(struct SN_env * z, symbol * p) {
+ int len = z->l;
+ if (CAPACITY(p) < len) {
+ p = increase_size(p, len);
+ if (p == NULL)
+ return NULL;
+ }
+ memmove(p, z->p, len * sizeof(symbol));
+ SET_SIZE(p, len);
+ return p;
+}
+
+#if 0
+extern void debug(struct SN_env * z, int number, int line_count) {
+ int i;
+ int limit = SIZE(z->p);
+ /*if (number >= 0) printf("%3d (line %4d): '", number, line_count);*/
+ if (number >= 0) printf("%3d (line %4d): [%d]'", number, line_count,limit);
+ for (i = 0; i <= limit; i++) {
+ if (z->lb == i) printf("{");
+ if (z->bra == i) printf("[");
+ if (z->c == i) printf("|");
+ if (z->ket == i) printf("]");
+ if (z->l == i) printf("}");
+ if (i < limit)
+ { int ch = z->p[i];
+ if (ch == 0) ch = '#';
+ printf("%c", ch);
+ }
+ }
+ printf("'\n");
+}
+#endif
diff --git a/src/backend/snowball/snowball.sql.in b/src/backend/snowball/snowball.sql.in
new file mode 100644
index 00000000000..5f1f3e772e8
--- /dev/null
+++ b/src/backend/snowball/snowball.sql.in
@@ -0,0 +1,26 @@
+-- $PostgreSQL: pgsql/src/backend/snowball/snowball.sql.in,v 1.1 2007/08/21 01:11:16 tgl Exp $$
+
+-- text search configuration for _CFGNAME_ language
+CREATE TEXT SEARCH DICTIONARY _DICTNAME_
+ (TEMPLATE = snowball,
+ OPTION = 'Language=_DICTNAME__STOPWORDS_');
+
+COMMENT ON TEXT SEARCH DICTIONARY _DICTNAME_ IS 'Snowball stemmer for _DICTNAME_ language';
+
+CREATE TEXT SEARCH CONFIGURATION _CFGNAME_
+ (PARSER = default);
+
+COMMENT ON TEXT SEARCH CONFIGURATION _CFGNAME_ IS 'Configuration for _CFGNAME_ language';
+
+ALTER TEXT SEARCH CONFIGURATION _CFGNAME_ ADD MAPPING
+ FOR email, url, host, sfloat, version, uri, file, float, int, uint
+ WITH simple;
+
+ALTER TEXT SEARCH CONFIGURATION _CFGNAME_ ADD MAPPING
+ FOR lhword, lpart_hword, lword
+ WITH _LATDICTNAME_;
+
+ALTER TEXT SEARCH CONFIGURATION _CFGNAME_ ADD MAPPING
+ FOR hword, nlhword, nlpart_hword, nlword, word, part_hword
+ WITH _NONLATDICTNAME_;
+
diff --git a/src/backend/snowball/snowball_func.sql.in b/src/backend/snowball/snowball_func.sql.in
new file mode 100644
index 00000000000..db3ca2c9d00
--- /dev/null
+++ b/src/backend/snowball/snowball_func.sql.in
@@ -0,0 +1,18 @@
+-- $PostgreSQL: pgsql/src/backend/snowball/snowball_func.sql.in,v 1.1 2007/08/21 01:11:16 tgl Exp $$
+
+SET search_path = pg_catalog;
+
+CREATE FUNCTION dsnowball_init(INTERNAL)
+ RETURNS INTERNAL AS '$libdir/dict_snowball', 'dsnowball_init'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION dsnowball_lexize(INTERNAL, INTERNAL, INTERNAL, INTERNAL)
+ RETURNS INTERNAL AS '$libdir/dict_snowball', 'dsnowball_lexize'
+LANGUAGE C STRICT;
+
+CREATE TEXT SEARCH TEMPLATE snowball
+ (INIT = dsnowball_init,
+ LEXIZE = dsnowball_lexize);
+
+COMMENT ON TEXT SEARCH TEMPLATE snowball IS 'Snowball stemmer';
+
diff --git a/src/backend/snowball/stopwords/danish.stop b/src/backend/snowball/stopwords/danish.stop
new file mode 100644
index 00000000000..d3edc675791
--- /dev/null
+++ b/src/backend/snowball/stopwords/danish.stop
@@ -0,0 +1,94 @@
+og
+i
+jeg
+det
+at
+en
+den
+til
+er
+som
+på
+de
+med
+han
+af
+for
+ikke
+der
+var
+mig
+sig
+men
+et
+har
+om
+vi
+min
+havde
+ham
+hun
+nu
+over
+da
+fra
+du
+ud
+sin
+dem
+os
+op
+man
+hans
+hvor
+eller
+hvad
+skal
+selv
+her
+alle
+vil
+blev
+kunne
+ind
+når
+være
+dog
+noget
+ville
+jo
+deres
+efter
+ned
+skulle
+denne
+end
+dette
+mit
+også
+under
+have
+dig
+anden
+hende
+mine
+alt
+meget
+sit
+sine
+vor
+mod
+disse
+hvis
+din
+nogle
+hos
+blive
+mange
+ad
+bliver
+hendes
+været
+thi
+jer
+sådan
diff --git a/src/backend/snowball/stopwords/dutch.stop b/src/backend/snowball/stopwords/dutch.stop
new file mode 100644
index 00000000000..cafa0324b53
--- /dev/null
+++ b/src/backend/snowball/stopwords/dutch.stop
@@ -0,0 +1,101 @@
+de
+en
+van
+ik
+te
+dat
+die
+in
+een
+hij
+het
+niet
+zijn
+is
+was
+op
+aan
+met
+als
+voor
+had
+er
+maar
+om
+hem
+dan
+zou
+of
+wat
+mijn
+men
+dit
+zo
+door
+over
+ze
+zich
+bij
+ook
+tot
+je
+mij
+uit
+der
+daar
+haar
+naar
+heb
+hoe
+heeft
+hebben
+deze
+u
+want
+nog
+zal
+me
+zij
+nu
+ge
+geen
+omdat
+iets
+worden
+toch
+al
+waren
+veel
+meer
+doen
+toen
+moet
+ben
+zonder
+kan
+hun
+dus
+alles
+onder
+ja
+eens
+hier
+wie
+werd
+altijd
+doch
+wordt
+wezen
+kunnen
+ons
+zelf
+tegen
+na
+reeds
+wil
+kon
+niets
+uw
+iemand
+geweest
+andere
diff --git a/src/backend/snowball/stopwords/english.stop b/src/backend/snowball/stopwords/english.stop
new file mode 100644
index 00000000000..a9130116d3e
--- /dev/null
+++ b/src/backend/snowball/stopwords/english.stop
@@ -0,0 +1,128 @@
+i
+me
+my
+myself
+we
+our
+ours
+ourselves
+you
+your
+yours
+yourself
+yourselves
+he
+him
+his
+himself
+she
+her
+hers
+herself
+it
+its
+itself
+they
+them
+their
+theirs
+themselves
+what
+which
+who
+whom
+this
+that
+these
+those
+am
+is
+are
+was
+were
+be
+been
+being
+have
+has
+had
+having
+do
+does
+did
+doing
+a
+an
+the
+and
+but
+if
+or
+because
+as
+until
+while
+of
+at
+by
+for
+with
+about
+against
+between
+into
+through
+during
+before
+after
+above
+below
+to
+from
+up
+down
+in
+out
+on
+off
+over
+under
+again
+further
+then
+once
+here
+there
+when
+where
+why
+how
+all
+any
+both
+each
+few
+more
+most
+other
+some
+such
+no
+nor
+not
+only
+own
+same
+so
+than
+too
+very
+s
+t
+can
+will
+just
+don
+should
+now
+
diff --git a/src/backend/snowball/stopwords/finnish.stop b/src/backend/snowball/stopwords/finnish.stop
new file mode 100644
index 00000000000..47ee200f678
--- /dev/null
+++ b/src/backend/snowball/stopwords/finnish.stop
@@ -0,0 +1,235 @@
+olla
+olen
+olet
+on
+olemme
+olette
+ovat
+ole
+oli
+olisi
+olisit
+olisin
+olisimme
+olisitte
+olisivat
+olit
+olin
+olimme
+olitte
+olivat
+ollut
+olleet
+en
+et
+ei
+emme
+ette
+eivät
+minä
+minun
+minut
+minua
+minussa
+minusta
+minuun
+minulla
+minulta
+minulle
+sinä
+sinun
+sinut
+sinua
+sinussa
+sinusta
+sinuun
+sinulla
+sinulta
+sinulle
+hän
+hänen
+hänet
+häntä
+hänessä
+hänestä
+häneen
+hänellä
+häneltä
+hänelle
+me
+meidän
+meidät
+meitä
+meissä
+meistä
+meihin
+meillä
+meiltä
+meille
+te
+teidän
+teidät
+teitä
+teissä
+teistä
+teihin
+teillä
+teiltä
+teille
+he
+heidän
+heidät
+heitä
+heissä
+heistä
+heihin
+heillä
+heiltä
+heille
+tämä
+tämän
+tätä
+tässä
+tästä
+tähän
+tallä
+tältä
+tälle
+tänä
+täksi
+tuo
+tuon
+tuotä
+tuossa
+tuosta
+tuohon
+tuolla
+tuolta
+tuolle
+tuona
+tuoksi
+se
+sen
+sitä
+siinä
+siitä
+siihen
+sillä
+siltä
+sille
+sinä
+siksi
+nämä
+näiden
+näitä
+näissä
+näistä
+näihin
+näillä
+näiltä
+näille
+näinä
+näiksi
+nuo
+noiden
+noita
+noissa
+noista
+noihin
+noilla
+noilta
+noille
+noina
+noiksi
+ne
+niiden
+niitä
+niissä
+niistä
+niihin
+niillä
+niiltä
+niille
+niinä
+niiksi
+kuka
+kenen
+kenet
+ketä
+kenessä
+kenestä
+keneen
+kenellä
+keneltä
+kenelle
+kenenä
+keneksi
+ketkä
+keiden
+ketkä
+keitä
+keissä
+keistä
+keihin
+keillä
+keiltä
+keille
+keinä
+keiksi
+mikä
+minkä
+minkä
+mitä
+missä
+mistä
+mihin
+millä
+miltä
+mille
+minä
+miksi
+mitkä
+joka
+jonka
+jota
+jossa
+josta
+johon
+jolla
+jolta
+jolle
+jona
+joksi
+jotka
+joiden
+joita
+joissa
+joista
+joihin
+joilla
+joilta
+joille
+joina
+joiksi
+että
+ja
+jos
+koska
+kuin
+mutta
+niin
+sekä
+sillä
+tai
+vaan
+vai
+vaikka
+kanssa
+mukaan
+noin
+poikki
+yli
+kun
+niin
+nyt
+itse
diff --git a/src/backend/snowball/stopwords/french.stop b/src/backend/snowball/stopwords/french.stop
new file mode 100644
index 00000000000..e7cbf4c9750
--- /dev/null
+++ b/src/backend/snowball/stopwords/french.stop
@@ -0,0 +1,155 @@
+au
+aux
+avec
+ce
+ces
+dans
+de
+des
+du
+elle
+en
+et
+eux
+il
+je
+la
+le
+leur
+lui
+ma
+mais
+me
+même
+mes
+moi
+mon
+ne
+nos
+notre
+nous
+on
+ou
+par
+pas
+pour
+qu
+que
+qui
+sa
+se
+ses
+son
+sur
+ta
+te
+tes
+toi
+ton
+tu
+un
+une
+vos
+votre
+vous
+c
+d
+j
+l
+m
+n
+s
+t
+y
+été
+étée
+étées
+étés
+étant
+étante
+étants
+étantes
+suis
+es
+est
+sommes
+êtes
+sont
+serai
+seras
+sera
+serons
+serez
+seront
+serais
+serait
+serions
+seriez
+seraient
+étais
+était
+étions
+étiez
+étaient
+fus
+fut
+fûmes
+fûtes
+furent
+sois
+soit
+soyons
+soyez
+soient
+fusse
+fusses
+fût
+fussions
+fussiez
+fussent
+ayant
+ayante
+ayantes
+ayants
+eu
+eue
+eues
+eus
+ai
+as
+avons
+avez
+ont
+aurai
+auras
+aura
+aurons
+aurez
+auront
+aurais
+aurait
+aurions
+auriez
+auraient
+avais
+avait
+avions
+aviez
+avaient
+eut
+eûmes
+eûtes
+eurent
+aie
+aies
+ait
+ayons
+ayez
+aient
+eusse
+eusses
+eût
+eussions
+eussiez
+eussent
diff --git a/src/backend/snowball/stopwords/german.stop b/src/backend/snowball/stopwords/german.stop
new file mode 100644
index 00000000000..edef220b7a7
--- /dev/null
+++ b/src/backend/snowball/stopwords/german.stop
@@ -0,0 +1,231 @@
+aber
+alle
+allem
+allen
+aller
+alles
+als
+also
+am
+an
+ander
+andere
+anderem
+anderen
+anderer
+anderes
+anderm
+andern
+anderr
+anders
+auch
+auf
+aus
+bei
+bin
+bis
+bist
+da
+damit
+dann
+der
+den
+des
+dem
+die
+das
+daß
+derselbe
+derselben
+denselben
+desselben
+demselben
+dieselbe
+dieselben
+dasselbe
+dazu
+dein
+deine
+deinem
+deinen
+deiner
+deines
+denn
+derer
+dessen
+dich
+dir
+du
+dies
+diese
+diesem
+diesen
+dieser
+dieses
+doch
+dort
+durch
+ein
+eine
+einem
+einen
+einer
+eines
+einig
+einige
+einigem
+einigen
+einiger
+einiges
+einmal
+er
+ihn
+ihm
+es
+etwas
+euer
+eure
+eurem
+euren
+eurer
+eures
+für
+gegen
+gewesen
+hab
+habe
+haben
+hat
+hatte
+hatten
+hier
+hin
+hinter
+ich
+mich
+mir
+ihr
+ihre
+ihrem
+ihren
+ihrer
+ihres
+euch
+im
+in
+indem
+ins
+ist
+jede
+jedem
+jeden
+jeder
+jedes
+jene
+jenem
+jenen
+jener
+jenes
+jetzt
+kann
+kein
+keine
+keinem
+keinen
+keiner
+keines
+können
+könnte
+machen
+man
+manche
+manchem
+manchen
+mancher
+manches
+mein
+meine
+meinem
+meinen
+meiner
+meines
+mit
+muss
+musste
+nach
+nicht
+nichts
+noch
+nun
+nur
+ob
+oder
+ohne
+sehr
+sein
+seine
+seinem
+seinen
+seiner
+seines
+selbst
+sich
+sie
+ihnen
+sind
+so
+solche
+solchem
+solchen
+solcher
+solches
+soll
+sollte
+sondern
+sonst
+über
+um
+und
+uns
+unse
+unsem
+unsen
+unser
+unses
+unter
+viel
+vom
+von
+vor
+während
+war
+waren
+warst
+was
+weg
+weil
+weiter
+welche
+welchem
+welchen
+welcher
+welches
+wenn
+werde
+werden
+wie
+wieder
+will
+wir
+wird
+wirst
+wo
+wollen
+wollte
+würde
+würden
+zu
+zum
+zur
+zwar
+zwischen
diff --git a/src/backend/snowball/stopwords/hungarian.stop b/src/backend/snowball/stopwords/hungarian.stop
new file mode 100644
index 00000000000..94e9f9a0b07
--- /dev/null
+++ b/src/backend/snowball/stopwords/hungarian.stop
@@ -0,0 +1,199 @@
+a
+ahogy
+ahol
+aki
+akik
+akkor
+alatt
+által
+általában
+amely
+amelyek
+amelyekben
+amelyeket
+amelyet
+amelynek
+ami
+amit
+amolyan
+amíg
+amikor
+át
+abban
+ahhoz
+annak
+arra
+arról
+az
+azok
+azon
+azt
+azzal
+azért
+aztán
+azután
+azonban
+bár
+be
+belül
+benne
+cikk
+cikkek
+cikkeket
+csak
+de
+e
+eddig
+egész
+egy
+egyes
+egyetlen
+egyéb
+egyik
+egyre
+ekkor
+el
+elég
+ellen
+elõ
+elõször
+elõtt
+elsõ
+én
+éppen
+ebben
+ehhez
+emilyen
+ennek
+erre
+ez
+ezt
+ezek
+ezen
+ezzel
+ezért
+és
+fel
+felé
+hanem
+hiszen
+hogy
+hogyan
+igen
+így
+illetve
+ill.
+ill
+ilyen
+ilyenkor
+ison
+ismét
+itt
+jó
+jól
+jobban
+kell
+kellett
+keresztül
+keressünk
+ki
+kívül
+között
+közül
+legalább
+lehet
+lehetett
+legyen
+lenne
+lenni
+lesz
+lett
+maga
+magát
+majd
+majd
+már
+más
+másik
+meg
+még
+mellett
+mert
+mely
+melyek
+mi
+mit
+míg
+miért
+milyen
+mikor
+minden
+mindent
+mindenki
+mindig
+mint
+mintha
+mivel
+most
+nagy
+nagyobb
+nagyon
+ne
+néha
+nekem
+neki
+nem
+néhány
+nélkül
+nincs
+olyan
+ott
+össze
+õk
+õket
+pedig
+persze
+rá
+s
+saját
+sem
+semmi
+sok
+sokat
+sokkal
+számára
+szemben
+szerint
+szinte
+talán
+tehát
+teljes
+tovább
+továbbá
+több
+úgy
+ugyanis
+új
+újabb
+újra
+után
+utána
+utolsó
+vagy
+vagyis
+valaki
+valami
+valamint
+való
+vagyok
+van
+vannak
+volt
+voltam
+voltak
+voltunk
+vissza
+vele
+viszont
+volna
diff --git a/src/backend/snowball/stopwords/italian.stop b/src/backend/snowball/stopwords/italian.stop
new file mode 100644
index 00000000000..6ee02b51fb1
--- /dev/null
+++ b/src/backend/snowball/stopwords/italian.stop
@@ -0,0 +1,279 @@
+ad
+al
+allo
+ai
+agli
+all
+agl
+alla
+alle
+con
+col
+coi
+da
+dal
+dallo
+dai
+dagli
+dall
+dagl
+dalla
+dalle
+di
+del
+dello
+dei
+degli
+dell
+degl
+della
+delle
+in
+nel
+nello
+nei
+negli
+nell
+negl
+nella
+nelle
+su
+sul
+sullo
+sui
+sugli
+sull
+sugl
+sulla
+sulle
+per
+tra
+contro
+io
+tu
+lui
+lei
+noi
+voi
+loro
+mio
+mia
+miei
+mie
+tuo
+tua
+tuoi
+tue
+suo
+sua
+suoi
+sue
+nostro
+nostra
+nostri
+nostre
+vostro
+vostra
+vostri
+vostre
+mi
+ti
+ci
+vi
+lo
+la
+li
+le
+gli
+ne
+il
+un
+uno
+una
+ma
+ed
+se
+perché
+anche
+come
+dov
+dove
+che
+chi
+cui
+non
+più
+quale
+quanto
+quanti
+quanta
+quante
+quello
+quelli
+quella
+quelle
+questo
+questi
+questa
+queste
+si
+tutto
+tutti
+a
+c
+e
+i
+l
+o
+ho
+hai
+ha
+abbiamo
+avete
+hanno
+abbia
+abbiate
+abbiano
+avrò
+avrai
+avrà
+avremo
+avrete
+avranno
+avrei
+avresti
+avrebbe
+avremmo
+avreste
+avrebbero
+avevo
+avevi
+aveva
+avevamo
+avevate
+avevano
+ebbi
+avesti
+ebbe
+avemmo
+aveste
+ebbero
+avessi
+avesse
+avessimo
+avessero
+avendo
+avuto
+avuta
+avuti
+avute
+sono
+sei
+siamo
+siete
+sia
+siate
+siano
+sarò
+sarai
+sarà
+saremo
+sarete
+saranno
+sarei
+saresti
+sarebbe
+saremmo
+sareste
+sarebbero
+ero
+eri
+era
+eravamo
+eravate
+erano
+fui
+fosti
+fu
+fummo
+foste
+furono
+fossi
+fosse
+fossimo
+fossero
+essendo
+faccio
+fai
+facciamo
+fanno
+faccia
+facciate
+facciano
+farò
+farai
+farà
+faremo
+farete
+faranno
+farei
+faresti
+farebbe
+faremmo
+fareste
+farebbero
+facevo
+facevi
+faceva
+facevamo
+facevate
+facevano
+feci
+facesti
+fece
+facemmo
+faceste
+fecero
+facessi
+facesse
+facessimo
+facessero
+facendo
+sto
+stai
+sta
+stiamo
+stanno
+stia
+stiate
+stiano
+starò
+starai
+starà
+staremo
+starete
+staranno
+starei
+staresti
+starebbe
+staremmo
+stareste
+starebbero
+stavo
+stavi
+stava
+stavamo
+stavate
+stavano
+stetti
+stesti
+stette
+stemmo
+steste
+stettero
+stessi
+stesse
+stessimo
+stessero
+stando
diff --git a/src/backend/snowball/stopwords/norwegian.stop b/src/backend/snowball/stopwords/norwegian.stop
new file mode 100644
index 00000000000..9ac1abbb6cb
--- /dev/null
+++ b/src/backend/snowball/stopwords/norwegian.stop
@@ -0,0 +1,176 @@
+og
+i
+jeg
+det
+at
+en
+et
+den
+til
+er
+som
+på
+de
+med
+han
+av
+ikke
+ikkje
+der
+så
+var
+meg
+seg
+men
+ett
+har
+om
+vi
+min
+mitt
+ha
+hadde
+hun
+nå
+over
+da
+ved
+fra
+du
+ut
+sin
+dem
+oss
+opp
+man
+kan
+hans
+hvor
+eller
+hva
+skal
+selv
+sjøl
+her
+alle
+vil
+bli
+ble
+blei
+blitt
+kunne
+inn
+når
+være
+kom
+noen
+noe
+ville
+dere
+som
+deres
+kun
+ja
+etter
+ned
+skulle
+denne
+for
+deg
+si
+sine
+sitt
+mot
+meget
+hvorfor
+dette
+disse
+uten
+hvordan
+ingen
+din
+ditt
+blir
+samme
+hvilken
+hvilke
+sånn
+inni
+mellom
+vår
+hver
+hvem
+vors
+hvis
+både
+bare
+enn
+fordi
+før
+mange
+også
+slik
+vært
+være
+båe
+begge
+siden
+dykk
+dykkar
+dei
+deira
+deires
+deim
+di
+då
+eg
+ein
+eit
+eitt
+elles
+honom
+hjå
+ho
+hoe
+henne
+hennar
+hennes
+hoss
+hossen
+ikkje
+ingi
+inkje
+korleis
+korso
+kva
+kvar
+kvarhelst
+kven
+kvi
+kvifor
+me
+medan
+mi
+mine
+mykje
+no
+nokon
+noka
+nokor
+noko
+nokre
+si
+sia
+sidan
+so
+somt
+somme
+um
+upp
+vere
+vore
+verte
+vort
+varte
+vart
diff --git a/src/backend/snowball/stopwords/portuguese.stop b/src/backend/snowball/stopwords/portuguese.stop
new file mode 100644
index 00000000000..6b2477863b7
--- /dev/null
+++ b/src/backend/snowball/stopwords/portuguese.stop
@@ -0,0 +1,203 @@
+de
+a
+o
+que
+e
+do
+da
+em
+um
+para
+com
+não
+uma
+os
+no
+se
+na
+por
+mais
+as
+dos
+como
+mas
+ao
+ele
+das
+seu
+sua
+ou
+quando
+muito
+nos
+já
+eu
+também
+só
+pelo
+pela
+até
+isso
+ela
+entre
+depois
+sem
+mesmo
+aos
+seus
+quem
+nas
+me
+esse
+eles
+você
+essa
+num
+nem
+suas
+meu
+às
+minha
+numa
+pelos
+elas
+qual
+nós
+lhe
+deles
+essas
+esses
+pelas
+este
+dele
+tu
+te
+vocês
+vos
+lhes
+meus
+minhas
+teu
+tua
+teus
+tuas
+nosso
+nossa
+nossos
+nossas
+dela
+delas
+esta
+estes
+estas
+aquele
+aquela
+aqueles
+aquelas
+isto
+aquilo
+estou
+está
+estamos
+estão
+estive
+esteve
+estivemos
+estiveram
+estava
+estávamos
+estavam
+estivera
+estivéramos
+esteja
+estejamos
+estejam
+estivesse
+estivéssemos
+estivessem
+estiver
+estivermos
+estiverem
+hei
+há
+havemos
+hão
+houve
+houvemos
+houveram
+houvera
+houvéramos
+haja
+hajamos
+hajam
+houvesse
+houvéssemos
+houvessem
+houver
+houvermos
+houverem
+houverei
+houverá
+houveremos
+houverão
+houveria
+houveríamos
+houveriam
+sou
+somos
+são
+era
+éramos
+eram
+fui
+foi
+fomos
+foram
+fora
+fôramos
+seja
+sejamos
+sejam
+fosse
+fôssemos
+fossem
+for
+formos
+forem
+serei
+será
+seremos
+serão
+seria
+seríamos
+seriam
+tenho
+tem
+temos
+tém
+tinha
+tínhamos
+tinham
+tive
+teve
+tivemos
+tiveram
+tivera
+tivéramos
+tenha
+tenhamos
+tenham
+tivesse
+tivéssemos
+tivessem
+tiver
+tivermos
+tiverem
+terei
+terá
+teremos
+terão
+teria
+teríamos
+teriam
diff --git a/src/backend/snowball/stopwords/russian.stop b/src/backend/snowball/stopwords/russian.stop
new file mode 100644
index 00000000000..ecb83d4a7f3
--- /dev/null
+++ b/src/backend/snowball/stopwords/russian.stop
@@ -0,0 +1,151 @@
+во
+не
+что
+он
+на
+со
+как
+то
+все
+она
+так
+его
+но
+да
+ты
+же
+вы
+за
+бы
+по
+только
+ее
+мне
+было
+вот
+от
+меня
+еще
+нет
+из
+ему
+теперь
+когда
+даже
+ну
+вдруг
+ли
+если
+уже
+или
+ни
+быть
+был
+него
+до
+вас
+нибудь
+опять
+уж
+вам
+ведь
+там
+потом
+себя
+ничего
+ей
+может
+они
+тут
+где
+есть
+надо
+ней
+для
+мы
+тебя
+их
+чем
+была
+сам
+чтоб
+без
+будто
+чего
+раз
+тоже
+себе
+под
+будет
+тогда
+кто
+этот
+того
+потому
+этого
+какой
+совсем
+ним
+здесь
+этом
+один
+почти
+мой
+тем
+чтобы
+нее
+сейчас
+были
+куда
+зачем
+всех
+никогда
+можно
+при
+наконец
+два
+об
+другой
+хоть
+после
+над
+больше
+тот
+через
+эти
+нас
+про
+всего
+них
+какая
+много
+разве
+три
+эту
+моя
+впрочем
+хорошо
+свою
+этой
+перед
+иногда
+лучше
+чуть
+том
+нельзя
+такой
+им
+более
+всегда
+конечно
+всю
+между
diff --git a/src/backend/snowball/stopwords/spanish.stop b/src/backend/snowball/stopwords/spanish.stop
new file mode 100644
index 00000000000..59bc786caa4
--- /dev/null
+++ b/src/backend/snowball/stopwords/spanish.stop
@@ -0,0 +1,313 @@
+de
+la
+que
+el
+en
+y
+a
+los
+del
+se
+las
+por
+un
+para
+con
+no
+una
+su
+al
+lo
+como
+más
+pero
+sus
+le
+ya
+o
+este
+sí
+porque
+esta
+entre
+cuando
+muy
+sin
+sobre
+también
+me
+hasta
+hay
+donde
+quien
+desde
+todo
+nos
+durante
+todos
+uno
+les
+ni
+contra
+otros
+ese
+eso
+ante
+ellos
+e
+esto
+mí
+antes
+algunos
+qué
+unos
+yo
+otro
+otras
+otra
+él
+tanto
+esa
+estos
+mucho
+quienes
+nada
+muchos
+cual
+poco
+ella
+estar
+estas
+algunas
+algo
+nosotros
+mi
+mis
+tú
+te
+ti
+tu
+tus
+ellas
+nosotras
+vosostros
+vosostras
+os
+mío
+mía
+míos
+mías
+tuyo
+tuya
+tuyos
+tuyas
+suyo
+suya
+suyos
+suyas
+nuestro
+nuestra
+nuestros
+nuestras
+vuestro
+vuestra
+vuestros
+vuestras
+esos
+esas
+estoy
+estás
+está
+estamos
+estáis
+están
+esté
+estés
+estemos
+estéis
+estén
+estaré
+estarás
+estará
+estaremos
+estaréis
+estarán
+estaría
+estarías
+estaríamos
+estaríais
+estarían
+estaba
+estabas
+estábamos
+estabais
+estaban
+estuve
+estuviste
+estuvo
+estuvimos
+estuvisteis
+estuvieron
+estuviera
+estuvieras
+estuviéramos
+estuvierais
+estuvieran
+estuviese
+estuvieses
+estuviésemos
+estuvieseis
+estuviesen
+estando
+estado
+estada
+estados
+estadas
+estad
+he
+has
+ha
+hemos
+habéis
+han
+haya
+hayas
+hayamos
+hayáis
+hayan
+habré
+habrás
+habrá
+habremos
+habréis
+habrán
+habría
+habrías
+habríamos
+habríais
+habrían
+había
+habías
+habíamos
+habíais
+habían
+hube
+hubiste
+hubo
+hubimos
+hubisteis
+hubieron
+hubiera
+hubieras
+hubiéramos
+hubierais
+hubieran
+hubiese
+hubieses
+hubiésemos
+hubieseis
+hubiesen
+habiendo
+habido
+habida
+habidos
+habidas
+soy
+eres
+es
+somos
+sois
+son
+sea
+seas
+seamos
+seáis
+sean
+seré
+serás
+será
+seremos
+seréis
+serán
+sería
+serías
+seríamos
+seríais
+serían
+era
+eras
+éramos
+erais
+eran
+fui
+fuiste
+fue
+fuimos
+fuisteis
+fueron
+fuera
+fueras
+fuéramos
+fuerais
+fueran
+fuese
+fueses
+fuésemos
+fueseis
+fuesen
+sintiendo
+sentido
+sentida
+sentidos
+sentidas
+siente
+sentid
+tengo
+tienes
+tiene
+tenemos
+tenéis
+tienen
+tenga
+tengas
+tengamos
+tengáis
+tengan
+tendré
+tendrás
+tendrá
+tendremos
+tendréis
+tendrán
+tendría
+tendrías
+tendríamos
+tendríais
+tendrían
+tenía
+tenías
+teníamos
+teníais
+tenían
+tuve
+tuviste
+tuvo
+tuvimos
+tuvisteis
+tuvieron
+tuviera
+tuvieras
+tuviéramos
+tuvierais
+tuvieran
+tuviese
+tuvieses
+tuviésemos
+tuvieseis
+tuviesen
+teniendo
+tenido
+tenida
+tenidos
+tenidas
+tened
diff --git a/src/backend/snowball/stopwords/swedish.stop b/src/backend/snowball/stopwords/swedish.stop
new file mode 100644
index 00000000000..742bb6263b9
--- /dev/null
+++ b/src/backend/snowball/stopwords/swedish.stop
@@ -0,0 +1,114 @@
+och
+det
+att
+i
+en
+jag
+hon
+som
+han
+på
+den
+med
+var
+sig
+för
+så
+till
+är
+men
+ett
+om
+hade
+de
+av
+icke
+mig
+du
+henne
+då
+sin
+nu
+har
+inte
+hans
+honom
+skulle
+hennes
+där
+min
+man
+ej
+vid
+kunde
+något
+från
+ut
+när
+efter
+upp
+vi
+dem
+vara
+vad
+över
+än
+dig
+kan
+sina
+här
+ha
+mot
+alla
+under
+någon
+eller
+allt
+mycket
+sedan
+ju
+denna
+själv
+detta
+åt
+utan
+varit
+hur
+ingen
+mitt
+ni
+bli
+blev
+oss
+din
+dessa
+några
+deras
+blir
+mina
+samma
+vilken
+er
+sådan
+vår
+blivit
+dess
+inom
+mellan
+sådant
+varför
+varje
+vilka
+ditt
+vem
+vilket
+sitta
+sådana
+vart
+dina
+vars
+vårt
+våra
+ert
+era
+vilkas
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 77e40674df9..c38647db322 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.284 2007/07/17 05:02:02 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.285 2007/08/21 01:11:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -355,6 +355,8 @@ check_xact_readonly(Node *parsetree)
case T_TruncateStmt:
case T_DropOwnedStmt:
case T_ReassignOwnedStmt:
+ case T_AlterTSDictionaryStmt:
+ case T_AlterTSConfigurationStmt:
ereport(ERROR,
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
errmsg("transaction is read-only")));
@@ -661,6 +663,26 @@ ProcessUtility(Node *parsetree,
stmt->missing_ok);
break;
+ case OBJECT_TSPARSER:
+ RemoveTSParser(names, stmt->behavior,
+ stmt->missing_ok);
+ break;
+
+ case OBJECT_TSDICTIONARY:
+ RemoveTSDictionary(names, stmt->behavior,
+ stmt->missing_ok);
+ break;
+
+ case OBJECT_TSTEMPLATE:
+ RemoveTSTemplate(names, stmt->behavior,
+ stmt->missing_ok);
+ break;
+
+ case OBJECT_TSCONFIGURATION:
+ RemoveTSConfiguration(names, stmt->behavior,
+ stmt->missing_ok);
+ break;
+
default:
elog(ERROR, "unrecognized drop object type: %d",
(int) stmt->removeType);
@@ -832,6 +854,22 @@ ProcessUtility(Node *parsetree,
Assert(stmt->args == NIL);
DefineType(stmt->defnames, stmt->definition);
break;
+ case OBJECT_TSPARSER:
+ Assert(stmt->args == NIL);
+ DefineTSParser(stmt->defnames, stmt->definition);
+ break;
+ case OBJECT_TSDICTIONARY:
+ Assert(stmt->args == NIL);
+ DefineTSDictionary(stmt->defnames, stmt->definition);
+ break;
+ case OBJECT_TSTEMPLATE:
+ Assert(stmt->args == NIL);
+ DefineTSTemplate(stmt->defnames, stmt->definition);
+ break;
+ case OBJECT_TSCONFIGURATION:
+ Assert(stmt->args == NIL);
+ DefineTSConfiguration(stmt->defnames, stmt->definition);
+ break;
default:
elog(ERROR, "unrecognized define stmt type: %d",
(int) stmt->kind);
@@ -1221,6 +1259,14 @@ ProcessUtility(Node *parsetree,
RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
break;
+ case T_AlterTSDictionaryStmt:
+ AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
+ break;
+
+ case T_AlterTSConfigurationStmt:
+ AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
+ break;
+
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(parsetree));
@@ -1525,6 +1571,18 @@ CreateCommandTag(Node *parsetree)
case OBJECT_SCHEMA:
tag = "DROP SCHEMA";
break;
+ case OBJECT_TSPARSER:
+ tag = "DROP TEXT SEARCH PARSER";
+ break;
+ case OBJECT_TSDICTIONARY:
+ tag = "DROP TEXT SEARCH DICTIONARY";
+ break;
+ case OBJECT_TSTEMPLATE:
+ tag = "DROP TEXT SEARCH TEMPLATE";
+ break;
+ case OBJECT_TSCONFIGURATION:
+ tag = "DROP TEXT SEARCH CONFIGURATION";
+ break;
default:
tag = "???";
}
@@ -1591,6 +1649,18 @@ CreateCommandTag(Node *parsetree)
case OBJECT_VIEW:
tag = "ALTER VIEW";
break;
+ case OBJECT_TSPARSER:
+ tag = "ALTER TEXT SEARCH PARSER";
+ break;
+ case OBJECT_TSDICTIONARY:
+ tag = "ALTER TEXT SEARCH DICTIONARY";
+ break;
+ case OBJECT_TSTEMPLATE:
+ tag = "ALTER TEXT SEARCH TEMPLATE";
+ break;
+ case OBJECT_TSCONFIGURATION:
+ tag = "ALTER TEXT SEARCH CONFIGURATION";
+ break;
default:
tag = "???";
break;
@@ -1618,6 +1688,18 @@ CreateCommandTag(Node *parsetree)
case OBJECT_TYPE:
tag = "ALTER TYPE";
break;
+ case OBJECT_TSPARSER:
+ tag = "ALTER TEXT SEARCH PARSER";
+ break;
+ case OBJECT_TSDICTIONARY:
+ tag = "ALTER TEXT SEARCH DICTIONARY";
+ break;
+ case OBJECT_TSTEMPLATE:
+ tag = "ALTER TEXT SEARCH TEMPLATE";
+ break;
+ case OBJECT_TSCONFIGURATION:
+ tag = "ALTER TEXT SEARCH CONFIGURATION";
+ break;
default:
tag = "???";
break;
@@ -1663,6 +1745,12 @@ CreateCommandTag(Node *parsetree)
case OBJECT_TYPE:
tag = "ALTER TYPE";
break;
+ case OBJECT_TSCONFIGURATION:
+ tag = "ALTER TEXT SEARCH CONFIGURATION";
+ break;
+ case OBJECT_TSDICTIONARY:
+ tag = "ALTER TEXT SEARCH DICTIONARY";
+ break;
default:
tag = "???";
break;
@@ -1722,6 +1810,18 @@ CreateCommandTag(Node *parsetree)
case OBJECT_TYPE:
tag = "CREATE TYPE";
break;
+ case OBJECT_TSPARSER:
+ tag = "CREATE TEXT SEARCH PARSER";
+ break;
+ case OBJECT_TSDICTIONARY:
+ tag = "CREATE TEXT SEARCH DICTIONARY";
+ break;
+ case OBJECT_TSTEMPLATE:
+ tag = "CREATE TEXT SEARCH TEMPLATE";
+ break;
+ case OBJECT_TSCONFIGURATION:
+ tag = "CREATE TEXT SEARCH CONFIGURATION";
+ break;
default:
tag = "???";
}
@@ -1949,6 +2049,14 @@ CreateCommandTag(Node *parsetree)
tag = "DROP OPERATOR FAMILY";
break;
+ case T_AlterTSDictionaryStmt:
+ tag = "ALTER TEXT SEARCH DICTIONARY";
+ break;
+
+ case T_AlterTSConfigurationStmt:
+ tag = "ALTER TEXT SEARCH CONFIGURATION";
+ break;
+
case T_PrepareStmt:
tag = "PREPARE";
break;
@@ -2386,6 +2494,14 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
+ case T_AlterTSDictionaryStmt:
+ lev = LOGSTMT_DDL;
+ break;
+
+ case T_AlterTSConfigurationStmt:
+ lev = LOGSTMT_DDL;
+ break;
+
case T_PrepareStmt:
{
PrepareStmt *stmt = (PrepareStmt *) parsetree;
diff --git a/src/backend/tsearch/Makefile b/src/backend/tsearch/Makefile
new file mode 100644
index 00000000000..30bd13fa116
--- /dev/null
+++ b/src/backend/tsearch/Makefile
@@ -0,0 +1,51 @@
+#-------------------------------------------------------------------------
+#
+# Makefile for backend/tsearch
+#
+# Copyright (c) 2006-2007, PostgreSQL Global Development Group
+#
+# $PostgreSQL: pgsql/src/backend/tsearch/Makefile,v 1.1 2007/08/21 01:11:18 tgl Exp $
+#
+#-------------------------------------------------------------------------
+subdir = src/backend/tsearch
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+DICTDIR=tsearch_data
+
+DICTFILES=synonym.syn.sample thesaurus.ths.sample
+
+OBJS = ts_locale.o ts_parse.o wparser.o wparser_def.o dict.o \
+ dict_simple.o dict_synonym.o dict_thesaurus.o \
+ dict_ispell.o regis.o spell.o \
+ to_tsany.o ts_utils.o
+
+all: SUBSYS.o
+
+SUBSYS.o: $(OBJS)
+ $(LD) $(LDREL) $(LDOUT) SUBSYS.o $^
+
+depend dep:
+ $(CC) -MM $(CFLAGS) *.c >depend
+
+.PHONY: install-data
+install-data: $(DICTFILES) installdirs
+ for i in $(DICTFILES); \
+ do $(INSTALL_DATA) $$i '$(DESTDIR)$(datadir)/$(DICTDIR)/'$$i; \
+ done
+
+installdirs:
+ $(mkinstalldirs) '$(DESTDIR)$(datadir)' '$(DESTDIR)$(datadir)/$(DICTDIR)'
+
+.PHONY: uninstall-data
+uninstall-data:
+ for i in $(DICTFILES); \
+ do rm -rf '$(DESTDIR)$(datadir)/$(DICTDIR)/'$$i ; \
+ done
+
+clean distclean maintainer-clean:
+ rm -f SUBSYS.o $(OBJS)
+
+ifeq (depend,$(wildcard depend))
+include depend
+endif
diff --git a/src/backend/tsearch/dict.c b/src/backend/tsearch/dict.c
new file mode 100644
index 00000000000..15deb71af62
--- /dev/null
+++ b/src/backend/tsearch/dict.c
@@ -0,0 +1,131 @@
+/*-------------------------------------------------------------------------
+ *
+ * dict.c
+ * Standard interface to dictionary
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/dict.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "funcapi.h"
+#include "access/genam.h"
+#include "access/heapam.h"
+#include "access/skey.h"
+#include "catalog/indexing.h"
+#include "catalog/namespace.h"
+#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_type.h"
+#include "tsearch/ts_cache.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/array.h"
+#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/rel.h"
+#include "utils/syscache.h"
+
+
+/*
+ * Lexize one word by dictionary, mostly debug function
+ */
+static ArrayType *
+ts_lexize_workhorse(Oid dictId, text *in)
+{
+ TSDictionaryCacheEntry *dict;
+ TSLexeme *res,
+ *ptr;
+ Datum *da;
+ ArrayType *a;
+ DictSubState dstate = {false, false, NULL};
+
+ dict = lookup_ts_dictionary_cache(dictId);
+
+ res = (TSLexeme *) DatumGetPointer(FunctionCall4(&dict->lexize,
+ PointerGetDatum(dict->dictData),
+ PointerGetDatum(VARDATA(in)),
+ Int32GetDatum(VARSIZE(in) - VARHDRSZ),
+ PointerGetDatum(&dstate)));
+
+ if (dstate.getnext)
+ {
+ dstate.isend = true;
+ ptr = (TSLexeme *) DatumGetPointer(FunctionCall4(&dict->lexize,
+ PointerGetDatum(dict->dictData),
+ PointerGetDatum(VARDATA(in)),
+ Int32GetDatum(VARSIZE(in) - VARHDRSZ),
+ PointerGetDatum(&dstate)));
+ if (ptr != NULL)
+ res = ptr;
+ }
+
+ if (!res)
+ return NULL;
+
+ ptr = res;
+ while (ptr->lexeme)
+ ptr++;
+ da = (Datum *) palloc(sizeof(Datum) * (ptr - res + 1));
+ ptr = res;
+ while (ptr->lexeme)
+ {
+ da[ptr - res] = DirectFunctionCall1(textin, CStringGetDatum(ptr->lexeme));
+ ptr++;
+ }
+
+ a = construct_array(da,
+ ptr - res,
+ TEXTOID,
+ -1,
+ false,
+ 'i');
+
+ ptr = res;
+ while (ptr->lexeme)
+ {
+ pfree(DatumGetPointer(da[ptr - res]));
+ pfree(ptr->lexeme);
+ ptr++;
+ }
+ pfree(res);
+ pfree(da);
+
+ return a;
+}
+
+Datum
+ts_lexize_byid(PG_FUNCTION_ARGS)
+{
+ Oid dictId = PG_GETARG_OID(0);
+ text *in = PG_GETARG_TEXT_P(1);
+ ArrayType *a;
+
+ a = ts_lexize_workhorse(dictId, in);
+
+ if (a)
+ PG_RETURN_POINTER(a);
+ else
+ PG_RETURN_NULL();
+}
+
+Datum
+ts_lexize_byname(PG_FUNCTION_ARGS)
+{
+ text *dictname = PG_GETARG_TEXT_P(0);
+ text *in = PG_GETARG_TEXT_P(1);
+ Oid dictId;
+ ArrayType *a;
+
+ dictId = TSDictionaryGetDictid(textToQualifiedNameList(dictname), false);
+ a = ts_lexize_workhorse(dictId, in);
+
+ if (a)
+ PG_RETURN_POINTER(a);
+ else
+ PG_RETURN_NULL();
+}
diff --git a/src/backend/tsearch/dict_ispell.c b/src/backend/tsearch/dict_ispell.c
new file mode 100644
index 00000000000..f7cee107300
--- /dev/null
+++ b/src/backend/tsearch/dict_ispell.c
@@ -0,0 +1,164 @@
+/*-------------------------------------------------------------------------
+ *
+ * dict_ispell.c
+ * Ispell dictionary interface
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/dict_ispell.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "tsearch/dicts/spell.h"
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+#include "utils/memutils.h"
+
+
+typedef struct
+{
+ StopList stoplist;
+ IspellDict obj;
+} DictISpell;
+
+Datum
+dispell_init(PG_FUNCTION_ARGS)
+{
+ DictISpell *d;
+ Map *cfg,
+ *pcfg;
+ bool affloaded = false,
+ dictloaded = false,
+ stoploaded = false;
+ text *in;
+
+ /* init functions must defend against NULLs for themselves */
+ if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("NULL config not allowed for ISpell")));
+ in = PG_GETARG_TEXT_P(0);
+
+ parse_keyvalpairs(in, &cfg);
+ PG_FREE_IF_COPY(in, 0);
+
+ d = (DictISpell *) palloc0(sizeof(DictISpell));
+ d->stoplist.wordop = recode_and_lowerstr;
+
+ pcfg = cfg;
+ while (pcfg->key)
+ {
+ if (pg_strcasecmp("DictFile", pcfg->key) == 0)
+ {
+ if (dictloaded)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("multiple DictFile parameters")));
+ NIImportDictionary(&(d->obj),
+ get_tsearch_config_filename(pcfg->value,
+ "dict"));
+ dictloaded = true;
+ }
+ else if (pg_strcasecmp("AffFile", pcfg->key) == 0)
+ {
+ if (affloaded)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("multiple AffFile parameters")));
+ NIImportAffixes(&(d->obj),
+ get_tsearch_config_filename(pcfg->value,
+ "affix"));
+ affloaded = true;
+ }
+ else if (pg_strcasecmp("StopWords", pcfg->key) == 0)
+ {
+ if (stoploaded)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("multiple StopWords parameters")));
+ readstoplist(pcfg->value, &(d->stoplist));
+ sortstoplist(&(d->stoplist));
+ stoploaded = true;
+ }
+ else
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized ISpell parameter: \"%s\"",
+ pcfg->key)));
+ }
+ pfree(pcfg->key);
+ pfree(pcfg->value);
+ pcfg++;
+ }
+ pfree(cfg);
+
+ if (affloaded && dictloaded)
+ {
+ NISortDictionary(&(d->obj));
+ NISortAffixes(&(d->obj));
+ }
+ else if (!affloaded)
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("missing AffFile parameter")));
+ }
+ else
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("missing DictFile parameter")));
+ }
+
+ MemoryContextDeleteChildren(CurrentMemoryContext);
+
+ PG_RETURN_POINTER(d);
+}
+
+Datum
+dispell_lexize(PG_FUNCTION_ARGS)
+{
+ DictISpell *d = (DictISpell *) PG_GETARG_POINTER(0);
+ char *in = (char *) PG_GETARG_POINTER(1);
+ int32 len = PG_GETARG_INT32(2);
+ char *txt;
+ TSLexeme *res;
+ TSLexeme *ptr,
+ *cptr;
+
+ if (len <= 0)
+ PG_RETURN_POINTER(NULL);
+
+ txt = lowerstr_with_len(in, len);
+ res = NINormalizeWord(&(d->obj), txt);
+
+ if (res == NULL)
+ PG_RETURN_POINTER(NULL);
+
+ ptr = cptr = res;
+ while (ptr->lexeme)
+ {
+ if (searchstoplist(&(d->stoplist), ptr->lexeme))
+ {
+ pfree(ptr->lexeme);
+ ptr->lexeme = NULL;
+ ptr++;
+ }
+ else
+ {
+ memcpy(cptr, ptr, sizeof(TSLexeme));
+ cptr++;
+ ptr++;
+ }
+ }
+ cptr->lexeme = NULL;
+
+ PG_RETURN_POINTER(res);
+}
diff --git a/src/backend/tsearch/dict_simple.c b/src/backend/tsearch/dict_simple.c
new file mode 100644
index 00000000000..2c1bc3d017e
--- /dev/null
+++ b/src/backend/tsearch/dict_simple.c
@@ -0,0 +1,65 @@
+/*-------------------------------------------------------------------------
+ *
+ * dict_simple.c
+ * Simple dictionary: just lowercase and check for stopword
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/dict_simple.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+
+
+typedef struct
+{
+ StopList stoplist;
+} DictExample;
+
+
+Datum
+dsimple_init(PG_FUNCTION_ARGS)
+{
+ DictExample *d = (DictExample *) palloc0(sizeof(DictExample));
+
+ d->stoplist.wordop = recode_and_lowerstr;
+
+ if (!PG_ARGISNULL(0) && PG_GETARG_POINTER(0) != NULL)
+ {
+ text *in = PG_GETARG_TEXT_P(0);
+ char *filename = TextPGetCString(in);
+
+ readstoplist(filename, &d->stoplist);
+ sortstoplist(&d->stoplist);
+ pfree(filename);
+ }
+
+ PG_RETURN_POINTER(d);
+}
+
+Datum
+dsimple_lexize(PG_FUNCTION_ARGS)
+{
+ DictExample *d = (DictExample *) PG_GETARG_POINTER(0);
+ char *in = (char *) PG_GETARG_POINTER(1);
+ int32 len = PG_GETARG_INT32(2);
+ char *txt = lowerstr_with_len(in, len);
+ TSLexeme *res = palloc0(sizeof(TSLexeme) * 2);
+
+ if (*txt == '\0' || searchstoplist(&(d->stoplist), txt))
+ {
+ pfree(txt);
+ }
+ else
+ res[0].lexeme = txt;
+
+ PG_RETURN_POINTER(res);
+}
diff --git a/src/backend/tsearch/dict_synonym.c b/src/backend/tsearch/dict_synonym.c
new file mode 100644
index 00000000000..cffad72b80f
--- /dev/null
+++ b/src/backend/tsearch/dict_synonym.c
@@ -0,0 +1,176 @@
+/*-------------------------------------------------------------------------
+ *
+ * dict_synonym.c
+ * Synonym dictionary: replace word by its synonym
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/dict_synonym.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "storage/fd.h"
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+
+
+#define SYNBUFLEN 4096
+typedef struct
+{
+ char *in;
+ char *out;
+} Syn;
+
+typedef struct
+{
+ int len;
+ Syn *syn;
+} DictSyn;
+
+static char *
+findwrd(char *in, char **end)
+{
+ char *start;
+
+ *end = NULL;
+ while (*in && t_isspace(in))
+ in += pg_mblen(in);
+
+ if (*in == '\0')
+ return NULL;
+ start = in;
+
+ while (*in && !t_isspace(in))
+ in += pg_mblen(in);
+
+ *end = in;
+ return start;
+}
+
+static int
+compareSyn(const void *a, const void *b)
+{
+ return strcmp(((Syn *) a)->in, ((Syn *) b)->in);
+}
+
+
+Datum
+dsynonym_init(PG_FUNCTION_ARGS)
+{
+ text *in;
+ DictSyn *d;
+ int cur = 0;
+ FILE *fin;
+ char *filename;
+ char buf[SYNBUFLEN];
+ char *starti,
+ *starto,
+ *end = NULL;
+ int slen;
+
+ /* init functions must defend against NULLs for themselves */
+ if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("NULL config not allowed for Synonym")));
+ in = PG_GETARG_TEXT_P(0);
+
+ filename = get_tsearch_config_filename(TextPGetCString(in), "syn");
+
+ PG_FREE_IF_COPY(in, 0);
+
+ if ((fin = AllocateFile(filename, "r")) == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("could not open synonym file \"%s\": %m",
+ filename)));
+
+ d = (DictSyn *) palloc0(sizeof(DictSyn));
+
+ while (fgets(buf, SYNBUFLEN, fin))
+ {
+ slen = strlen(buf);
+ pg_verifymbstr(buf, slen, false);
+ if (cur == d->len)
+ {
+ if (d->len == 0)
+ {
+ d->len = 16;
+ d->syn = (Syn *) palloc(sizeof(Syn) * d->len);
+ }
+ else
+ {
+ d->len *= 2;
+ d->syn = (Syn *) repalloc(d->syn, sizeof(Syn) * d->len);
+ }
+ }
+
+ starti = findwrd(buf, &end);
+ if (!starti)
+ continue;
+ *end = '\0';
+ if (end >= buf + slen)
+ continue;
+
+ starto = findwrd(end + 1, &end);
+ if (!starto)
+ continue;
+ *end = '\0';
+
+ d->syn[cur].in = recode_and_lowerstr(starti);
+ d->syn[cur].out = recode_and_lowerstr(starto);
+ if (!(d->syn[cur].in && d->syn[cur].out))
+ {
+ FreeFile(fin);
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+ }
+
+ cur++;
+ }
+
+ FreeFile(fin);
+
+ d->len = cur;
+ if (cur > 1)
+ qsort(d->syn, d->len, sizeof(Syn), compareSyn);
+
+ pfree(filename);
+ PG_RETURN_POINTER(d);
+}
+
+Datum
+dsynonym_lexize(PG_FUNCTION_ARGS)
+{
+ DictSyn *d = (DictSyn *) PG_GETARG_POINTER(0);
+ char *in = (char *) PG_GETARG_POINTER(1);
+ int32 len = PG_GETARG_INT32(2);
+ Syn key,
+ *found;
+ TSLexeme *res;
+
+ if (len <= 0)
+ PG_RETURN_POINTER(NULL);
+
+ key.in = lowerstr_with_len(in, len);
+ key.out = NULL;
+
+ found = (Syn *) bsearch(&key, d->syn, d->len, sizeof(Syn), compareSyn);
+ pfree(key.in);
+
+ if (!found)
+ PG_RETURN_POINTER(NULL);
+
+ res = palloc(sizeof(TSLexeme) * 2);
+ memset(res, 0, sizeof(TSLexeme) * 2);
+ res[0].lexeme = pstrdup(found->out);
+
+ PG_RETURN_POINTER(res);
+}
diff --git a/src/backend/tsearch/dict_thesaurus.c b/src/backend/tsearch/dict_thesaurus.c
new file mode 100644
index 00000000000..8c544ad4f8a
--- /dev/null
+++ b/src/backend/tsearch/dict_thesaurus.c
@@ -0,0 +1,887 @@
+/*-------------------------------------------------------------------------
+ *
+ * dict_thesaurus.c
+ * Thesaurus dictionary: phrase to phrase substitution
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/dict_thesaurus.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "catalog/namespace.h"
+#include "storage/fd.h"
+#include "tsearch/ts_cache.h"
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+
+
+/*
+ * Temporay we use TSLexeme.flags for inner use...
+ */
+#define DT_USEASIS 0x1000
+
+typedef struct LexemeInfo
+{
+ uint16 idsubst; /* entry's number in DictThesaurus->subst */
+ uint16 posinsubst; /* pos info in entry */
+ uint16 tnvariant; /* total num lexemes in one variant */
+ struct LexemeInfo *nextentry;
+ struct LexemeInfo *nextvariant;
+} LexemeInfo;
+
+typedef struct
+{
+ char *lexeme;
+ LexemeInfo *entries;
+} TheLexeme;
+
+typedef struct
+{
+ uint16 lastlexeme; /* number lexemes to substitute */
+ uint16 reslen;
+ TSLexeme *res; /* prepared substituted result */
+} TheSubstitute;
+
+typedef struct
+{
+ /* subdictionary to normalize lexemes */
+ Oid subdictOid;
+ TSDictionaryCacheEntry *subdict;
+
+ /* Array to search lexeme by exact match */
+ TheLexeme *wrds;
+ int nwrds;
+ int ntwrds;
+
+ /*
+ * Storage of substituted result, n-th element is for n-th expression
+ */
+ TheSubstitute *subst;
+ int nsubst;
+} DictThesaurus;
+
+
+static void
+newLexeme(DictThesaurus * d, char *b, char *e, uint16 idsubst, uint16 posinsubst)
+{
+ TheLexeme *ptr;
+
+ if (d->nwrds >= d->ntwrds)
+ {
+ if (d->ntwrds == 0)
+ {
+ d->ntwrds = 16;
+ d->wrds = (TheLexeme *) palloc(sizeof(TheLexeme) * d->ntwrds);
+ }
+ else
+ {
+ d->ntwrds *= 2;
+ d->wrds = (TheLexeme *) repalloc(d->wrds, sizeof(TheLexeme) * d->ntwrds);
+ }
+ }
+
+ ptr = d->wrds + d->nwrds;
+ d->nwrds++;
+
+ ptr->lexeme = palloc(e - b + 1);
+
+ memcpy(ptr->lexeme, b, e - b);
+ ptr->lexeme[e - b] = '\0';
+
+ ptr->entries = (LexemeInfo *) palloc(sizeof(LexemeInfo));
+
+ ptr->entries->nextentry = NULL;
+ ptr->entries->idsubst = idsubst;
+ ptr->entries->posinsubst = posinsubst;
+}
+
+static void
+addWrd(DictThesaurus * d, char *b, char *e, uint16 idsubst, uint16 nwrd, uint16 posinsubst, bool useasis)
+{
+ static int nres = 0;
+ static int ntres = 0;
+ TheSubstitute *ptr;
+
+ if (nwrd == 0)
+ {
+ nres = ntres = 0;
+
+ if (idsubst >= d->nsubst)
+ {
+ if (d->nsubst == 0)
+ {
+ d->nsubst = 16;
+ d->subst = (TheSubstitute *) palloc(sizeof(TheSubstitute) * d->nsubst);
+ }
+ else
+ {
+ d->nsubst *= 2;
+ d->subst = (TheSubstitute *) repalloc(d->subst, sizeof(TheSubstitute) * d->nsubst);
+ }
+ }
+ }
+
+ ptr = d->subst + idsubst;
+
+ ptr->lastlexeme = posinsubst - 1;
+
+ if (nres + 1 >= ntres)
+ {
+ if (ntres == 0)
+ {
+ ntres = 2;
+ ptr->res = (TSLexeme *) palloc(sizeof(TSLexeme) * ntres);
+ }
+ else
+ {
+ ntres *= 2;
+ ptr->res = (TSLexeme *) repalloc(ptr->res, sizeof(TSLexeme) * ntres);
+ }
+
+ }
+
+ ptr->res[nres].lexeme = palloc(e - b + 1);
+ memcpy(ptr->res[nres].lexeme, b, e - b);
+ ptr->res[nres].lexeme[e - b] = '\0';
+
+ ptr->res[nres].nvariant = nwrd;
+ if (useasis)
+ ptr->res[nres].flags = DT_USEASIS;
+ else
+ ptr->res[nres].flags = 0;
+
+ ptr->res[++nres].lexeme = NULL;
+}
+
+#define TR_WAITLEX 1
+#define TR_INLEX 2
+#define TR_WAITSUBS 3
+#define TR_INSUBS 4
+
+static void
+thesaurusRead(char *filename, DictThesaurus * d)
+{
+ FILE *fh;
+ char str[BUFSIZ];
+ int lineno = 0;
+ uint16 idsubst = 0;
+ bool useasis = false;
+
+ filename = get_tsearch_config_filename(filename, "ths");
+ fh = AllocateFile(filename, "r");
+ if (!fh)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("could not open thesaurus file \"%s\": %m",
+ filename)));
+
+ while (fgets(str, sizeof(str), fh))
+ {
+ char *ptr,
+ *recoded;
+ int state = TR_WAITLEX;
+ char *beginwrd = NULL;
+ uint16 posinsubst = 0;
+ uint16 nwrd = 0;
+
+ ptr = recoded = (char *) pg_do_encoding_conversion((unsigned char *) str, strlen(str),
+ GetDatabaseEncoding(), PG_UTF8);
+ if (recoded == NULL)
+ elog(ERROR, "encoding conversion failed");
+
+ lineno++;
+
+ /* is it comment ? */
+ while (t_isspace(ptr))
+ ptr += pg_mblen(ptr);
+ if (t_iseq(recoded, '#') || *recoded == '\0' || t_iseq(recoded, '\n') || t_iseq(recoded, '\r'))
+ continue;
+
+ while (*ptr)
+ {
+ if (state == TR_WAITLEX)
+ {
+ if (t_iseq(ptr, ':'))
+ {
+ if (posinsubst == 0)
+ {
+ FreeFile(fh);
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("unexpected delimiter at line %d of thesaurus file \"%s\"",
+ lineno, filename)));
+ }
+ state = TR_WAITSUBS;
+ }
+ else if (!t_isspace(ptr))
+ {
+ beginwrd = ptr;
+ state = TR_INLEX;
+ }
+ }
+ else if (state == TR_INLEX)
+ {
+ if (t_iseq(ptr, ':'))
+ {
+ newLexeme(d, beginwrd, ptr, idsubst, posinsubst++);
+ state = TR_WAITSUBS;
+ }
+ else if (t_isspace(ptr))
+ {
+ newLexeme(d, beginwrd, ptr, idsubst, posinsubst++);
+ state = TR_WAITLEX;
+ }
+ }
+ else if (state == TR_WAITSUBS)
+ {
+ if (t_iseq(ptr, '*'))
+ {
+ useasis = true;
+ state = TR_INSUBS;
+ beginwrd = ptr + pg_mblen(ptr);
+ }
+ else if (t_iseq(ptr, '\\'))
+ {
+ useasis = false;
+ state = TR_INSUBS;
+ beginwrd = ptr + pg_mblen(ptr);
+ }
+ else if (!t_isspace(ptr))
+ {
+ useasis = false;
+ beginwrd = ptr;
+ state = TR_INSUBS;
+ }
+ }
+ else if (state == TR_INSUBS)
+ {
+ if (t_isspace(ptr))
+ {
+ if (ptr == beginwrd)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("unexpected end of line or lexeme at line %d of thesaurus file \"%s\"",
+ lineno, filename)));
+ addWrd(d, beginwrd, ptr, idsubst, nwrd++, posinsubst, useasis);
+ state = TR_WAITSUBS;
+ }
+ }
+ else
+ elog(ERROR, "unrecognized thesaurus state: %d", state);
+
+ ptr += pg_mblen(ptr);
+ }
+
+ if (state == TR_INSUBS)
+ {
+ if (ptr == beginwrd)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("unexpected end of line or lexeme at line %d of thesaurus file \"%s\"",
+ lineno, filename)));
+ addWrd(d, beginwrd, ptr, idsubst, nwrd++, posinsubst, useasis);
+ }
+
+ idsubst++;
+
+ if (!(nwrd && posinsubst))
+ {
+ FreeFile(fh);
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("unexpected end of line at line %d of thesaurus file \"%s\"",
+ lineno, filename)));
+ }
+
+ if (recoded != str)
+ pfree(recoded);
+ }
+
+ d->nsubst = idsubst;
+
+ FreeFile(fh);
+}
+
+static TheLexeme *
+addCompiledLexeme(TheLexeme * newwrds, int *nnw, int *tnm, TSLexeme * lexeme, LexemeInfo * src, uint16 tnvariant)
+{
+
+ if (*nnw >= *tnm)
+ {
+ *tnm *= 2;
+ newwrds = (TheLexeme *) repalloc(newwrds, sizeof(TheLexeme) * *tnm);
+ }
+
+ newwrds[*nnw].entries = (LexemeInfo *) palloc(sizeof(LexemeInfo));
+
+ if (lexeme && lexeme->lexeme)
+ {
+ newwrds[*nnw].lexeme = pstrdup(lexeme->lexeme);
+ newwrds[*nnw].entries->tnvariant = tnvariant;
+ }
+ else
+ {
+ newwrds[*nnw].lexeme = NULL;
+ newwrds[*nnw].entries->tnvariant = 1;
+ }
+
+ newwrds[*nnw].entries->idsubst = src->idsubst;
+ newwrds[*nnw].entries->posinsubst = src->posinsubst;
+
+ newwrds[*nnw].entries->nextentry = NULL;
+
+ (*nnw)++;
+ return newwrds;
+}
+
+static int
+cmpLexemeInfo(LexemeInfo * a, LexemeInfo * b)
+{
+ if (a == NULL || b == NULL)
+ return 0;
+
+ if (a->idsubst == b->idsubst)
+ {
+ if (a->posinsubst == b->posinsubst)
+ {
+ if (a->tnvariant == b->tnvariant)
+ return 0;
+
+ return (a->tnvariant > b->tnvariant) ? 1 : -1;
+ }
+
+ return (a->posinsubst > b->posinsubst) ? 1 : -1;
+ }
+
+ return (a->idsubst > b->idsubst) ? 1 : -1;
+}
+
+static int
+cmpLexeme(TheLexeme * a, TheLexeme * b)
+{
+ if (a->lexeme == NULL)
+ {
+ if (b->lexeme == NULL)
+ return 0;
+ else
+ return 1;
+ }
+ else if (b->lexeme == NULL)
+ return -1;
+
+ return strcmp(a->lexeme, b->lexeme);
+}
+
+static int
+cmpLexemeQ(const void *a, const void *b)
+{
+ return cmpLexeme((TheLexeme *) a, (TheLexeme *) b);
+}
+
+static int
+cmpTheLexeme(const void *a, const void *b)
+{
+ TheLexeme *la = (TheLexeme *) a;
+ TheLexeme *lb = (TheLexeme *) b;
+ int res;
+
+ if ((res = cmpLexeme(la, lb)) != 0)
+ return res;
+
+ return -cmpLexemeInfo(la->entries, lb->entries);
+}
+
+static void
+compileTheLexeme(DictThesaurus * d)
+{
+ int i,
+ nnw = 0,
+ tnm = 16;
+ TheLexeme *newwrds = (TheLexeme *) palloc(sizeof(TheLexeme) * tnm),
+ *ptrwrds;
+
+ for (i = 0; i < d->nwrds; i++)
+ {
+ TSLexeme *ptr;
+
+ ptr = (TSLexeme *) DatumGetPointer(FunctionCall4(&(d->subdict->lexize),
+ PointerGetDatum(d->subdict->dictData),
+ PointerGetDatum(d->wrds[i].lexeme),
+ Int32GetDatum(strlen(d->wrds[i].lexeme)),
+ PointerGetDatum(NULL)));
+
+ if (!(ptr && ptr->lexeme))
+ {
+ if (!ptr)
+ elog(ERROR, "thesaurus word-sample \"%s\" isn't recognized by subdictionary (rule %d)",
+ d->wrds[i].lexeme, d->wrds[i].entries->idsubst + 1);
+ else
+ elog(NOTICE, "thesaurus word-sample \"%s\" is recognized as stop-word, assign any stop-word (rule %d)",
+ d->wrds[i].lexeme, d->wrds[i].entries->idsubst + 1);
+
+ newwrds = addCompiledLexeme(newwrds, &nnw, &tnm, NULL, d->wrds[i].entries, 0);
+ }
+ else
+ {
+ while (ptr->lexeme)
+ {
+ TSLexeme *remptr = ptr + 1;
+ int tnvar = 1;
+ int curvar = ptr->nvariant;
+
+ /* compute n words in one variant */
+ while (remptr->lexeme)
+ {
+ if (remptr->nvariant != (remptr - 1)->nvariant)
+ break;
+ tnvar++;
+ remptr++;
+ }
+
+ remptr = ptr;
+ while (remptr->lexeme && remptr->nvariant == curvar)
+ {
+ newwrds = addCompiledLexeme(newwrds, &nnw, &tnm, remptr, d->wrds[i].entries, tnvar);
+ remptr++;
+ }
+
+ ptr = remptr;
+ }
+ }
+
+ pfree(d->wrds[i].lexeme);
+ pfree(d->wrds[i].entries);
+ }
+
+ pfree(d->wrds);
+ d->wrds = newwrds;
+ d->nwrds = nnw;
+ d->ntwrds = tnm;
+
+ if (d->nwrds > 1)
+ {
+ qsort(d->wrds, d->nwrds, sizeof(TheLexeme), cmpTheLexeme);
+
+ /* uniq */
+ newwrds = d->wrds;
+ ptrwrds = d->wrds + 1;
+ while (ptrwrds - d->wrds < d->nwrds)
+ {
+ if (cmpLexeme(ptrwrds, newwrds) == 0)
+ {
+ if (cmpLexemeInfo(ptrwrds->entries, newwrds->entries))
+ {
+ ptrwrds->entries->nextentry = newwrds->entries;
+ newwrds->entries = ptrwrds->entries;
+ }
+ else
+ pfree(ptrwrds->entries);
+
+ if (ptrwrds->lexeme)
+ pfree(ptrwrds->lexeme);
+ }
+ else
+ {
+ newwrds++;
+ *newwrds = *ptrwrds;
+ }
+
+ ptrwrds++;
+ }
+
+ d->nwrds = newwrds - d->wrds + 1;
+ d->wrds = (TheLexeme *) repalloc(d->wrds, sizeof(TheLexeme) * d->nwrds);
+ }
+}
+
+static void
+compileTheSubstitute(DictThesaurus * d)
+{
+ int i;
+
+ for (i = 0; i < d->nsubst; i++)
+ {
+ TSLexeme *rem = d->subst[i].res,
+ *outptr,
+ *inptr;
+ int n = 2;
+
+ outptr = d->subst[i].res = (TSLexeme *) palloc(sizeof(TSLexeme) * n);
+ outptr->lexeme = NULL;
+ inptr = rem;
+
+ while (inptr && inptr->lexeme)
+ {
+ TSLexeme *lexized,
+ tmplex[2];
+
+ if (inptr->flags & DT_USEASIS)
+ { /* do not lexize */
+ tmplex[0] = *inptr;
+ tmplex[0].flags = 0;
+ tmplex[1].lexeme = NULL;
+ lexized = tmplex;
+ }
+ else
+ {
+ lexized = (TSLexeme *) DatumGetPointer(
+ FunctionCall4(
+ &(d->subdict->lexize),
+ PointerGetDatum(d->subdict->dictData),
+ PointerGetDatum(inptr->lexeme),
+ Int32GetDatum(strlen(inptr->lexeme)),
+ PointerGetDatum(NULL)
+ )
+ );
+ }
+
+ if (lexized && lexized->lexeme)
+ {
+ int toset = (lexized->lexeme && outptr != d->subst[i].res) ? (outptr - d->subst[i].res) : -1;
+
+ while (lexized->lexeme)
+ {
+ if (outptr - d->subst[i].res + 1 >= n)
+ {
+ int diff = outptr - d->subst[i].res;
+
+ n *= 2;
+ d->subst[i].res = (TSLexeme *) repalloc(d->subst[i].res, sizeof(TSLexeme) * n);
+ outptr = d->subst[i].res + diff;
+ }
+
+ *outptr = *lexized;
+ outptr->lexeme = pstrdup(lexized->lexeme);
+
+ outptr++;
+ lexized++;
+ }
+
+ if (toset > 0)
+ d->subst[i].res[toset].flags |= TSL_ADDPOS;
+ }
+ else if (lexized)
+ {
+ elog(NOTICE, "thesaurus word \"%s\" in substitution is a stop-word, ignored (rule %d)", inptr->lexeme, i + 1);
+ }
+ else
+ {
+ elog(ERROR, "thesaurus word \"%s\" in substitution isn't recognized (rule %d)", inptr->lexeme, i + 1);
+ }
+
+ if (inptr->lexeme)
+ pfree(inptr->lexeme);
+ inptr++;
+ }
+
+ if (outptr == d->subst[i].res)
+ elog(ERROR, "all words in thesaurus substitution are stop words (rule %d)", i + 1);
+
+ d->subst[i].reslen = outptr - d->subst[i].res;
+
+ pfree(rem);
+ }
+}
+
+Datum
+thesaurus_init(PG_FUNCTION_ARGS)
+{
+ DictThesaurus *d;
+ Map *cfg,
+ *pcfg;
+ text *in;
+ char *subdictname = NULL;
+ bool fileloaded = false;
+
+ /* init functions must defend against NULLs for themselves */
+ if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("NULL config not allowed for Thesaurus")));
+ in = PG_GETARG_TEXT_P(0);
+
+ parse_keyvalpairs(in, &cfg);
+ PG_FREE_IF_COPY(in, 0);
+
+ d = (DictThesaurus *) palloc0(sizeof(DictThesaurus));
+
+ pcfg = cfg;
+ while (pcfg->key)
+ {
+ if (pg_strcasecmp("DictFile", pcfg->key) == 0)
+ {
+ if (fileloaded)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("multiple DictFile parameters")));
+ thesaurusRead(pcfg->value, d);
+ fileloaded = true;
+ }
+ else if (pg_strcasecmp("Dictionary", pcfg->key) == 0)
+ {
+ if (subdictname)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("multiple Dictionary parameters")));
+ subdictname = pstrdup(pcfg->value);
+ }
+ else
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized Thesaurus parameter: \"%s\"",
+ pcfg->key)));
+ }
+ pfree(pcfg->key);
+ pfree(pcfg->value);
+ pcfg++;
+ }
+ pfree(cfg);
+
+ if (!fileloaded)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("missing DictFile parameter")));
+ if (!subdictname)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("missing Dictionary parameter")));
+
+ d->subdictOid = TSDictionaryGetDictid(stringToQualifiedNameList(subdictname), false);
+ d->subdict = lookup_ts_dictionary_cache(d->subdictOid);
+
+ compileTheLexeme(d);
+ compileTheSubstitute(d);
+
+ PG_RETURN_POINTER(d);
+}
+
+static LexemeInfo *
+findTheLexeme(DictThesaurus * d, char *lexeme)
+{
+ TheLexeme key = {lexeme, NULL}, *res;
+
+ if (d->nwrds == 0)
+ return NULL;
+
+ res = bsearch(&key, d->wrds, d->nwrds, sizeof(TheLexeme), cmpLexemeQ);
+
+ if (res == NULL)
+ return NULL;
+ return res->entries;
+}
+
+static bool
+matchIdSubst(LexemeInfo * stored, uint16 idsubst)
+{
+ bool res = true;
+
+ if (stored)
+ {
+ res = false;
+
+ for (; stored; stored = stored->nextvariant)
+ if (stored->idsubst == idsubst)
+ {
+ res = true;
+ break;
+ }
+ }
+
+ return res;
+}
+
+static LexemeInfo *
+findVariant(LexemeInfo * in, LexemeInfo * stored, uint16 curpos, LexemeInfo ** newin, int newn)
+{
+ for (;;)
+ {
+ int i;
+ LexemeInfo *ptr = newin[0];
+
+ for (i = 0; i < newn; i++)
+ {
+ while (newin[i] && newin[i]->idsubst < ptr->idsubst)
+ newin[i] = newin[i]->nextentry;
+
+ if (newin[i] == NULL)
+ return in;
+
+ if (newin[i]->idsubst > ptr->idsubst)
+ {
+ ptr = newin[i];
+ i = -1;
+ continue;
+ }
+
+ while (newin[i]->idsubst == ptr->idsubst)
+ {
+ if (newin[i]->posinsubst == curpos && newin[i]->tnvariant == newn)
+ {
+ ptr = newin[i];
+ break;
+ }
+
+ newin[i] = newin[i]->nextentry;
+ if (newin[i] == NULL)
+ return in;
+ }
+
+ if (newin[i]->idsubst != ptr->idsubst)
+ {
+ ptr = newin[i];
+ i = -1;
+ continue;
+ }
+ }
+
+ if (i == newn && matchIdSubst(stored, ptr->idsubst) && (in == NULL || !matchIdSubst(in, ptr->idsubst)))
+ { /* found */
+
+ ptr->nextvariant = in;
+ in = ptr;
+ }
+
+ /* step forward */
+ for (i = 0; i < newn; i++)
+ newin[i] = newin[i]->nextentry;
+ }
+
+ return NULL;
+}
+
+static TSLexeme *
+copyTSLexeme(TheSubstitute * ts)
+{
+ TSLexeme *res;
+ uint16 i;
+
+ res = (TSLexeme *) palloc(sizeof(TSLexeme) * (ts->reslen + 1));
+ for (i = 0; i < ts->reslen; i++)
+ {
+ res[i] = ts->res[i];
+ res[i].lexeme = pstrdup(ts->res[i].lexeme);
+ }
+
+ res[ts->reslen].lexeme = NULL;
+
+ return res;
+}
+
+static TSLexeme *
+checkMatch(DictThesaurus * d, LexemeInfo * info, uint16 curpos, bool *moreres)
+{
+ *moreres = false;
+ while (info)
+ {
+ Assert(info->idsubst < d->nsubst);
+ if (info->nextvariant)
+ *moreres = true;
+ if (d->subst[info->idsubst].lastlexeme == curpos)
+ return copyTSLexeme(d->subst + info->idsubst);
+ info = info->nextvariant;
+ }
+
+ return NULL;
+}
+
+Datum
+thesaurus_lexize(PG_FUNCTION_ARGS)
+{
+ DictThesaurus *d = (DictThesaurus *) PG_GETARG_POINTER(0);
+ DictSubState *dstate = (DictSubState *) PG_GETARG_POINTER(3);
+ TSLexeme *res = NULL;
+ LexemeInfo *stored,
+ *info = NULL;
+ uint16 curpos = 0;
+ bool moreres = false;
+
+ if (PG_NARGS() < 4 || dstate == NULL)
+ elog(ERROR, "forbidden call of thesaurus or nested call");
+
+ if (dstate->isend)
+ PG_RETURN_POINTER(NULL);
+ stored = (LexemeInfo *) dstate->private;
+
+ if (stored)
+ curpos = stored->posinsubst + 1;
+
+ if (!d->subdict->isvalid)
+ d->subdict = lookup_ts_dictionary_cache(d->subdictOid);
+
+ res = (TSLexeme *) DatumGetPointer(FunctionCall4(&(d->subdict->lexize),
+ PointerGetDatum(d->subdict->dictData),
+ PG_GETARG_DATUM(1),
+ PG_GETARG_DATUM(2),
+ PointerGetDatum(NULL)));
+
+ if (res && res->lexeme)
+ {
+ TSLexeme *ptr = res,
+ *basevar;
+
+ while (ptr->lexeme)
+ {
+ uint16 nv = ptr->nvariant;
+ uint16 i,
+ nlex = 0;
+ LexemeInfo **infos;
+
+ basevar = ptr;
+ while (ptr->lexeme && nv == ptr->nvariant)
+ {
+ nlex++;
+ ptr++;
+ }
+
+ infos = (LexemeInfo **) palloc(sizeof(LexemeInfo *) * nlex);
+ for (i = 0; i < nlex; i++)
+ if ((infos[i] = findTheLexeme(d, basevar[i].lexeme)) == NULL)
+ break;
+
+ if (i < nlex)
+ {
+ /* no chance to find */
+ pfree(infos);
+ continue;
+ }
+
+ info = findVariant(info, stored, curpos, infos, nlex);
+ }
+ }
+ else if (res)
+ { /* stop-word */
+ LexemeInfo *infos = findTheLexeme(d, NULL);
+
+ info = findVariant(NULL, stored, curpos, &infos, 1);
+ }
+ else
+ {
+ info = NULL; /* word isn't recognized */
+ }
+
+ dstate->private = (void *) info;
+
+ if (!info)
+ {
+ dstate->getnext = false;
+ PG_RETURN_POINTER(NULL);
+ }
+
+ if ((res = checkMatch(d, info, curpos, &moreres)) != NULL)
+ {
+ dstate->getnext = moreres;
+ PG_RETURN_POINTER(res);
+ }
+
+ dstate->getnext = true;
+
+ PG_RETURN_POINTER(NULL);
+}
diff --git a/src/backend/tsearch/regis.c b/src/backend/tsearch/regis.c
new file mode 100644
index 00000000000..705dd96b4ac
--- /dev/null
+++ b/src/backend/tsearch/regis.c
@@ -0,0 +1,236 @@
+/*-------------------------------------------------------------------------
+ *
+ * regis.c
+ * Fast regex subset
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/regis.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "tsearch/dicts/regis.h"
+#include "tsearch/ts_locale.h"
+
+bool
+RS_isRegis(const char *str)
+{
+ while (str && *str)
+ {
+ if (t_isalpha(str) ||
+ t_iseq(str, '[') ||
+ t_iseq(str, ']') ||
+ t_iseq(str, '^'))
+ str += pg_mblen(str);
+ else
+ return false;
+ }
+ return true;
+}
+
+#define RS_IN_ONEOF 1
+#define RS_IN_ONEOF_IN 2
+#define RS_IN_NONEOF 3
+#define RS_IN_WAIT 4
+
+static RegisNode *
+newRegisNode(RegisNode * prev, int len)
+{
+ RegisNode *ptr;
+
+ ptr = (RegisNode *) palloc0(RNHDRSZ + len + 1);
+ if (prev)
+ prev->next = ptr;
+ return ptr;
+}
+
+void
+RS_compile(Regis * r, bool issuffix, char *str)
+{
+ int len = strlen(str);
+ int state = RS_IN_WAIT;
+ char *c = (char *) str;
+ RegisNode *ptr = NULL;
+
+ memset(r, 0, sizeof(Regis));
+ r->issuffix = (issuffix) ? 1 : 0;
+
+ while (*c)
+ {
+ if (state == RS_IN_WAIT)
+ {
+ if (t_isalpha(c))
+ {
+ if (ptr)
+ ptr = newRegisNode(ptr, len);
+ else
+ ptr = r->node = newRegisNode(NULL, len);
+ COPYCHAR(ptr->data, c);
+ ptr->type = RSF_ONEOF;
+ ptr->len = pg_mblen(c);
+ }
+ else if (t_iseq(c, '['))
+ {
+ if (ptr)
+ ptr = newRegisNode(ptr, len);
+ else
+ ptr = r->node = newRegisNode(NULL, len);
+ ptr->type = RSF_ONEOF;
+ state = RS_IN_ONEOF;
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
+ errmsg("invalid regis pattern: \"%s\"",
+ str)));
+ }
+ else if (state == RS_IN_ONEOF)
+ {
+ if (t_iseq(c, '^'))
+ {
+ ptr->type = RSF_NONEOF;
+ state = RS_IN_NONEOF;
+ }
+ else if (t_isalpha(c))
+ {
+ COPYCHAR(ptr->data, c);
+ ptr->len = pg_mblen(c);
+ state = RS_IN_ONEOF_IN;
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
+ errmsg("invalid regis pattern: \"%s\"",
+ str)));
+ }
+ else if (state == RS_IN_ONEOF_IN || state == RS_IN_NONEOF)
+ {
+ if (t_isalpha(c))
+ {
+ COPYCHAR(ptr->data + ptr->len, c);
+ ptr->len += pg_mblen(c);
+ }
+ else if (t_iseq(c, ']'))
+ state = RS_IN_WAIT;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
+ errmsg("invalid regis pattern: \"%s\"",
+ str)));
+ }
+ else
+ elog(ERROR, "internal error in RS_compile: state %d", state);
+ c += pg_mblen(c);
+ }
+
+ ptr = r->node;
+ while (ptr)
+ {
+ r->nchar++;
+ ptr = ptr->next;
+ }
+}
+
+void
+RS_free(Regis * r)
+{
+ RegisNode *ptr = r->node,
+ *tmp;
+
+ while (ptr)
+ {
+ tmp = ptr->next;
+ pfree(ptr);
+ ptr = tmp;
+ }
+
+ r->node = NULL;
+}
+
+#ifdef TS_USE_WIDE
+static bool
+mb_strchr(char *str, char *c)
+{
+ int clen = pg_mblen(c),
+ plen,
+ i;
+ char *ptr = str;
+ bool res = false;
+
+ clen = pg_mblen(c);
+ while (*ptr && !res)
+ {
+ plen = pg_mblen(ptr);
+ if (plen == clen)
+ {
+ i = plen;
+ res = true;
+ while (i--)
+ if (*(ptr + i) != *(c + i))
+ {
+ res = false;
+ break;
+ }
+ }
+
+ ptr += plen;
+ }
+
+ return res;
+}
+#else
+#define mb_strchr(s,c) ( (strchr((s),*(c)) == NULL) ? false : true )
+#endif
+
+
+bool
+RS_execute(Regis * r, char *str)
+{
+ RegisNode *ptr = r->node;
+ char *c = str;
+ int len = 0;
+
+ while (*c)
+ {
+ len++;
+ c += pg_mblen(c);
+ }
+
+ if (len < r->nchar)
+ return 0;
+
+ c = str;
+ if (r->issuffix)
+ {
+ len -= r->nchar;
+ while (len-- > 0)
+ c += pg_mblen(c);
+ }
+
+
+ while (ptr)
+ {
+ switch (ptr->type)
+ {
+ case RSF_ONEOF:
+ if (mb_strchr((char *) ptr->data, c) != true)
+ return false;
+ break;
+ case RSF_NONEOF:
+ if (mb_strchr((char *) ptr->data, c) == true)
+ return false;
+ break;
+ default:
+ elog(ERROR, "unrecognized regis node type: %d", ptr->type);
+ }
+ ptr = ptr->next;
+ c += pg_mblen(c);
+ }
+
+ return true;
+}
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
new file mode 100644
index 00000000000..d09208649f7
--- /dev/null
+++ b/src/backend/tsearch/spell.c
@@ -0,0 +1,1747 @@
+/*-------------------------------------------------------------------------
+ *
+ * spell.c
+ * Normalizing word with ISpell
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "storage/fd.h"
+#include "tsearch/dicts/spell.h"
+#include "tsearch/ts_locale.h"
+#include "utils/memutils.h"
+
+
+/*
+ * during initialization dictionary requires a lot
+ * of memory, so it will use temporary context
+ */
+static MemoryContext tmpCtx = NULL;
+
+#define tmpalloc(sz) MemoryContextAlloc(tmpCtx, (sz))
+#define tmpalloc0(sz) MemoryContextAllocZero(tmpCtx, (sz))
+
+static void
+checkTmpCtx(void)
+{
+ if (CurrentMemoryContext->firstchild == NULL)
+ {
+ tmpCtx = AllocSetContextCreate(CurrentMemoryContext,
+ "Ispell dictionary init context",
+ ALLOCSET_DEFAULT_MINSIZE,
+ ALLOCSET_DEFAULT_INITSIZE,
+ ALLOCSET_DEFAULT_MAXSIZE);
+ }
+ else
+ tmpCtx = CurrentMemoryContext->firstchild;
+}
+
+static char *
+lowerstr_ctx(char *src)
+{
+ MemoryContext saveCtx;
+ char *dst;
+
+ saveCtx = MemoryContextSwitchTo(tmpCtx);
+ dst = lowerstr(src);
+ MemoryContextSwitchTo(saveCtx);
+
+ return dst;
+}
+
+#define MAX_NORM 1024
+#define MAXNORMLEN 256
+
+#define STRNCMP(s,p) strncmp( (s), (p), strlen(p) )
+#define GETWCHAR(W,L,N,T) ( ((uint8*)(W))[ ((T)==FF_PREFIX) ? (N) : ( (L) - 1 - (N) ) ] )
+#define GETCHAR(A,N,T) GETWCHAR( (A)->repl, (A)->replen, N, T )
+
+static char *VoidString = "";
+
+static int
+cmpspell(const void *s1, const void *s2)
+{
+ return (strcmp((*(const SPELL **) s1)->word, (*(const SPELL **) s2)->word));
+}
+static int
+cmpspellaffix(const void *s1, const void *s2)
+{
+ return (strcmp((*(const SPELL **) s1)->p.flag, (*(const SPELL **) s2)->p.flag));
+}
+
+static char *
+strnduplicate(char *s, int len)
+{
+ char *d = (char *) palloc(len + 1);
+
+ memcpy(d, s, len);
+ d[len] = '\0';
+ return d;
+}
+
+static char *
+findchar(char *str, int c)
+{
+ while (*str)
+ {
+ if (t_iseq(str, c))
+ return str;
+ str += pg_mblen(str);
+ }
+
+ return NULL;
+}
+
+
+/* backward string compare for suffix tree operations */
+static int
+strbcmp(const unsigned char *s1, const unsigned char *s2)
+{
+ int l1 = strlen((const char *) s1) - 1,
+ l2 = strlen((const char *) s2) - 1;
+
+ while (l1 >= 0 && l2 >= 0)
+ {
+ if (s1[l1] < s2[l2])
+ return -1;
+ if (s1[l1] > s2[l2])
+ return 1;
+ l1--;
+ l2--;
+ }
+ if (l1 < l2)
+ return -1;
+ if (l1 > l2)
+ return 1;
+
+ return 0;
+}
+static int
+strbncmp(const unsigned char *s1, const unsigned char *s2, size_t count)
+{
+ int l1 = strlen((const char *) s1) - 1,
+ l2 = strlen((const char *) s2) - 1,
+ l = count;
+
+ while (l1 >= 0 && l2 >= 0 && l > 0)
+ {
+ if (s1[l1] < s2[l2])
+ return -1;
+ if (s1[l1] > s2[l2])
+ return 1;
+ l1--;
+ l2--;
+ l--;
+ }
+ if (l == 0)
+ return 0;
+ if (l1 < l2)
+ return -1;
+ if (l1 > l2)
+ return 1;
+ return 0;
+}
+
+static int
+cmpaffix(const void *s1, const void *s2)
+{
+ const AFFIX *a1 = (const AFFIX *) s1;
+ const AFFIX *a2 = (const AFFIX *) s2;
+
+ if (a1->type < a2->type)
+ return -1;
+ if (a1->type > a2->type)
+ return 1;
+ if (a1->type == FF_PREFIX)
+ return strcmp(a1->repl, a2->repl);
+ else
+ return strbcmp((const unsigned char *) a1->repl,
+ (const unsigned char *) a2->repl);
+}
+
+static void
+NIAddSpell(IspellDict * Conf, const char *word, const char *flag)
+{
+ if (Conf->nspell >= Conf->mspell)
+ {
+ if (Conf->mspell)
+ {
+ Conf->mspell += 1024 * 20;
+ Conf->Spell = (SPELL **) repalloc(Conf->Spell, Conf->mspell * sizeof(SPELL *));
+ }
+ else
+ {
+ Conf->mspell = 1024 * 20;
+ Conf->Spell = (SPELL **) tmpalloc(Conf->mspell * sizeof(SPELL *));
+ }
+ }
+ Conf->Spell[Conf->nspell] = (SPELL *) tmpalloc(SPELLHDRSZ + strlen(word) + 1);
+ strcpy(Conf->Spell[Conf->nspell]->word, word);
+ strncpy(Conf->Spell[Conf->nspell]->p.flag, flag, 16);
+ Conf->nspell++;
+}
+
+/*
+ * import dictionary
+ *
+ * Note caller must already have applied get_tsearch_config_filename
+ */
+void
+NIImportDictionary(IspellDict * Conf, const char *filename)
+{
+ char str[BUFSIZ],
+ *pstr;
+ FILE *dict;
+
+ checkTmpCtx();
+
+ if (!(dict = AllocateFile(filename, "r")))
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("could not open dictionary file \"%s\": %m",
+ filename)));
+
+ while (fgets(str, sizeof(str), dict))
+ {
+ char *s,
+ *recoded;
+ const char *flag;
+
+ recoded = (char *) pg_do_encoding_conversion((unsigned char *) str, strlen(str),
+ PG_UTF8, GetDatabaseEncoding());
+ if (recoded == NULL)
+ elog(ERROR, "encoding conversion failed");
+
+ flag = NULL;
+ if ((s = findchar(recoded, '/')))
+ {
+ *s++ = '\0';
+ flag = s;
+ while (*s)
+ {
+ /* we allow only single encoded flags for faster works */
+ if (pg_mblen(s) == 1 && t_isprint(s) && !t_isspace(s))
+ s++;
+ else
+ {
+ *s = '\0';
+ break;
+ }
+ }
+ }
+ else
+ flag = "";
+
+
+ s = recoded;
+ while (*s)
+ {
+ if (t_isspace(s))
+ {
+ *s = '\0';
+ break;
+ }
+ s += pg_mblen(s);
+ }
+ pstr = lowerstr_ctx(recoded);
+
+ NIAddSpell(Conf, pstr, flag);
+ pfree(pstr);
+
+ if (recoded != str)
+ pfree(recoded);
+ }
+ FreeFile(dict);
+}
+
+
+static int
+FindWord(IspellDict * Conf, const char *word, int affixflag, int flag)
+{
+ SPNode *node = Conf->Dictionary;
+ SPNodeData *StopLow,
+ *StopHigh,
+ *StopMiddle;
+ uint8 *ptr = (uint8 *) word;
+
+ flag &= FF_DICTFLAGMASK;
+
+ while (node && *ptr)
+ {
+ StopLow = node->data;
+ StopHigh = node->data + node->length;
+ while (StopLow < StopHigh)
+ {
+ StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
+ if (StopMiddle->val == *ptr)
+ {
+ if (*(ptr + 1) == '\0' && StopMiddle->isword)
+ {
+ if (flag == 0)
+ {
+ if (StopMiddle->compoundflag & FF_COMPOUNDONLY)
+ return 0;
+ }
+ else if ((flag & StopMiddle->compoundflag) == 0)
+ return 0;
+
+ if ((affixflag == 0) || (strchr(Conf->AffixData[StopMiddle->affix], affixflag) != NULL))
+ return 1;
+ }
+ node = StopMiddle->node;
+ ptr++;
+ break;
+ }
+ else if (StopMiddle->val < *ptr)
+ StopLow = StopMiddle + 1;
+ else
+ StopHigh = StopMiddle;
+ }
+ if (StopLow >= StopHigh)
+ break;
+ }
+ return 0;
+}
+
+static void
+NIAddAffix(IspellDict * Conf, int flag, char flagflags, const char *mask, const char *find, const char *repl, int type)
+{
+ AFFIX *Affix;
+
+ if (Conf->naffixes >= Conf->maffixes)
+ {
+ if (Conf->maffixes)
+ {
+ Conf->maffixes += 16;
+ Conf->Affix = (AFFIX *) repalloc((void *) Conf->Affix, Conf->maffixes * sizeof(AFFIX));
+ }
+ else
+ {
+ Conf->maffixes = 16;
+ Conf->Affix = (AFFIX *) palloc(Conf->maffixes * sizeof(AFFIX));
+ }
+ }
+
+ Affix = Conf->Affix + Conf->naffixes;
+
+ if (strcmp(mask, ".") == 0)
+ {
+ Affix->issimple = 1;
+ Affix->isregis = 0;
+ }
+ else if (RS_isRegis(mask))
+ {
+ Affix->issimple = 0;
+ Affix->isregis = 1;
+ RS_compile(&(Affix->reg.regis), (type == FF_SUFFIX) ? true : false,
+ (char *) ((mask && *mask) ? mask : VoidString));
+ }
+ else
+ {
+ int masklen;
+ int wmasklen;
+ int err;
+ pg_wchar *wmask;
+ char *tmask;
+
+ Affix->issimple = 0;
+ Affix->isregis = 0;
+ tmask = (char *) tmpalloc(strlen(mask) + 3);
+ if (type == FF_SUFFIX)
+ sprintf(tmask, "%s$", mask);
+ else
+ sprintf(tmask, "^%s", mask);
+
+ masklen = strlen(tmask);
+ wmask = (pg_wchar *) tmpalloc((masklen + 1) * sizeof(pg_wchar));
+ wmasklen = pg_mb2wchar_with_len(tmask, wmask, masklen);
+
+ err = pg_regcomp(&(Affix->reg.regex), wmask, wmasklen, REG_ADVANCED | REG_NOSUB);
+ if (err)
+ {
+ char errstr[100];
+
+ pg_regerror(err, &(Affix->reg.regex), errstr, sizeof(errstr));
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
+ errmsg("invalid regular expression: %s", errstr)));
+ }
+ }
+
+ Affix->flagflags = flagflags;
+ if ((Affix->flagflags & FF_COMPOUNDONLY) || (Affix->flagflags & FF_COMPOUNDPERMITFLAG))
+ {
+ if ((Affix->flagflags & FF_COMPOUNDFLAG) == 0)
+ Affix->flagflags |= FF_COMPOUNDFLAG;
+ }
+ Affix->flag = flag;
+ Affix->type = type;
+
+ Affix->find = (find && *find) ? pstrdup(find) : VoidString;
+ if ((Affix->replen = strlen(repl)) > 0)
+ Affix->repl = pstrdup(repl);
+ else
+ Affix->repl = VoidString;
+ Conf->naffixes++;
+}
+
+#define PAE_WAIT_MASK 0
+#define PAE_INMASK 1
+#define PAE_WAIT_FIND 2
+#define PAE_INFIND 3
+#define PAE_WAIT_REPL 4
+#define PAE_INREPL 5
+
+static bool
+parse_affentry(char *str, char *mask, char *find, char *repl,
+ const char *filename, int line)
+{
+ int state = PAE_WAIT_MASK;
+ char *pmask = mask,
+ *pfind = find,
+ *prepl = repl;
+
+ *mask = *find = *repl = '\0';
+
+ while (*str)
+ {
+ if (state == PAE_WAIT_MASK)
+ {
+ if (t_iseq(str, '#'))
+ return false;
+ else if (!t_isspace(str))
+ {
+ COPYCHAR(pmask, str);
+ pmask += pg_mblen(str);
+ state = PAE_INMASK;
+ }
+ }
+ else if (state == PAE_INMASK)
+ {
+ if (t_iseq(str, '>'))
+ {
+ *pmask = '\0';
+ state = PAE_WAIT_FIND;
+ }
+ else if (!t_isspace(str))
+ {
+ COPYCHAR(pmask, str);
+ pmask += pg_mblen(str);
+ }
+ }
+ else if (state == PAE_WAIT_FIND)
+ {
+ if (t_iseq(str, '-'))
+ {
+ state = PAE_INFIND;
+ }
+ else if (t_isalpha(str) || t_iseq(str, '\'') /* english 's */ )
+ {
+ COPYCHAR(prepl, str);
+ prepl += pg_mblen(str);
+ state = PAE_INREPL;
+ }
+ else if (!t_isspace(str))
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("syntax error at line %d of affix file \"%s\"",
+ line, filename)));
+ }
+ else if (state == PAE_INFIND)
+ {
+ if (t_iseq(str, ','))
+ {
+ *pfind = '\0';
+ state = PAE_WAIT_REPL;
+ }
+ else if (t_isalpha(str))
+ {
+ COPYCHAR(pfind, str);
+ pfind += pg_mblen(str);
+ }
+ else if (!t_isspace(str))
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("syntax error at line %d of affix file \"%s\"",
+ line, filename)));
+ }
+ else if (state == PAE_WAIT_REPL)
+ {
+ if (t_iseq(str, '-'))
+ {
+ break; /* void repl */
+ }
+ else if (t_isalpha(str))
+ {
+ COPYCHAR(prepl, str);
+ prepl += pg_mblen(str);
+ state = PAE_INREPL;
+ }
+ else if (!t_isspace(str))
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("syntax error at line %d of affix file \"%s\"",
+ line, filename)));
+ }
+ else if (state == PAE_INREPL)
+ {
+ if (t_iseq(str, '#'))
+ {
+ *prepl = '\0';
+ break;
+ }
+ else if (t_isalpha(str))
+ {
+ COPYCHAR(prepl, str);
+ prepl += pg_mblen(str);
+ }
+ else if (!t_isspace(str))
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("syntax error at line %d of affix file \"%s\"",
+ line, filename)));
+ }
+ else
+ elog(ERROR, "unknown state in parse_affentry: %d", state);
+
+ str += pg_mblen(str);
+ }
+
+ *pmask = *pfind = *prepl = '\0';
+
+ return (*mask && (*find || *repl)) ? true : false;
+}
+
+static void
+addFlagValue(IspellDict * Conf, char *s, uint32 val,
+ const char *filename, int line)
+{
+ while (*s && t_isspace(s))
+ s++;
+
+ if (!*s)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("syntax error at line %d of affix file \"%s\"",
+ line, filename)));
+
+ if (pg_mblen(s) != 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("multibyte flag character is not allowed at line %d of affix file \"%s\"",
+ line, filename)));
+
+ Conf->flagval[(unsigned int) *s] = (unsigned char) val;
+ Conf->usecompound = true;
+}
+
+static void
+NIImportOOAffixes(IspellDict * Conf, const char *filename)
+{
+ char str[BUFSIZ];
+ char type[BUFSIZ],
+ *ptype = NULL;
+ char sflag[BUFSIZ];
+ char mask[BUFSIZ],
+ *pmask;
+ char find[BUFSIZ],
+ *pfind;
+ char repl[BUFSIZ],
+ *prepl;
+ bool isSuffix = false;
+ int flag = 0;
+ char flagflags = 0;
+ FILE *affix;
+ int line = 0;
+ int scanread = 0;
+ char scanbuf[BUFSIZ];
+
+ checkTmpCtx();
+
+ /* read file to find any flag */
+ memset(Conf->flagval, 0, sizeof(Conf->flagval));
+ Conf->usecompound = false;
+
+ if (!(affix = AllocateFile(filename, "r")))
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("could not open affix file \"%s\": %m",
+ filename)));
+
+ while (fgets(str, sizeof(str), affix))
+ {
+ char *recoded;
+
+ recoded = (char *) pg_do_encoding_conversion((unsigned char *) str, strlen(str),
+ PG_UTF8, GetDatabaseEncoding());
+ if (recoded == NULL)
+ elog(ERROR, "encoding conversion failed");
+
+ line++;
+
+ if (*recoded == '\0' || t_isspace(recoded) || t_iseq(recoded, '#'))
+ continue;
+
+ if (STRNCMP(recoded, "COMPOUNDFLAG") == 0)
+ addFlagValue(Conf, recoded + strlen("COMPOUNDFLAG"),
+ FF_COMPOUNDFLAG, filename, line);
+ else if (STRNCMP(recoded, "COMPOUNDBEGIN") == 0)
+ addFlagValue(Conf, recoded + strlen("COMPOUNDBEGIN"),
+ FF_COMPOUNDBEGIN, filename, line);
+ else if (STRNCMP(recoded, "COMPOUNDLAST") == 0)
+ addFlagValue(Conf, recoded + strlen("COMPOUNDLAST"),
+ FF_COMPOUNDLAST, filename, line);
+ /* COMPOUNDLAST and COMPOUNDEND are synonyms */
+ else if (STRNCMP(recoded, "COMPOUNDEND") == 0)
+ addFlagValue(Conf, recoded + strlen("COMPOUNDEND"),
+ FF_COMPOUNDLAST, filename, line);
+ else if (STRNCMP(recoded, "COMPOUNDMIDDLE") == 0)
+ addFlagValue(Conf, recoded + strlen("COMPOUNDMIDDLE"),
+ FF_COMPOUNDMIDDLE, filename, line);
+ else if (STRNCMP(recoded, "ONLYINCOMPOUND") == 0)
+ addFlagValue(Conf, recoded + strlen("ONLYINCOMPOUND"),
+ FF_COMPOUNDONLY, filename, line);
+ else if (STRNCMP(recoded, "COMPOUNDPERMITFLAG") == 0)
+ addFlagValue(Conf, recoded + strlen("COMPOUNDPERMITFLAG"),
+ FF_COMPOUNDPERMITFLAG, filename, line);
+ else if (STRNCMP(recoded, "COMPOUNDFORBIDFLAG") == 0)
+ addFlagValue(Conf, recoded + strlen("COMPOUNDFORBIDFLAG"),
+ FF_COMPOUNDFORBIDFLAG, filename, line);
+ else if (STRNCMP(recoded, "FLAG") == 0)
+ {
+ char *s = recoded + strlen("FLAG");
+
+ while (*s && t_isspace(s))
+ s++;
+
+ if (*s && STRNCMP(s, "default") != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("Ispell dictionary supports only default flag value at line %d of affix file \"%s\"",
+ line, filename)));
+ }
+
+ if (recoded != str)
+ pfree(recoded);
+ }
+ FreeFile(affix);
+ line = 0;
+
+ sprintf(scanbuf, "%%6s %%%ds %%%ds %%%ds %%%ds", BUFSIZ / 5, BUFSIZ / 5, BUFSIZ / 5, BUFSIZ / 5);
+
+ if (!(affix = AllocateFile(filename, "r")))
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("could not open affix file \"%s\": %m",
+ filename)));
+
+ while (fgets(str, sizeof(str), affix))
+ {
+ char *recoded;
+
+ recoded = (char *) pg_do_encoding_conversion((unsigned char *) str, strlen(str),
+ PG_UTF8, GetDatabaseEncoding());
+ if (recoded == NULL)
+ elog(ERROR, "encoding conversion failed");
+
+ line++;
+ if (*recoded == '\0' || t_isspace(recoded) || t_iseq(recoded, '#'))
+ continue;
+
+ scanread = sscanf(recoded, scanbuf, type, sflag, find, repl, mask);
+
+ if (ptype)
+ pfree(ptype);
+ ptype = lowerstr_ctx(type);
+ if (scanread < 4 || (STRNCMP(ptype, "sfx") && STRNCMP(ptype, "pfx")))
+ continue;
+
+ if (scanread == 4)
+ {
+ if (strlen(sflag) != 1)
+ continue;
+ flag = *sflag;
+ isSuffix = (STRNCMP(ptype, "sfx") == 0) ? true : false;
+ pfind = lowerstr_ctx(find);
+ if (t_iseq(find, 'y'))
+ flagflags = FF_CROSSPRODUCT;
+ else
+ flagflags = 0;
+ pfree(pfind);
+ }
+ else
+ {
+ char *ptr;
+ int aflg = 0;
+
+ if (strlen(sflag) != 1 || flag != *sflag || flag == 0)
+ continue;
+ prepl = lowerstr_ctx(repl);
+ /* affix flag */
+ if ((ptr = strchr(prepl, '/')) != NULL)
+ {
+ *ptr = '\0';
+ ptr++;
+ while (*ptr)
+ {
+ aflg |= Conf->flagval[(unsigned int) *ptr];
+ ptr++;
+ }
+ }
+ pfind = lowerstr_ctx(find);
+ pmask = lowerstr_ctx(mask);
+ if (t_iseq(find, '0'))
+ *pfind = '\0';
+ if (t_iseq(repl, '0'))
+ *prepl = '\0';
+
+ NIAddAffix(Conf, flag, flagflags | aflg, pmask, pfind, prepl,
+ isSuffix ? FF_SUFFIX : FF_PREFIX);
+ pfree(prepl);
+ pfree(pfind);
+ pfree(pmask);
+ }
+
+ if (recoded != str)
+ pfree(recoded);
+ }
+
+ if (ptype)
+ pfree(ptype);
+ FreeFile(affix);
+}
+
+/*
+ * import affixes
+ *
+ * Note caller must already have applied get_tsearch_config_filename
+ */
+void
+NIImportAffixes(IspellDict * Conf, const char *filename)
+{
+ char str[BUFSIZ],
+ *pstr = NULL;
+ char mask[BUFSIZ];
+ char find[BUFSIZ];
+ char repl[BUFSIZ];
+ char *s;
+ int suffixes = 0;
+ int prefixes = 0;
+ int flag = 0;
+ char flagflags = 0;
+ FILE *affix;
+ int line = 0;
+ int oldformat = 0;
+
+ checkTmpCtx();
+
+ if (!(affix = AllocateFile(filename, "r")))
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("could not open affix file \"%s\": %m",
+ filename)));
+
+ memset(Conf->flagval, 0, sizeof(Conf->flagval));
+ Conf->usecompound = false;
+
+ while (fgets(str, sizeof(str), affix))
+ {
+ if (pstr)
+ pfree(pstr);
+
+ pstr = recode_and_lowerstr(str);
+
+ line++;
+ if (*pstr == '#' || *pstr == '\n')
+ continue;
+
+ if (STRNCMP(pstr, "compoundwords") == 0)
+ {
+ s = findchar(str, 'l');
+ if (s)
+ {
+ while (*s && !t_isspace(s))
+ s++;
+ while (*s && t_isspace(s))
+ s++;
+ if (*s && pg_mblen(s) == 1)
+ {
+ Conf->flagval[(unsigned int) *s] = FF_COMPOUNDFLAG;
+ Conf->usecompound = true;
+ }
+ oldformat++;
+ continue;
+ }
+ }
+ if (STRNCMP(pstr, "suffixes") == 0)
+ {
+ suffixes = 1;
+ prefixes = 0;
+ oldformat++;
+ continue;
+ }
+ if (STRNCMP(pstr, "prefixes") == 0)
+ {
+ suffixes = 0;
+ prefixes = 1;
+ oldformat++;
+ continue;
+ }
+ if (STRNCMP(pstr, "flag") == 0)
+ {
+ s = str + 4;
+ flagflags = 0;
+
+ while (*s && t_isspace(s))
+ s++;
+ oldformat++;
+
+ /* allow only single-encoded flags */
+ if (pg_mblen(s) != 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("multibyte flag character is not allowed at line %d of affix file \"%s\"",
+ line, filename)));
+
+ if (*s == '*')
+ {
+ flagflags |= FF_CROSSPRODUCT;
+ s++;
+ }
+ else if (*s == '~')
+ {
+ flagflags |= FF_COMPOUNDONLY;
+ s++;
+ }
+
+ if (*s == '\\')
+ s++;
+
+ /* allow only single-encoded flags */
+ if (pg_mblen(s) != 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("multibyte flag character is not allowed at line %d of affix file \"%s\"",
+ line, filename)));
+
+ flag = (unsigned char) *s;
+ continue;
+ }
+ if (STRNCMP(str, "COMPOUNDFLAG") == 0 || STRNCMP(str, "COMPOUNDMIN") == 0 ||
+ STRNCMP(str, "PFX") == 0 || STRNCMP(str, "SFX") == 0)
+ {
+ if (oldformat)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("wrong affix file format for flag at line %d of affix file \"%s\"",
+ line, filename)));
+ FreeFile(affix);
+ NIImportOOAffixes(Conf, filename);
+ return;
+ }
+ if ((!suffixes) && (!prefixes))
+ continue;
+
+ if (!parse_affentry(pstr, mask, find, repl, filename, line))
+ continue;
+
+ NIAddAffix(Conf, flag, flagflags, mask, find, repl, suffixes ? FF_SUFFIX : FF_PREFIX);
+ }
+ FreeFile(affix);
+
+ if (pstr)
+ pfree(pstr);
+}
+
+static int
+MergeAffix(IspellDict * Conf, int a1, int a2)
+{
+ char **ptr;
+
+ while (Conf->nAffixData + 1 >= Conf->lenAffixData)
+ {
+ Conf->lenAffixData *= 2;
+ Conf->AffixData = (char **) repalloc(Conf->AffixData,
+ sizeof(char *) * Conf->lenAffixData);
+ }
+
+ ptr = Conf->AffixData + Conf->nAffixData;
+ *ptr = palloc(strlen(Conf->AffixData[a1]) + strlen(Conf->AffixData[a2]) +
+ 1 /* space */ + 1 /* \0 */ );
+ sprintf(*ptr, "%s %s", Conf->AffixData[a1], Conf->AffixData[a2]);
+ ptr++;
+ *ptr = NULL;
+ Conf->nAffixData++;
+
+ return Conf->nAffixData - 1;
+}
+
+static uint32
+makeCompoundFlags(IspellDict * Conf, int affix)
+{
+ uint32 flag = 0;
+ char *str = Conf->AffixData[affix];
+
+ while (str && *str)
+ {
+ flag |= Conf->flagval[(unsigned int) *str];
+ str++;
+ }
+
+ return (flag & FF_DICTFLAGMASK);
+}
+
+static SPNode *
+mkSPNode(IspellDict * Conf, int low, int high, int level)
+{
+ int i;
+ int nchar = 0;
+ char lastchar = '\0';
+ SPNode *rs;
+ SPNodeData *data;
+ int lownew = low;
+
+ for (i = low; i < high; i++)
+ if (Conf->Spell[i]->p.d.len > level && lastchar != Conf->Spell[i]->word[level])
+ {
+ nchar++;
+ lastchar = Conf->Spell[i]->word[level];
+ }
+
+ if (!nchar)
+ return NULL;
+
+ rs = (SPNode *) palloc0(SPNHRDSZ + nchar * sizeof(SPNodeData));
+ rs->length = nchar;
+ data = rs->data;
+
+ lastchar = '\0';
+ for (i = low; i < high; i++)
+ if (Conf->Spell[i]->p.d.len > level)
+ {
+ if (lastchar != Conf->Spell[i]->word[level])
+ {
+ if (lastchar)
+ {
+ data->node = mkSPNode(Conf, lownew, i, level + 1);
+ lownew = i;
+ data++;
+ }
+ lastchar = Conf->Spell[i]->word[level];
+ }
+ data->val = ((uint8 *) (Conf->Spell[i]->word))[level];
+ if (Conf->Spell[i]->p.d.len == level + 1)
+ {
+ bool clearCompoundOnly = false;
+
+ if (data->isword && data->affix != Conf->Spell[i]->p.d.affix)
+ {
+ /*
+ * MergeAffix called a few times. If one of word is
+ * allowed to be in compound word and another isn't, then
+ * clear FF_COMPOUNDONLY flag.
+ */
+
+ clearCompoundOnly = (FF_COMPOUNDONLY & data->compoundflag
+ & makeCompoundFlags(Conf, Conf->Spell[i]->p.d.affix))
+ ? false : true;
+ data->affix = MergeAffix(Conf, data->affix, Conf->Spell[i]->p.d.affix);
+ }
+ else
+ data->affix = Conf->Spell[i]->p.d.affix;
+ data->isword = 1;
+
+ data->compoundflag = makeCompoundFlags(Conf, data->affix);
+
+ if ((data->compoundflag & FF_COMPOUNDONLY) &&
+ (data->compoundflag & FF_COMPOUNDFLAG) == 0)
+ data->compoundflag |= FF_COMPOUNDFLAG;
+
+ if (clearCompoundOnly)
+ data->compoundflag &= ~FF_COMPOUNDONLY;
+ }
+ }
+
+ data->node = mkSPNode(Conf, lownew, high, level + 1);
+
+ return rs;
+}
+
+void
+NISortDictionary(IspellDict * Conf)
+{
+ size_t i;
+ int naffix = 3;
+
+ checkTmpCtx();
+
+ /* compress affixes */
+ qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspellaffix);
+ for (i = 1; i < Conf->nspell; i++)
+ if (strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag))
+ naffix++;
+
+ Conf->AffixData = (char **) palloc0(naffix * sizeof(char *));
+ naffix = 1;
+ Conf->AffixData[0] = pstrdup("");
+ Conf->AffixData[1] = pstrdup(Conf->Spell[0]->p.flag);
+ Conf->Spell[0]->p.d.affix = 1;
+ Conf->Spell[0]->p.d.len = strlen(Conf->Spell[0]->word);
+ for (i = 1; i < Conf->nspell; i++)
+ {
+ if (strcmp(Conf->Spell[i]->p.flag, Conf->AffixData[naffix]))
+ {
+ naffix++;
+ Conf->AffixData[naffix] = pstrdup(Conf->Spell[i]->p.flag);
+ }
+ Conf->Spell[i]->p.d.affix = naffix;
+ Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
+ }
+
+ Conf->lenAffixData = Conf->nAffixData = naffix;
+ qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
+ Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
+
+ Conf->Spell = NULL;
+}
+
+static AffixNode *
+mkANode(IspellDict * Conf, int low, int high, int level, int type)
+{
+ int i;
+ int nchar = 0;
+ uint8 lastchar = '\0';
+ AffixNode *rs;
+ AffixNodeData *data;
+ int lownew = low;
+ int naff;
+ AFFIX **aff;
+
+ for (i = low; i < high; i++)
+ if (Conf->Affix[i].replen > level && lastchar != GETCHAR(Conf->Affix + i, level, type))
+ {
+ nchar++;
+ lastchar = GETCHAR(Conf->Affix + i, level, type);
+ }
+
+ if (!nchar)
+ return NULL;
+
+ aff = (AFFIX **) tmpalloc(sizeof(AFFIX *) * (high - low + 1));
+ naff = 0;
+
+ rs = (AffixNode *) palloc0(ANHRDSZ + nchar * sizeof(AffixNodeData));
+ rs->length = nchar;
+ data = rs->data;
+
+ lastchar = '\0';
+ for (i = low; i < high; i++)
+ if (Conf->Affix[i].replen > level)
+ {
+ if (lastchar != GETCHAR(Conf->Affix + i, level, type))
+ {
+ if (lastchar)
+ {
+ data->node = mkANode(Conf, lownew, i, level + 1, type);
+ if (naff)
+ {
+ data->naff = naff;
+ data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * naff);
+ memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
+ naff = 0;
+ }
+ data++;
+ lownew = i;
+ }
+ lastchar = GETCHAR(Conf->Affix + i, level, type);
+ }
+ data->val = GETCHAR(Conf->Affix + i, level, type);
+ if (Conf->Affix[i].replen == level + 1)
+ { /* affix stopped */
+ aff[naff++] = Conf->Affix + i;
+ }
+ }
+
+ data->node = mkANode(Conf, lownew, high, level + 1, type);
+ if (naff)
+ {
+ data->naff = naff;
+ data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * naff);
+ memcpy(data->aff, aff, sizeof(AFFIX *) * naff);
+ naff = 0;
+ }
+
+ pfree(aff);
+
+ return rs;
+}
+
+static void
+mkVoidAffix(IspellDict * Conf, int issuffix, int startsuffix)
+{
+ int i,
+ cnt = 0;
+ int start = (issuffix) ? startsuffix : 0;
+ int end = (issuffix) ? Conf->naffixes : startsuffix;
+ AffixNode *Affix = (AffixNode *) palloc0(ANHRDSZ + sizeof(AffixNodeData));
+
+ Affix->length = 1;
+ Affix->isvoid = 1;
+
+ if (issuffix)
+ {
+ Affix->data->node = Conf->Suffix;
+ Conf->Suffix = Affix;
+ }
+ else
+ {
+ Affix->data->node = Conf->Prefix;
+ Conf->Prefix = Affix;
+ }
+
+
+ for (i = start; i < end; i++)
+ if (Conf->Affix[i].replen == 0)
+ cnt++;
+
+ if (cnt == 0)
+ return;
+
+ Affix->data->aff = (AFFIX **) palloc(sizeof(AFFIX *) * cnt);
+ Affix->data->naff = (uint32) cnt;
+
+ cnt = 0;
+ for (i = start; i < end; i++)
+ if (Conf->Affix[i].replen == 0)
+ {
+ Affix->data->aff[cnt] = Conf->Affix + i;
+ cnt++;
+ }
+}
+
+static bool
+isAffixInUse(IspellDict * Conf, char flag)
+{
+ int i;
+
+ for (i = 0; i < Conf->nAffixData; i++)
+ if (strchr(Conf->AffixData[i], flag) != NULL)
+ return true;
+
+ return false;
+}
+
+void
+NISortAffixes(IspellDict * Conf)
+{
+ AFFIX *Affix;
+ size_t i;
+ CMPDAffix *ptr;
+ int firstsuffix = -1;
+
+ checkTmpCtx();
+
+ if (Conf->naffixes == 0)
+ return;
+
+ if (Conf->naffixes > 1)
+ qsort((void *) Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
+ Conf->CompoundAffix = ptr = (CMPDAffix *) palloc(sizeof(CMPDAffix) * Conf->naffixes);
+ ptr->affix = NULL;
+
+ for (i = 0; i < Conf->naffixes; i++)
+ {
+ Affix = &(((AFFIX *) Conf->Affix)[i]);
+ if (Affix->type == FF_SUFFIX && firstsuffix < 0)
+ firstsuffix = i;
+
+ if ((Affix->flagflags & FF_COMPOUNDFLAG) && Affix->replen > 0 &&
+ isAffixInUse(Conf, (char) Affix->flag))
+ {
+ if (ptr == Conf->CompoundAffix ||
+ ptr->issuffix != (ptr - 1)->issuffix ||
+ strbncmp((const unsigned char *) (ptr - 1)->affix,
+ (const unsigned char *) Affix->repl,
+ (ptr - 1)->len))
+ {
+ /* leave only unique and minimals suffixes */
+ ptr->affix = Affix->repl;
+ ptr->len = Affix->replen;
+ ptr->issuffix = (Affix->type == FF_SUFFIX) ? true : false;
+ ptr++;
+ }
+ }
+ }
+ ptr->affix = NULL;
+ Conf->CompoundAffix = (CMPDAffix *) repalloc(Conf->CompoundAffix, sizeof(CMPDAffix) * (ptr - Conf->CompoundAffix + 1));
+
+ Conf->Prefix = mkANode(Conf, 0, firstsuffix, 0, FF_PREFIX);
+ Conf->Suffix = mkANode(Conf, firstsuffix, Conf->naffixes, 0, FF_SUFFIX);
+ mkVoidAffix(Conf, 1, firstsuffix);
+ mkVoidAffix(Conf, 0, firstsuffix);
+}
+
+static AffixNodeData *
+FinfAffixes(AffixNode * node, const char *word, int wrdlen, int *level, int type)
+{
+ AffixNodeData *StopLow,
+ *StopHigh,
+ *StopMiddle;
+ uint8 symbol;
+
+ if (node->isvoid)
+ { /* search void affixes */
+ if (node->data->naff)
+ return node->data;
+ node = node->data->node;
+ }
+
+ while (node && *level < wrdlen)
+ {
+ StopLow = node->data;
+ StopHigh = node->data + node->length;
+ while (StopLow < StopHigh)
+ {
+ StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
+ symbol = GETWCHAR(word, wrdlen, *level, type);
+ if (StopMiddle->val == symbol)
+ {
+ (*level)++;
+ if (StopMiddle->naff)
+ return StopMiddle;
+ node = StopMiddle->node;
+ break;
+ }
+ else if (StopMiddle->val < symbol)
+ StopLow = StopMiddle + 1;
+ else
+ StopHigh = StopMiddle;
+ }
+ if (StopLow >= StopHigh)
+ break;
+ }
+ return NULL;
+}
+
+static char *
+CheckAffix(const char *word, size_t len, AFFIX * Affix, int flagflags, char *newword, int *baselen)
+{
+ /*
+ * Check compound allow flags
+ */
+
+ if (flagflags == 0)
+ {
+ if (Affix->flagflags & FF_COMPOUNDONLY)
+ return NULL;
+ }
+ else if (flagflags & FF_COMPOUNDBEGIN)
+ {
+ if (Affix->flagflags & FF_COMPOUNDFORBIDFLAG)
+ return NULL;
+ if ((Affix->flagflags & FF_COMPOUNDBEGIN) == 0)
+ if (Affix->type == FF_SUFFIX)
+ return NULL;
+ }
+ else if (flagflags & FF_COMPOUNDMIDDLE)
+ {
+ if ((Affix->flagflags & FF_COMPOUNDMIDDLE) == 0 ||
+ (Affix->flagflags & FF_COMPOUNDFORBIDFLAG))
+ return NULL;
+ }
+ else if (flagflags & FF_COMPOUNDLAST)
+ {
+ if (Affix->flagflags & FF_COMPOUNDFORBIDFLAG)
+ return NULL;
+ if ((Affix->flagflags & FF_COMPOUNDLAST) == 0)
+ if (Affix->type == FF_PREFIX)
+ return NULL;
+ }
+
+ /*
+ * make replace pattern of affix
+ */
+ if (Affix->type == FF_SUFFIX)
+ {
+ strcpy(newword, word);
+ strcpy(newword + len - Affix->replen, Affix->find);
+ if (baselen) /* store length of non-changed part of word */
+ *baselen = len - Affix->replen;
+ }
+ else
+ {
+ /*
+ * if prefix is a all non-chaged part's length then all word contains
+ * only prefix and suffix, so out
+ */
+ if (baselen && *baselen + strlen(Affix->find) <= Affix->replen)
+ return NULL;
+ strcpy(newword, Affix->find);
+ strcat(newword, word + Affix->replen);
+ }
+
+ /*
+ * check resulting word
+ */
+ if (Affix->issimple)
+ return newword;
+ else if (Affix->isregis)
+ {
+ if (RS_execute(&(Affix->reg.regis), newword))
+ return newword;
+ }
+ else
+ {
+ int err;
+ pg_wchar *data;
+ size_t data_len;
+ int newword_len;
+
+ /* Convert data string to wide characters */
+ newword_len = strlen(newword);
+ data = (pg_wchar *) palloc((newword_len + 1) * sizeof(pg_wchar));
+ data_len = pg_mb2wchar_with_len(newword, data, newword_len);
+
+ if (!(err = pg_regexec(&(Affix->reg.regex), data, data_len, 0, NULL, 0, NULL, 0)))
+ {
+ pfree(data);
+ return newword;
+ }
+ pfree(data);
+ }
+
+ return NULL;
+}
+
+static int
+addToResult(char **forms, char **cur, char *word)
+{
+ if (cur - forms >= MAX_NORM - 1)
+ return 0;
+ if (forms == cur || strcmp(word, *(cur - 1)) != 0)
+ {
+ *cur = pstrdup(word);
+ cur++;
+ *cur = NULL;
+ return 1;
+ }
+
+ return 0;
+}
+
+static char **
+NormalizeSubWord(IspellDict * Conf, char *word, char flag)
+{
+ AffixNodeData *suffix = NULL,
+ *prefix = NULL;
+ int slevel = 0,
+ plevel = 0;
+ int wrdlen = strlen(word),
+ swrdlen;
+ char **forms;
+ char **cur;
+ char newword[2 * MAXNORMLEN] = "";
+ char pnewword[2 * MAXNORMLEN] = "";
+ AffixNode *snode = Conf->Suffix,
+ *pnode;
+ int i,
+ j;
+
+ if (wrdlen > MAXNORMLEN)
+ return NULL;
+ cur = forms = (char **) palloc(MAX_NORM * sizeof(char *));
+ *cur = NULL;
+
+
+ /* Check that the word itself is normal form */
+ if (FindWord(Conf, word, 0, flag))
+ {
+ *cur = pstrdup(word);
+ cur++;
+ *cur = NULL;
+ }
+
+ /* Find all other NORMAL forms of the 'word' (check only prefix) */
+ pnode = Conf->Prefix;
+ plevel = 0;
+ while (pnode)
+ {
+ prefix = FinfAffixes(pnode, word, wrdlen, &plevel, FF_PREFIX);
+ if (!prefix)
+ break;
+ for (j = 0; j < prefix->naff; j++)
+ {
+ if (CheckAffix(word, wrdlen, prefix->aff[j], flag, newword, NULL))
+ {
+ /* prefix success */
+ if (FindWord(Conf, newword, prefix->aff[j]->flag, flag))
+ cur += addToResult(forms, cur, newword);
+ }
+ }
+ pnode = prefix->node;
+ }
+
+ /*
+ * Find all other NORMAL forms of the 'word' (check suffix and then
+ * prefix)
+ */
+ while (snode)
+ {
+ int baselen = 0;
+
+ /* find possible suffix */
+ suffix = FinfAffixes(snode, word, wrdlen, &slevel, FF_SUFFIX);
+ if (!suffix)
+ break;
+ /* foreach suffix check affix */
+ for (i = 0; i < suffix->naff; i++)
+ {
+ if (CheckAffix(word, wrdlen, suffix->aff[i], flag, newword, &baselen))
+ {
+ /* suffix success */
+ if (FindWord(Conf, newword, suffix->aff[i]->flag, flag))
+ cur += addToResult(forms, cur, newword);
+
+ /* now we will look changed word with prefixes */
+ pnode = Conf->Prefix;
+ plevel = 0;
+ swrdlen = strlen(newword);
+ while (pnode)
+ {
+ prefix = FinfAffixes(pnode, newword, swrdlen, &plevel, FF_PREFIX);
+ if (!prefix)
+ break;
+ for (j = 0; j < prefix->naff; j++)
+ {
+ if (CheckAffix(newword, swrdlen, prefix->aff[j], flag, pnewword, &baselen))
+ {
+ /* prefix success */
+ int ff = (prefix->aff[j]->flagflags & suffix->aff[i]->flagflags & FF_CROSSPRODUCT) ?
+ 0 : prefix->aff[j]->flag;
+
+ if (FindWord(Conf, pnewword, ff, flag))
+ cur += addToResult(forms, cur, pnewword);
+ }
+ }
+ pnode = prefix->node;
+ }
+ }
+ }
+
+ snode = suffix->node;
+ }
+
+ if (cur == forms)
+ {
+ pfree(forms);
+ return (NULL);
+ }
+ return (forms);
+}
+
+typedef struct SplitVar
+{
+ int nstem;
+ char **stem;
+ struct SplitVar *next;
+} SplitVar;
+
+static int
+CheckCompoundAffixes(CMPDAffix ** ptr, char *word, int len, bool CheckInPlace)
+{
+ bool issuffix;
+
+ if (CheckInPlace)
+ {
+ while ((*ptr)->affix)
+ {
+ if (len > (*ptr)->len && strncmp((*ptr)->affix, word, (*ptr)->len) == 0)
+ {
+ len = (*ptr)->len;
+ issuffix = (*ptr)->issuffix;
+ (*ptr)++;
+ return (issuffix) ? len : 0;
+ }
+ (*ptr)++;
+ }
+ }
+ else
+ {
+ char *affbegin;
+
+ while ((*ptr)->affix)
+ {
+ if (len > (*ptr)->len && (affbegin = strstr(word, (*ptr)->affix)) != NULL)
+ {
+ len = (*ptr)->len + (affbegin - word);
+ issuffix = (*ptr)->issuffix;
+ (*ptr)++;
+ return (issuffix) ? len : 0;
+ }
+ (*ptr)++;
+ }
+ }
+ return -1;
+}
+
+static SplitVar *
+CopyVar(SplitVar * s, int makedup)
+{
+ SplitVar *v = (SplitVar *) palloc(sizeof(SplitVar));
+
+ v->stem = (char **) palloc(sizeof(char *) * (MAX_NORM));
+ v->next = NULL;
+ if (s)
+ {
+ int i;
+
+ v->nstem = s->nstem;
+ for (i = 0; i < s->nstem; i++)
+ v->stem[i] = (makedup) ? pstrdup(s->stem[i]) : s->stem[i];
+ }
+ else
+ v->nstem = 0;
+ return v;
+}
+
+
+static SplitVar *
+SplitToVariants(IspellDict * Conf, SPNode * snode, SplitVar * orig, char *word, int wordlen, int startpos, int minpos)
+{
+ SplitVar *var = NULL;
+ SPNodeData *StopLow,
+ *StopHigh,
+ *StopMiddle = NULL;
+ SPNode *node = (snode) ? snode : Conf->Dictionary;
+ int level = (snode) ? minpos : startpos; /* recursive
+ * minpos==level */
+ int lenaff;
+ CMPDAffix *caff;
+ char *notprobed;
+ int compoundflag = 0;
+
+ notprobed = (char *) palloc(wordlen);
+ memset(notprobed, 1, wordlen);
+ var = CopyVar(orig, 1);
+
+ while (level < wordlen)
+ {
+ /* find word with epenthetic or/and compound affix */
+ caff = Conf->CompoundAffix;
+ while (level > startpos && (lenaff = CheckCompoundAffixes(&caff, word + level, wordlen - level, (node) ? true : false)) >= 0)
+ {
+ /*
+ * there is one of compound affixes, so check word for existings
+ */
+ char buf[MAXNORMLEN];
+ char **subres;
+
+ lenaff = level - startpos + lenaff;
+
+ if (!notprobed[startpos + lenaff - 1])
+ continue;
+
+ if (level + lenaff - 1 <= minpos)
+ continue;
+
+ if (lenaff > 0)
+ memcpy(buf, word + startpos, lenaff);
+ buf[lenaff] = '\0';
+
+ if (level == FF_COMPOUNDBEGIN)
+ compoundflag = FF_COMPOUNDBEGIN;
+ else if (level == wordlen - 1)
+ compoundflag = FF_COMPOUNDLAST;
+ else
+ compoundflag = FF_COMPOUNDMIDDLE;
+ subres = NormalizeSubWord(Conf, buf, compoundflag);
+ if (subres)
+ {
+ /* Yes, it was a word from dictionary */
+ SplitVar *new = CopyVar(var, 0);
+ SplitVar *ptr = var;
+ char **sptr = subres;
+
+ notprobed[startpos + lenaff - 1] = 0;
+
+ while (*sptr)
+ {
+ new->stem[new->nstem] = *sptr;
+ new->nstem++;
+ sptr++;
+ }
+ pfree(subres);
+
+ while (ptr->next)
+ ptr = ptr->next;
+ ptr->next = SplitToVariants(Conf, NULL, new, word, wordlen, startpos + lenaff, startpos + lenaff);
+
+ pfree(new->stem);
+ pfree(new);
+ }
+ }
+
+ if (!node)
+ break;
+
+ StopLow = node->data;
+ StopHigh = node->data + node->length;
+ while (StopLow < StopHigh)
+ {
+ StopMiddle = StopLow + ((StopHigh - StopLow) >> 1);
+ if (StopMiddle->val == ((uint8 *) (word))[level])
+ break;
+ else if (StopMiddle->val < ((uint8 *) (word))[level])
+ StopLow = StopMiddle + 1;
+ else
+ StopHigh = StopMiddle;
+ }
+
+ if (StopLow < StopHigh)
+ {
+ if (level == FF_COMPOUNDBEGIN)
+ compoundflag = FF_COMPOUNDBEGIN;
+ else if (level == wordlen - 1)
+ compoundflag = FF_COMPOUNDLAST;
+ else
+ compoundflag = FF_COMPOUNDMIDDLE;
+
+ /* find infinitive */
+ if (StopMiddle->isword &&
+ (StopMiddle->compoundflag & compoundflag) &&
+ notprobed[level])
+ {
+ /* ok, we found full compoundallowed word */
+ if (level > minpos)
+ {
+ /* and its length more than minimal */
+ if (wordlen == level + 1)
+ {
+ /* well, it was last word */
+ var->stem[var->nstem] = strnduplicate(word + startpos, wordlen - startpos);
+ var->nstem++;
+ pfree(notprobed);
+ return var;
+ }
+ else
+ {
+ /* then we will search more big word at the same point */
+ SplitVar *ptr = var;
+
+ while (ptr->next)
+ ptr = ptr->next;
+ ptr->next = SplitToVariants(Conf, node, var, word, wordlen, startpos, level);
+ /* we can find next word */
+ level++;
+ var->stem[var->nstem] = strnduplicate(word + startpos, level - startpos);
+ var->nstem++;
+ node = Conf->Dictionary;
+ startpos = level;
+ continue;
+ }
+ }
+ }
+ node = StopMiddle->node;
+ }
+ else
+ node = NULL;
+ level++;
+ }
+
+ var->stem[var->nstem] = strnduplicate(word + startpos, wordlen - startpos);
+ var->nstem++;
+ pfree(notprobed);
+ return var;
+}
+
+TSLexeme *
+NINormalizeWord(IspellDict * Conf, char *word)
+{
+ char **res;
+ TSLexeme *lcur = NULL,
+ *lres = NULL;
+ uint16 NVariant = 1;
+
+ res = NormalizeSubWord(Conf, word, 0);
+
+ if (res)
+ {
+ char **ptr = res;
+
+ lcur = lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
+ while (*ptr)
+ {
+ lcur->lexeme = *ptr;
+ lcur->flags = 0;
+ lcur->nvariant = NVariant++;
+ lcur++;
+ ptr++;
+ }
+ lcur->lexeme = NULL;
+ pfree(res);
+ }
+
+ if (Conf->usecompound)
+ {
+ int wordlen = strlen(word);
+ SplitVar *ptr,
+ *var = SplitToVariants(Conf, NULL, NULL, word, wordlen, 0, -1);
+ int i;
+
+ while (var)
+ {
+ if (var->nstem > 1)
+ {
+ char **subres = NormalizeSubWord(Conf, var->stem[var->nstem - 1], FF_COMPOUNDLAST);
+
+ if (subres)
+ {
+ char **subptr = subres;
+
+ if (!lcur)
+ lcur = lres = (TSLexeme *) palloc(MAX_NORM * sizeof(TSLexeme));
+
+ while (*subptr)
+ {
+ for (i = 0; i < var->nstem - 1; i++)
+ {
+ lcur->lexeme = (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]);
+ lcur->flags = 0;
+ lcur->nvariant = NVariant;
+ lcur++;
+ }
+
+ lcur->lexeme = *subptr;
+ lcur->flags = 0;
+ lcur->nvariant = NVariant;
+ lcur++;
+ subptr++;
+ NVariant++;
+ }
+
+ lcur->lexeme = NULL;
+ pfree(subres);
+ var->stem[0] = NULL;
+ pfree(var->stem[var->nstem - 1]);
+ }
+ }
+
+ for (i = 0; i < var->nstem && var->stem[i]; i++)
+ pfree(var->stem[i]);
+ ptr = var->next;
+ pfree(var->stem);
+ pfree(var);
+ var = ptr;
+ }
+ }
+
+ return lres;
+}
diff --git a/src/backend/tsearch/synonym.syn.sample b/src/backend/tsearch/synonym.syn.sample
new file mode 100644
index 00000000000..fdccca102b4
--- /dev/null
+++ b/src/backend/tsearch/synonym.syn.sample
@@ -0,0 +1,3 @@
+skies sky
+booking book
+bookings book
diff --git a/src/backend/tsearch/thesaurus.ths.sample b/src/backend/tsearch/thesaurus.ths.sample
new file mode 100644
index 00000000000..7e7702e2ae4
--- /dev/null
+++ b/src/backend/tsearch/thesaurus.ths.sample
@@ -0,0 +1,20 @@
+#
+# Theasurus config file. Character ':' separates string from replacement, eg
+# sample-words : substitute-words
+#
+# Any substitute-word can be marked by preceding '*' character,
+# which means do not lexize this word
+# Docs: http://www.sai.msu.su/~megera/oddmuse/index.cgi/Thesaurus_dictionary
+
+one two three : *123
+one two : *12
+one : *1
+two : *2
+
+#foo bar : blah blah
+#f bar : fbar
+#e bar : ebar
+#g bar bar : gbarbar
+#asd:sdffff
+#qwerty:qwer wert erty
+
diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c
new file mode 100644
index 00000000000..ee4b61d44bf
--- /dev/null
+++ b/src/backend/tsearch/to_tsany.c
@@ -0,0 +1,363 @@
+/*-------------------------------------------------------------------------
+ *
+ * to_tsany.c
+ * to_ts* function definitions
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/to_tsany.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "catalog/namespace.h"
+#include "tsearch/ts_cache.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+#include "utils/syscache.h"
+
+
+Datum
+get_current_ts_config(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_OID(getTSCurrentConfig(true));
+}
+
+/*
+ * to_tsvector
+ */
+static int
+compareWORD(const void *a, const void *b)
+{
+ if (((ParsedWord *) a)->len == ((ParsedWord *) b)->len)
+ {
+ int res = strncmp(
+ ((ParsedWord *) a)->word,
+ ((ParsedWord *) b)->word,
+ ((ParsedWord *) b)->len);
+
+ if (res == 0)
+ return (((ParsedWord *) a)->pos.pos > ((ParsedWord *) b)->pos.pos) ? 1 : -1;
+ return res;
+ }
+ return (((ParsedWord *) a)->len > ((ParsedWord *) b)->len) ? 1 : -1;
+}
+
+static int
+uniqueWORD(ParsedWord * a, int4 l)
+{
+ ParsedWord *ptr,
+ *res;
+ int tmppos;
+
+ if (l == 1)
+ {
+ tmppos = LIMITPOS(a->pos.pos);
+ a->alen = 2;
+ a->pos.apos = (uint16 *) palloc(sizeof(uint16) * a->alen);
+ a->pos.apos[0] = 1;
+ a->pos.apos[1] = tmppos;
+ return l;
+ }
+
+ res = a;
+ ptr = a + 1;
+
+ qsort((void *) a, l, sizeof(ParsedWord), compareWORD);
+ tmppos = LIMITPOS(a->pos.pos);
+ a->alen = 2;
+ a->pos.apos = (uint16 *) palloc(sizeof(uint16) * a->alen);
+ a->pos.apos[0] = 1;
+ a->pos.apos[1] = tmppos;
+
+ while (ptr - a < l)
+ {
+ if (!(ptr->len == res->len &&
+ strncmp(ptr->word, res->word, res->len) == 0))
+ {
+ res++;
+ res->len = ptr->len;
+ res->word = ptr->word;
+ tmppos = LIMITPOS(ptr->pos.pos);
+ res->alen = 2;
+ res->pos.apos = (uint16 *) palloc(sizeof(uint16) * res->alen);
+ res->pos.apos[0] = 1;
+ res->pos.apos[1] = tmppos;
+ }
+ else
+ {
+ pfree(ptr->word);
+ if (res->pos.apos[0] < MAXNUMPOS - 1 && res->pos.apos[res->pos.apos[0]] != MAXENTRYPOS - 1)
+ {
+ if (res->pos.apos[0] + 1 >= res->alen)
+ {
+ res->alen *= 2;
+ res->pos.apos = (uint16 *) repalloc(res->pos.apos, sizeof(uint16) * res->alen);
+ }
+ if (res->pos.apos[0] == 0 || res->pos.apos[res->pos.apos[0]] != LIMITPOS(ptr->pos.pos))
+ {
+ res->pos.apos[res->pos.apos[0] + 1] = LIMITPOS(ptr->pos.pos);
+ res->pos.apos[0]++;
+ }
+ }
+ }
+ ptr++;
+ }
+
+ return res + 1 - a;
+}
+
+/*
+ * make value of tsvector, given parsed text
+ */
+TSVector
+make_tsvector(ParsedText *prs)
+{
+ int4 i,
+ j,
+ lenstr = 0,
+ totallen;
+ TSVector in;
+ WordEntry *ptr;
+ char *str,
+ *cur;
+
+ prs->curwords = uniqueWORD(prs->words, prs->curwords);
+ for (i = 0; i < prs->curwords; i++)
+ {
+ lenstr += SHORTALIGN(prs->words[i].len);
+
+ if (prs->words[i].alen)
+ lenstr += sizeof(uint16) + prs->words[i].pos.apos[0] * sizeof(WordEntryPos);
+ }
+
+ totallen = CALCDATASIZE(prs->curwords, lenstr);
+ in = (TSVector) palloc0(totallen);
+ SET_VARSIZE(in, totallen);
+ in->size = prs->curwords;
+
+ ptr = ARRPTR(in);
+ cur = str = STRPTR(in);
+ for (i = 0; i < prs->curwords; i++)
+ {
+ ptr->len = prs->words[i].len;
+ if (cur - str > MAXSTRPOS)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("string is too long for tsvector")));
+ ptr->pos = cur - str;
+ memcpy((void *) cur, (void *) prs->words[i].word, prs->words[i].len);
+ pfree(prs->words[i].word);
+ cur += SHORTALIGN(prs->words[i].len);
+ if (prs->words[i].alen)
+ {
+ WordEntryPos *wptr;
+
+ ptr->haspos = 1;
+ *(uint16 *) cur = prs->words[i].pos.apos[0];
+ wptr = POSDATAPTR(in, ptr);
+ for (j = 0; j < *(uint16 *) cur; j++)
+ {
+ WEP_SETWEIGHT(wptr[j], 0);
+ WEP_SETPOS(wptr[j], prs->words[i].pos.apos[j + 1]);
+ }
+ cur += sizeof(uint16) + prs->words[i].pos.apos[0] * sizeof(WordEntryPos);
+ pfree(prs->words[i].pos.apos);
+ }
+ else
+ ptr->haspos = 0;
+ ptr++;
+ }
+ pfree(prs->words);
+ return in;
+}
+
+Datum
+to_tsvector_byid(PG_FUNCTION_ARGS)
+{
+ Oid cfgId = PG_GETARG_OID(0);
+ text *in = PG_GETARG_TEXT_P(1);
+ ParsedText prs;
+ TSVector out;
+
+ prs.lenwords = (VARSIZE(in) - VARHDRSZ) / 6; /* just estimation of
+ * word's number */
+ if (prs.lenwords == 0)
+ prs.lenwords = 2;
+ prs.curwords = 0;
+ prs.pos = 0;
+ prs.words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs.lenwords);
+
+ parsetext(cfgId, &prs, VARDATA(in), VARSIZE(in) - VARHDRSZ);
+ PG_FREE_IF_COPY(in, 1);
+
+ if (prs.curwords)
+ out = make_tsvector(&prs);
+ else
+ {
+ pfree(prs.words);
+ out = palloc(CALCDATASIZE(0, 0));
+ SET_VARSIZE(out, CALCDATASIZE(0, 0));
+ out->size = 0;
+ }
+
+ PG_RETURN_POINTER(out);
+}
+
+Datum
+to_tsvector(PG_FUNCTION_ARGS)
+{
+ text *in = PG_GETARG_TEXT_P(0);
+ Oid cfgId;
+
+ cfgId = getTSCurrentConfig(true);
+ PG_RETURN_DATUM(DirectFunctionCall2(to_tsvector_byid,
+ ObjectIdGetDatum(cfgId),
+ PointerGetDatum(in)));
+}
+
+/*
+ * to_tsquery
+ */
+
+
+/*
+ * This function is used for morph parsing
+ */
+static void
+pushval_morph(TSQueryParserState * state, int typeval, char *strval, int lenval, int2 weight)
+{
+ int4 count = 0;
+ ParsedText prs;
+ uint32 variant,
+ pos,
+ cntvar = 0,
+ cntpos = 0,
+ cnt = 0;
+
+ prs.lenwords = 4;
+ prs.curwords = 0;
+ prs.pos = 0;
+ prs.words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs.lenwords);
+
+ parsetext(state->cfg_id, &prs, strval, lenval);
+
+ if (prs.curwords > 0)
+ {
+
+ while (count < prs.curwords)
+ {
+ pos = prs.words[count].pos.pos;
+ cntvar = 0;
+ while (count < prs.curwords && pos == prs.words[count].pos.pos)
+ {
+ variant = prs.words[count].nvariant;
+
+ cnt = 0;
+ while (count < prs.curwords && pos == prs.words[count].pos.pos && variant == prs.words[count].nvariant)
+ {
+
+ pushval_asis(state, VAL, prs.words[count].word, prs.words[count].len, weight);
+ pfree(prs.words[count].word);
+ if (cnt)
+ pushquery(state, OPR, (int4) '&', 0, 0, 0);
+ cnt++;
+ count++;
+ }
+
+ if (cntvar)
+ pushquery(state, OPR, (int4) '|', 0, 0, 0);
+ cntvar++;
+ }
+
+ if (cntpos)
+ pushquery(state, OPR, (int4) '&', 0, 0, 0);
+
+ cntpos++;
+ }
+
+ pfree(prs.words);
+
+ }
+ else
+ pushval_asis(state, VALSTOP, NULL, 0, 0);
+}
+
+Datum
+to_tsquery_byid(PG_FUNCTION_ARGS)
+{
+ Oid cfgid = PG_GETARG_OID(0);
+ text *in = PG_GETARG_TEXT_P(1);
+ TSQuery query;
+ QueryItem *res;
+ int4 len;
+
+ query = parse_tsquery(TextPGetCString(in), pushval_morph, cfgid, false);
+
+ if (query->size == 0)
+ PG_RETURN_TSQUERY(query);
+
+ res = clean_fakeval(GETQUERY(query), &len);
+ if (!res)
+ {
+ SET_VARSIZE(query, HDRSIZETQ);
+ query->size = 0;
+ PG_RETURN_POINTER(query);
+ }
+ memcpy((void *) GETQUERY(query), (void *) res, len * sizeof(QueryItem));
+ pfree(res);
+ PG_RETURN_TSQUERY(query);
+}
+
+Datum
+to_tsquery(PG_FUNCTION_ARGS)
+{
+ text *in = PG_GETARG_TEXT_P(0);
+ Oid cfgId;
+
+ cfgId = getTSCurrentConfig(true);
+ PG_RETURN_DATUM(DirectFunctionCall2(to_tsquery_byid,
+ ObjectIdGetDatum(cfgId),
+ PointerGetDatum(in)));
+}
+
+Datum
+plainto_tsquery_byid(PG_FUNCTION_ARGS)
+{
+ Oid cfgid = PG_GETARG_OID(0);
+ text *in = PG_GETARG_TEXT_P(1);
+ TSQuery query;
+ QueryItem *res;
+ int4 len;
+
+ query = parse_tsquery(TextPGetCString(in), pushval_morph, cfgid, true);
+
+ if (query->size == 0)
+ PG_RETURN_TSQUERY(query);
+
+ res = clean_fakeval(GETQUERY(query), &len);
+ if (!res)
+ {
+ SET_VARSIZE(query, HDRSIZETQ);
+ query->size = 0;
+ PG_RETURN_POINTER(query);
+ }
+ memcpy((void *) GETQUERY(query), (void *) res, len * sizeof(QueryItem));
+ pfree(res);
+ PG_RETURN_POINTER(query);
+}
+
+Datum
+plainto_tsquery(PG_FUNCTION_ARGS)
+{
+ text *in = PG_GETARG_TEXT_P(0);
+ Oid cfgId;
+
+ cfgId = getTSCurrentConfig(true);
+ PG_RETURN_DATUM(DirectFunctionCall2(plainto_tsquery_byid,
+ ObjectIdGetDatum(cfgId),
+ PointerGetDatum(in)));
+}
diff --git a/src/backend/tsearch/ts_locale.c b/src/backend/tsearch/ts_locale.c
new file mode 100644
index 00000000000..c822f086e0a
--- /dev/null
+++ b/src/backend/tsearch/ts_locale.c
@@ -0,0 +1,241 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_locale.c
+ * locale compatiblility layer for tsearch
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/ts_locale.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_public.h"
+
+#ifdef TS_USE_WIDE
+
+#ifdef WIN32
+
+size_t
+wchar2char(char *to, const wchar_t *from, size_t len)
+{
+ if (len == 0)
+ return 0;
+
+ if (GetDatabaseEncoding() == PG_UTF8)
+ {
+ int r;
+
+ r = WideCharToMultiByte(CP_UTF8, 0, from, -1, to, len,
+ NULL, NULL);
+
+ if (r == 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+ errmsg("UTF-16 to UTF-8 translation failed: %lu",
+ GetLastError())));
+ Assert(r <= len);
+
+ return r;
+ }
+
+ return wcstombs(to, from, len);
+}
+#endif /* WIN32 */
+
+size_t
+char2wchar(wchar_t *to, const char *from, size_t len)
+{
+ if (len == 0)
+ return 0;
+
+#ifdef WIN32
+ if (GetDatabaseEncoding() == PG_UTF8)
+ {
+ int r;
+
+ r = MultiByteToWideChar(CP_UTF8, 0, from, len, to, len);
+
+ if (!r)
+ {
+ pg_verifymbstr(from, len, false);
+ ereport(ERROR,
+ (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+ errmsg("invalid multibyte character for locale"),
+ errhint("The server's LC_CTYPE locale is probably incompatible with the database encoding.")));
+ }
+
+ Assert(r <= len);
+
+ return r;
+ }
+ else
+#endif /* WIN32 */
+ if (lc_ctype_is_c())
+ {
+ /*
+ * pg_mb2wchar_with_len always adds trailing '\0', so 'to' should be
+ * allocated with sufficient space
+ */
+ return pg_mb2wchar_with_len(from, (pg_wchar *) to, len);
+ }
+ else
+ {
+ /*
+ * mbstowcs require ending '\0'
+ */
+ char *str = pnstrdup(from, len);
+ size_t tolen;
+
+ tolen = mbstowcs(to, str, len);
+ pfree(str);
+
+ return tolen;
+ }
+}
+
+int
+_t_isalpha(const char *ptr)
+{
+ wchar_t character[2];
+
+ if (lc_ctype_is_c())
+ return isalpha(TOUCHAR(ptr));
+
+ char2wchar(character, ptr, 1);
+
+ return iswalpha((wint_t) *character);
+}
+
+int
+_t_isprint(const char *ptr)
+{
+ wchar_t character[2];
+
+ if (lc_ctype_is_c())
+ return isprint(TOUCHAR(ptr));
+
+ char2wchar(character, ptr, 1);
+
+ return iswprint((wint_t) *character);
+}
+#endif /* TS_USE_WIDE */
+
+/*
+ * Convert C-string from UTF8 to server encoding and
+ * lower it
+ */
+char *
+recode_and_lowerstr(char *str)
+{
+ char *recoded;
+ char *ret;
+
+ recoded = (char *) pg_do_encoding_conversion((unsigned char *) str, strlen(str),
+ PG_UTF8, GetDatabaseEncoding());
+
+ if (recoded == NULL)
+ elog(ERROR, "encoding conversion failed");
+
+ ret = lowerstr(recoded);
+
+ if (recoded != str)
+ pfree(recoded);
+
+ return ret;
+}
+
+char *
+lowerstr(char *str)
+{
+ return lowerstr_with_len(str, strlen(str));
+}
+
+char *
+lowerstr_with_len(char *str, int len)
+{
+ char *ptr = str;
+ char *out;
+
+ if (len == 0)
+ return pstrdup("");
+
+#ifdef TS_USE_WIDE
+
+ /*
+ * Use wide char code only when max encoding length > 1 and ctype != C.
+ * Some operating systems fail with multi-byte encodings and a C locale.
+ * Also, for a C locale there is no need to process as multibyte. From
+ * backend/utils/adt/oracle_compat.c Teodor
+ */
+ if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
+ {
+ wchar_t *wstr,
+ *wptr;
+ int wlen;
+
+ /*
+ * alloc number of wchar_t for worst case, len contains number of
+ * bytes <= number of characters and alloc 1 wchar_t for 0, because
+ * wchar2char(wcstombs in really) wants zero-terminated string
+ */
+ wptr = wstr = (wchar_t *) palloc(sizeof(wchar_t) * (len + 1));
+
+ /*
+ * str SHOULD be cstring, so wlen contains number of converted
+ * character
+ */
+ wlen = char2wchar(wstr, str, len);
+ if (wlen < 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+ errmsg("translation failed from server encoding to wchar_t")));
+
+ Assert(wlen <= len);
+ wstr[wlen] = 0;
+
+ while (*wptr)
+ {
+ *wptr = towlower((wint_t) *wptr);
+ wptr++;
+ }
+
+ /*
+ * Alloc result string for worst case + '\0'
+ */
+ len = sizeof(char) * pg_database_encoding_max_length() *(wlen + 1);
+ out = (char *) palloc(len);
+
+ /*
+ * wlen now is number of bytes which is always >= number of characters
+ */
+ wlen = wchar2char(out, wstr, len);
+ pfree(wstr);
+
+ if (wlen < 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+ errmsg("translation failed from wchar_t to server encoding %d", errno)));
+ Assert(wlen <= len);
+ out[wlen] = '\0';
+ }
+ else
+#endif
+ {
+ char *outptr;
+
+ outptr = out = (char *) palloc(sizeof(char) * (len + 1));
+ while (*ptr && ptr - str < len)
+ {
+ *outptr++ = tolower(*(unsigned char *) ptr);
+ ptr++;
+ }
+ *outptr = '\0';
+ }
+
+ return out;
+}
diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c
new file mode 100644
index 00000000000..f286a61fb0d
--- /dev/null
+++ b/src/backend/tsearch/ts_parse.c
@@ -0,0 +1,626 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_parse.c
+ * main parse functions for tsearch
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/ts_parse.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "tsearch/ts_cache.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+
+#define IGNORE_LONGLEXEME 1
+
+/*
+ * Lexize subsystem
+ */
+
+typedef struct ParsedLex
+{
+ int type;
+ char *lemm;
+ int lenlemm;
+ bool resfollow;
+ struct ParsedLex *next;
+} ParsedLex;
+
+typedef struct ListParsedLex
+{
+ ParsedLex *head;
+ ParsedLex *tail;
+} ListParsedLex;
+
+typedef struct
+{
+ TSConfigCacheEntry *cfg;
+ Oid curDictId;
+ int posDict;
+ DictSubState dictState;
+ ParsedLex *curSub;
+ ListParsedLex towork; /* current list to work */
+ ListParsedLex waste; /* list of lexemes that already lexized */
+
+ /*
+ * fields to store last variant to lexize (basically, thesaurus or similar
+ * to, which wants several lexemes
+ */
+
+ ParsedLex *lastRes;
+ TSLexeme *tmpRes;
+} LexizeData;
+
+static void
+LexizeInit(LexizeData * ld, TSConfigCacheEntry * cfg)
+{
+ ld->cfg = cfg;
+ ld->curDictId = InvalidOid;
+ ld->posDict = 0;
+ ld->towork.head = ld->towork.tail = ld->curSub = NULL;
+ ld->waste.head = ld->waste.tail = NULL;
+ ld->lastRes = NULL;
+ ld->tmpRes = NULL;
+}
+
+static void
+LPLAddTail(ListParsedLex * list, ParsedLex * newpl)
+{
+ if (list->tail)
+ {
+ list->tail->next = newpl;
+ list->tail = newpl;
+ }
+ else
+ list->head = list->tail = newpl;
+ newpl->next = NULL;
+}
+
+static ParsedLex *
+LPLRemoveHead(ListParsedLex * list)
+{
+ ParsedLex *res = list->head;
+
+ if (list->head)
+ list->head = list->head->next;
+
+ if (list->head == NULL)
+ list->tail = NULL;
+
+ return res;
+}
+
+static void
+LexizeAddLemm(LexizeData * ld, int type, char *lemm, int lenlemm)
+{
+ ParsedLex *newpl = (ParsedLex *) palloc(sizeof(ParsedLex));
+
+ newpl = (ParsedLex *) palloc(sizeof(ParsedLex));
+ newpl->type = type;
+ newpl->lemm = lemm;
+ newpl->lenlemm = lenlemm;
+ LPLAddTail(&ld->towork, newpl);
+ ld->curSub = ld->towork.tail;
+}
+
+static void
+RemoveHead(LexizeData * ld)
+{
+ LPLAddTail(&ld->waste, LPLRemoveHead(&ld->towork));
+
+ ld->posDict = 0;
+}
+
+static void
+setCorrLex(LexizeData * ld, ParsedLex ** correspondLexem)
+{
+ if (correspondLexem)
+ {
+ *correspondLexem = ld->waste.head;
+ }
+ else
+ {
+ ParsedLex *tmp,
+ *ptr = ld->waste.head;
+
+ while (ptr)
+ {
+ tmp = ptr->next;
+ pfree(ptr);
+ ptr = tmp;
+ }
+ }
+ ld->waste.head = ld->waste.tail = NULL;
+}
+
+static void
+moveToWaste(LexizeData * ld, ParsedLex * stop)
+{
+ bool go = true;
+
+ while (ld->towork.head && go)
+ {
+ if (ld->towork.head == stop)
+ {
+ ld->curSub = stop->next;
+ go = false;
+ }
+ RemoveHead(ld);
+ }
+}
+
+static void
+setNewTmpRes(LexizeData * ld, ParsedLex * lex, TSLexeme * res)
+{
+ if (ld->tmpRes)
+ {
+ TSLexeme *ptr;
+
+ for (ptr = ld->tmpRes; ptr->lexeme; ptr++)
+ pfree(ptr->lexeme);
+ pfree(ld->tmpRes);
+ }
+ ld->tmpRes = res;
+ ld->lastRes = lex;
+}
+
+static TSLexeme *
+LexizeExec(LexizeData * ld, ParsedLex ** correspondLexem)
+{
+ int i;
+ ListDictionary *map;
+ TSDictionaryCacheEntry *dict;
+ TSLexeme *res;
+
+ if (ld->curDictId == InvalidOid)
+ {
+ /*
+ * usial mode: dictionary wants only one word, but we should keep in
+ * mind that we should go through all stack
+ */
+
+ while (ld->towork.head)
+ {
+ ParsedLex *curVal = ld->towork.head;
+
+ map = ld->cfg->map + curVal->type;
+
+ if (curVal->type == 0 || curVal->type >= ld->cfg->lenmap || map->len == 0)
+ {
+ /* skip this type of lexeme */
+ RemoveHead(ld);
+ continue;
+ }
+
+ for (i = ld->posDict; i < map->len; i++)
+ {
+ dict = lookup_ts_dictionary_cache(map->dictIds[i]);
+
+ ld->dictState.isend = ld->dictState.getnext = false;
+ ld->dictState.private = NULL;
+ res = (TSLexeme *) DatumGetPointer(FunctionCall4(
+ &(dict->lexize),
+ PointerGetDatum(dict->dictData),
+ PointerGetDatum(curVal->lemm),
+ Int32GetDatum(curVal->lenlemm),
+ PointerGetDatum(&ld->dictState)
+ ));
+
+ if (ld->dictState.getnext)
+ {
+ /*
+ * dictionary wants next word, so setup and store current
+ * position and go to multiword mode
+ */
+
+ ld->curDictId = DatumGetObjectId(map->dictIds[i]);
+ ld->posDict = i + 1;
+ ld->curSub = curVal->next;
+ if (res)
+ setNewTmpRes(ld, curVal, res);
+ return LexizeExec(ld, correspondLexem);
+ }
+
+ if (!res) /* dictionary doesn't know this lexeme */
+ continue;
+
+ RemoveHead(ld);
+ setCorrLex(ld, correspondLexem);
+ return res;
+ }
+
+ RemoveHead(ld);
+ }
+ }
+ else
+ { /* curDictId is valid */
+ dict = lookup_ts_dictionary_cache(ld->curDictId);
+
+ /*
+ * Dictionary ld->curDictId asks us about following words
+ */
+
+ while (ld->curSub)
+ {
+ ParsedLex *curVal = ld->curSub;
+
+ map = ld->cfg->map + curVal->type;
+
+ if (curVal->type != 0)
+ {
+ bool dictExists = false;
+
+ if (curVal->type >= ld->cfg->lenmap || map->len == 0)
+ {
+ /* skip this type of lexeme */
+ ld->curSub = curVal->next;
+ continue;
+ }
+
+ /*
+ * We should be sure that current type of lexeme is recognized
+ * by our dictinonary: we just check is it exist in list of
+ * dictionaries ?
+ */
+ for (i = 0; i < map->len && !dictExists; i++)
+ if (ld->curDictId == DatumGetObjectId(map->dictIds[i]))
+ dictExists = true;
+
+ if (!dictExists)
+ {
+ /*
+ * Dictionary can't work with current tpe of lexeme,
+ * return to basic mode and redo all stored lexemes
+ */
+ ld->curDictId = InvalidOid;
+ return LexizeExec(ld, correspondLexem);
+ }
+ }
+
+ ld->dictState.isend = (curVal->type == 0) ? true : false;
+ ld->dictState.getnext = false;
+
+ res = (TSLexeme *) DatumGetPointer(FunctionCall4(
+ &(dict->lexize),
+ PointerGetDatum(dict->dictData),
+ PointerGetDatum(curVal->lemm),
+ Int32GetDatum(curVal->lenlemm),
+ PointerGetDatum(&ld->dictState)
+ ));
+
+ if (ld->dictState.getnext)
+ {
+ /* Dictionary wants one more */
+ ld->curSub = curVal->next;
+ if (res)
+ setNewTmpRes(ld, curVal, res);
+ continue;
+ }
+
+ if (res || ld->tmpRes)
+ {
+ /*
+ * Dictionary normalizes lexemes, so we remove from stack all
+ * used lexemes , return to basic mode and redo end of stack
+ * (if it exists)
+ */
+ if (res)
+ {
+ moveToWaste(ld, ld->curSub);
+ }
+ else
+ {
+ res = ld->tmpRes;
+ moveToWaste(ld, ld->lastRes);
+ }
+
+ /* reset to initial state */
+ ld->curDictId = InvalidOid;
+ ld->posDict = 0;
+ ld->lastRes = NULL;
+ ld->tmpRes = NULL;
+ setCorrLex(ld, correspondLexem);
+ return res;
+ }
+
+ /*
+ * Dict don't want next lexem and didn't recognize anything, redo
+ * from ld->towork.head
+ */
+ ld->curDictId = InvalidOid;
+ return LexizeExec(ld, correspondLexem);
+ }
+ }
+
+ setCorrLex(ld, correspondLexem);
+ return NULL;
+}
+
+/*
+ * Parse string and lexize words
+ */
+void
+parsetext(Oid cfgId, ParsedText * prs, char *buf, int4 buflen)
+{
+ int type,
+ lenlemm;
+ char *lemm = NULL;
+ LexizeData ldata;
+ TSLexeme *norms;
+ TSConfigCacheEntry *cfg;
+ TSParserCacheEntry *prsobj;
+ void *prsdata;
+
+ cfg = lookup_ts_config_cache(cfgId);
+ prsobj = lookup_ts_parser_cache(cfg->prsId);
+
+ prsdata = (void *) DatumGetPointer(FunctionCall2(&prsobj->prsstart,
+ PointerGetDatum(buf),
+ Int32GetDatum(buflen)));
+
+ LexizeInit(&ldata, cfg);
+
+ do
+ {
+ type = DatumGetInt32(FunctionCall3(&(prsobj->prstoken),
+ PointerGetDatum(prsdata),
+ PointerGetDatum(&lemm),
+ PointerGetDatum(&lenlemm)));
+
+ if (type > 0 && lenlemm >= MAXSTRLEN)
+ {
+#ifdef IGNORE_LONGLEXEME
+ ereport(NOTICE,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("word is too long to be indexed"),
+ errdetail("Words longer than %d characters are ignored.",
+ MAXSTRLEN)));
+ continue;
+#else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("word is too long to be indexed")));
+#endif
+ }
+
+ LexizeAddLemm(&ldata, type, lemm, lenlemm);
+
+ while ((norms = LexizeExec(&ldata, NULL)) != NULL)
+ {
+ TSLexeme *ptr = norms;
+
+ prs->pos++; /* set pos */
+
+ while (ptr->lexeme)
+ {
+ if (prs->curwords == prs->lenwords)
+ {
+ prs->lenwords *= 2;
+ prs->words = (ParsedWord *) repalloc((void *) prs->words, prs->lenwords * sizeof(ParsedWord));
+ }
+
+ if (ptr->flags & TSL_ADDPOS)
+ prs->pos++;
+ prs->words[prs->curwords].len = strlen(ptr->lexeme);
+ prs->words[prs->curwords].word = ptr->lexeme;
+ prs->words[prs->curwords].nvariant = ptr->nvariant;
+ prs->words[prs->curwords].alen = 0;
+ prs->words[prs->curwords].pos.pos = LIMITPOS(prs->pos);
+ ptr++;
+ prs->curwords++;
+ }
+ pfree(norms);
+ }
+ } while (type > 0);
+
+ FunctionCall1(&(prsobj->prsend), PointerGetDatum(prsdata));
+}
+
+/*
+ * Headline framework
+ */
+static void
+hladdword(HeadlineText * prs, char *buf, int4 buflen, int type)
+{
+ while (prs->curwords >= prs->lenwords)
+ {
+ prs->lenwords *= 2;
+ prs->words = (HeadlineWord *) repalloc((void *) prs->words, prs->lenwords * sizeof(HeadlineWord));
+ }
+ memset(&(prs->words[prs->curwords]), 0, sizeof(HeadlineWord));
+ prs->words[prs->curwords].type = (uint8) type;
+ prs->words[prs->curwords].len = buflen;
+ prs->words[prs->curwords].word = palloc(buflen);
+ memcpy(prs->words[prs->curwords].word, buf, buflen);
+ prs->curwords++;
+}
+
+static void
+hlfinditem(HeadlineText * prs, TSQuery query, char *buf, int buflen)
+{
+ int i;
+ QueryItem *item = GETQUERY(query);
+ HeadlineWord *word;
+
+ while (prs->curwords + query->size >= prs->lenwords)
+ {
+ prs->lenwords *= 2;
+ prs->words = (HeadlineWord *) repalloc((void *) prs->words, prs->lenwords * sizeof(HeadlineWord));
+ }
+
+ word = &(prs->words[prs->curwords - 1]);
+ for (i = 0; i < query->size; i++)
+ {
+ if (item->type == VAL && item->length == buflen && strncmp(GETOPERAND(query) + item->distance, buf, buflen) == 0)
+ {
+ if (word->item)
+ {
+ memcpy(&(prs->words[prs->curwords]), word, sizeof(HeadlineWord));
+ prs->words[prs->curwords].item = item;
+ prs->words[prs->curwords].repeated = 1;
+ prs->curwords++;
+ }
+ else
+ word->item = item;
+ }
+ item++;
+ }
+}
+
+static void
+addHLParsedLex(HeadlineText * prs, TSQuery query, ParsedLex * lexs, TSLexeme * norms)
+{
+ ParsedLex *tmplexs;
+ TSLexeme *ptr;
+
+ while (lexs)
+ {
+
+ if (lexs->type > 0)
+ hladdword(prs, lexs->lemm, lexs->lenlemm, lexs->type);
+
+ ptr = norms;
+ while (ptr && ptr->lexeme)
+ {
+ hlfinditem(prs, query, ptr->lexeme, strlen(ptr->lexeme));
+ ptr++;
+ }
+
+ tmplexs = lexs->next;
+ pfree(lexs);
+ lexs = tmplexs;
+ }
+
+ if (norms)
+ {
+ ptr = norms;
+ while (ptr->lexeme)
+ {
+ pfree(ptr->lexeme);
+ ptr++;
+ }
+ pfree(norms);
+ }
+}
+
+void
+hlparsetext(Oid cfgId, HeadlineText * prs, TSQuery query, char *buf, int4 buflen)
+{
+ int type,
+ lenlemm;
+ char *lemm = NULL;
+ LexizeData ldata;
+ TSLexeme *norms;
+ ParsedLex *lexs;
+ TSConfigCacheEntry *cfg;
+ TSParserCacheEntry *prsobj;
+ void *prsdata;
+
+ cfg = lookup_ts_config_cache(cfgId);
+ prsobj = lookup_ts_parser_cache(cfg->prsId);
+
+ prsdata = (void *) DatumGetPointer(FunctionCall2(&(prsobj->prsstart),
+ PointerGetDatum(buf),
+ Int32GetDatum(buflen)));
+
+ LexizeInit(&ldata, cfg);
+
+ do
+ {
+ type = DatumGetInt32(FunctionCall3(&(prsobj->prstoken),
+ PointerGetDatum(prsdata),
+ PointerGetDatum(&lemm),
+ PointerGetDatum(&lenlemm)));
+
+ if (type > 0 && lenlemm >= MAXSTRLEN)
+ {
+#ifdef IGNORE_LONGLEXEME
+ ereport(NOTICE,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("word is too long to be indexed"),
+ errdetail("Words longer than %d characters are ignored.",
+ MAXSTRLEN)));
+ continue;
+#else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("word is too long to be indexed")));
+#endif
+ }
+
+ LexizeAddLemm(&ldata, type, lemm, lenlemm);
+
+ do
+ {
+ if ((norms = LexizeExec(&ldata, &lexs)) != NULL)
+ addHLParsedLex(prs, query, lexs, norms);
+ else
+ addHLParsedLex(prs, query, lexs, NULL);
+ } while (norms);
+
+ } while (type > 0);
+
+ FunctionCall1(&(prsobj->prsend), PointerGetDatum(prsdata));
+}
+
+text *
+generatHeadline(HeadlineText * prs)
+{
+ text *out;
+ int len = 128;
+ char *ptr;
+ HeadlineWord *wrd = prs->words;
+
+ out = (text *) palloc(len);
+ ptr = ((char *) out) + VARHDRSZ;
+
+ while (wrd - prs->words < prs->curwords)
+ {
+ while (wrd->len + prs->stopsellen + prs->startsellen + (ptr - ((char *) out)) >= len)
+ {
+ int dist = ptr - ((char *) out);
+
+ len *= 2;
+ out = (text *) repalloc(out, len);
+ ptr = ((char *) out) + dist;
+ }
+
+ if (wrd->in && !wrd->repeated)
+ {
+ if (wrd->replace)
+ {
+ *ptr = ' ';
+ ptr++;
+ }
+ else
+ {
+ if (wrd->selected)
+ {
+ memcpy(ptr, prs->startsel, prs->startsellen);
+ ptr += prs->startsellen;
+ }
+ memcpy(ptr, wrd->word, wrd->len);
+ ptr += wrd->len;
+ if (wrd->selected)
+ {
+ memcpy(ptr, prs->stopsel, prs->stopsellen);
+ ptr += prs->stopsellen;
+ }
+ }
+ }
+ else if (!wrd->repeated)
+ pfree(wrd->word);
+
+ wrd++;
+ }
+
+ SET_VARSIZE(out, ptr - ((char *) out));
+ return out;
+}
diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c
new file mode 100644
index 00000000000..bb0a75ca85a
--- /dev/null
+++ b/src/backend/tsearch/ts_utils.c
@@ -0,0 +1,330 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_utils.c
+ * various support functions
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/ts_utils.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include <ctype.h>
+
+#include "miscadmin.h"
+#include "storage/fd.h"
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+
+
+#define CS_WAITKEY 0
+#define CS_INKEY 1
+#define CS_WAITEQ 2
+#define CS_WAITVALUE 3
+#define CS_INVALUE 4
+#define CS_IN2VALUE 5
+#define CS_WAITDELIM 6
+#define CS_INESC 7
+#define CS_IN2ESC 8
+
+static char *
+nstrdup(char *ptr, int len)
+{
+ char *res = palloc(len + 1),
+ *cptr;
+
+ memcpy(res, ptr, len);
+ res[len] = '\0';
+ cptr = ptr = res;
+ while (*ptr)
+ {
+ if (t_iseq(ptr, '\\'))
+ ptr++;
+ COPYCHAR(cptr, ptr);
+ cptr += pg_mblen(ptr);
+ ptr += pg_mblen(ptr);
+ }
+ *cptr = '\0';
+
+ return res;
+}
+
+/*
+ * Parse a parameter string consisting of key = value clauses
+ */
+void
+parse_keyvalpairs(text *in, Map ** m)
+{
+ Map *mptr;
+ char *ptr = VARDATA(in),
+ *begin = NULL;
+ char num = 0;
+ int state = CS_WAITKEY;
+
+ while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
+ {
+ if (t_iseq(ptr, ','))
+ num++;
+ ptr += pg_mblen(ptr);
+ }
+
+ *m = mptr = (Map *) palloc(sizeof(Map) * (num + 2));
+ memset(mptr, 0, sizeof(Map) * (num + 2));
+ ptr = VARDATA(in);
+ while (ptr - VARDATA(in) < VARSIZE(in) - VARHDRSZ)
+ {
+ if (state == CS_WAITKEY)
+ {
+ if (t_isalpha(ptr))
+ {
+ begin = ptr;
+ state = CS_INKEY;
+ }
+ else if (!t_isspace(ptr))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("invalid parameter list format: \"%s\"",
+ TextPGetCString(in))));
+ }
+ else if (state == CS_INKEY)
+ {
+ if (t_isspace(ptr))
+ {
+ mptr->key = nstrdup(begin, ptr - begin);
+ state = CS_WAITEQ;
+ }
+ else if (t_iseq(ptr, '='))
+ {
+ mptr->key = nstrdup(begin, ptr - begin);
+ state = CS_WAITVALUE;
+ }
+ else if (!t_isalpha(ptr))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("invalid parameter list format: \"%s\"",
+ TextPGetCString(in))));
+ }
+ else if (state == CS_WAITEQ)
+ {
+ if (t_iseq(ptr, '='))
+ state = CS_WAITVALUE;
+ else if (!t_isspace(ptr))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("invalid parameter list format: \"%s\"",
+ TextPGetCString(in))));
+ }
+ else if (state == CS_WAITVALUE)
+ {
+ if (t_iseq(ptr, '"'))
+ {
+ begin = ptr + 1;
+ state = CS_INVALUE;
+ }
+ else if (!t_isspace(ptr))
+ {
+ begin = ptr;
+ state = CS_IN2VALUE;
+ }
+ }
+ else if (state == CS_INVALUE)
+ {
+ if (t_iseq(ptr, '"'))
+ {
+ mptr->value = nstrdup(begin, ptr - begin);
+ mptr++;
+ state = CS_WAITDELIM;
+ }
+ else if (t_iseq(ptr, '\\'))
+ state = CS_INESC;
+ }
+ else if (state == CS_IN2VALUE)
+ {
+ if (t_isspace(ptr) || t_iseq(ptr, ','))
+ {
+ mptr->value = nstrdup(begin, ptr - begin);
+ mptr++;
+ state = (t_iseq(ptr, ',')) ? CS_WAITKEY : CS_WAITDELIM;
+ }
+ else if (t_iseq(ptr, '\\'))
+ state = CS_INESC;
+ }
+ else if (state == CS_WAITDELIM)
+ {
+ if (t_iseq(ptr, ','))
+ state = CS_WAITKEY;
+ else if (!t_isspace(ptr))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("invalid parameter list format: \"%s\"",
+ TextPGetCString(in))));
+ }
+ else if (state == CS_INESC)
+ state = CS_INVALUE;
+ else if (state == CS_IN2ESC)
+ state = CS_IN2VALUE;
+ else
+ elog(ERROR, "unrecognized parse_keyvalpairs state: %d", state);
+ ptr += pg_mblen(ptr);
+ }
+
+ if (state == CS_IN2VALUE)
+ {
+ mptr->value = nstrdup(begin, ptr - begin);
+ mptr++;
+ }
+ else if (!(state == CS_WAITDELIM || state == CS_WAITKEY))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("invalid parameter list format: \"%s\"",
+ TextPGetCString(in))));
+}
+
+/*
+ * Given the base name and extension of a tsearch config file, return
+ * its full path name. The base name is assumed to be user-supplied,
+ * and is checked to prevent pathname attacks. The extension is assumed
+ * to be safe.
+ *
+ * The result is a palloc'd string.
+ */
+char *
+get_tsearch_config_filename(const char *basename,
+ const char *extension)
+{
+ char sharepath[MAXPGPATH];
+ char *result;
+ const char *p;
+
+ /*
+ * We enforce that the basename is all alpha characters. This may be
+ * overly restrictive, but we don't want to allow access to anything
+ * outside the tsearch_data directory, so for instance '/' *must* be
+ * rejected. This is the same test used for timezonesets names.
+ */
+ for (p = basename; *p; p++)
+ {
+ if (!isalpha((unsigned char) *p))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid text search configuration file name \"%s\"",
+ basename)));
+ }
+
+ get_share_path(my_exec_path, sharepath);
+ result = palloc(MAXPGPATH);
+ snprintf(result, MAXPGPATH, "%s/tsearch_data/%s.%s",
+ sharepath, basename, extension);
+
+ return result;
+}
+
+#define STOPBUFLEN 4096
+
+void
+readstoplist(char *in, StopList * s)
+{
+ char **stop = NULL;
+
+ s->len = 0;
+ if (in && *in)
+ {
+ char *filename = get_tsearch_config_filename(in, "stop");
+ FILE *hin;
+ char buf[STOPBUFLEN];
+ int reallen = 0;
+ int line = 0;
+
+ if ((hin = AllocateFile(filename, "r")) == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("could not open stopword file \"%s\": %m",
+ filename)));
+
+ while (fgets(buf, STOPBUFLEN, hin))
+ {
+ char *pbuf = buf;
+
+ line++;
+ while (*pbuf && !isspace(*pbuf))
+ pbuf++;
+ *pbuf = '\0';
+
+ if (*buf == '\0')
+ continue;
+
+ if (!pg_verifymbstr(buf, strlen(buf), true))
+ {
+ FreeFile(hin);
+ ereport(ERROR,
+ (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+ errmsg("invalid multibyte encoding at line %d in file \"%s\"",
+ line, filename)));
+ }
+
+ if (s->len >= reallen)
+ {
+ if (reallen == 0)
+ {
+ reallen = 16;
+ stop = (char **) palloc(sizeof(char *) * reallen);
+ }
+ else
+ {
+ reallen *= 2;
+ stop = (char **) repalloc((void *) stop, sizeof(char *) * reallen);
+ }
+ }
+
+
+ if (s->wordop)
+ stop[s->len] = s->wordop(buf);
+ else
+ stop[s->len] = pstrdup(buf);
+
+ (s->len)++;
+ }
+ FreeFile(hin);
+ pfree(filename);
+ }
+
+ s->stop = stop;
+}
+
+static int
+comparestr(const void *a, const void *b)
+{
+ return strcmp(*(char **) a, *(char **) b);
+}
+
+void
+sortstoplist(StopList * s)
+{
+ if (s->stop && s->len > 0)
+ qsort(s->stop, s->len, sizeof(char *), comparestr);
+}
+
+bool
+searchstoplist(StopList * s, char *key)
+{
+ return (s->stop && s->len > 0 &&
+ bsearch(&key, s->stop, s->len,
+ sizeof(char *), comparestr)) ? true : false;
+}
+
+char *
+pnstrdup(const char *in, int len)
+{
+ char *out = palloc(len + 1);
+
+ memcpy(out, in, len);
+ out[len] = '\0';
+ return out;
+}
diff --git a/src/backend/tsearch/wparser.c b/src/backend/tsearch/wparser.c
new file mode 100644
index 00000000000..0b374e8159e
--- /dev/null
+++ b/src/backend/tsearch/wparser.c
@@ -0,0 +1,360 @@
+/*-------------------------------------------------------------------------
+ *
+ * wparser.c
+ * Standard interface to word parser
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/wparser.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "funcapi.h"
+#include "access/genam.h"
+#include "access/heapam.h"
+#include "access/skey.h"
+#include "catalog/indexing.h"
+#include "catalog/namespace.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_type.h"
+#include "tsearch/ts_cache.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/rel.h"
+#include "utils/syscache.h"
+
+
+/******sql-level interface******/
+
+typedef struct
+{
+ int cur;
+ LexDescr *list;
+} TSTokenTypeStorage;
+
+static void
+tt_setup_firstcall(FuncCallContext *funcctx, Oid prsid)
+{
+ TupleDesc tupdesc;
+ MemoryContext oldcontext;
+ TSTokenTypeStorage *st;
+ TSParserCacheEntry *prs = lookup_ts_parser_cache(prsid);
+
+ if (!OidIsValid(prs->lextypeOid))
+ elog(ERROR, "method lextype isn't defined for text search parser %u",
+ prsid);
+
+ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+
+ st = (TSTokenTypeStorage *) palloc(sizeof(TSTokenTypeStorage));
+ st->cur = 0;
+ /* OidFunctionCall0 is absent */
+ st->list = (LexDescr *) DatumGetPointer(OidFunctionCall1(prs->lextypeOid,
+ (Datum) 0));
+ funcctx->user_fctx = (void *) st;
+
+ tupdesc = CreateTemplateTupleDesc(3, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 2, "alias",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
+ TEXTOID, -1, 0);
+
+ funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
+ MemoryContextSwitchTo(oldcontext);
+}
+
+static Datum
+tt_process_call(FuncCallContext *funcctx)
+{
+ TSTokenTypeStorage *st;
+
+ st = (TSTokenTypeStorage *) funcctx->user_fctx;
+ if (st->list && st->list[st->cur].lexid)
+ {
+ Datum result;
+ char *values[3];
+ char txtid[16];
+ HeapTuple tuple;
+
+ sprintf(txtid, "%d", st->list[st->cur].lexid);
+ values[0] = txtid;
+ values[1] = st->list[st->cur].alias;
+ values[2] = st->list[st->cur].descr;
+
+ tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
+ result = HeapTupleGetDatum(tuple);
+
+ pfree(values[1]);
+ pfree(values[2]);
+ st->cur++;
+ return result;
+ }
+ if (st->list)
+ pfree(st->list);
+ pfree(st);
+ return (Datum) 0;
+}
+
+Datum
+ts_token_type_byid(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ Datum result;
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ funcctx = SRF_FIRSTCALL_INIT();
+ tt_setup_firstcall(funcctx, PG_GETARG_OID(0));
+ }
+
+ funcctx = SRF_PERCALL_SETUP();
+
+ if ((result = tt_process_call(funcctx)) != (Datum) 0)
+ SRF_RETURN_NEXT(funcctx, result);
+ SRF_RETURN_DONE(funcctx);
+}
+
+Datum
+ts_token_type_byname(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ Datum result;
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ text *prsname = PG_GETARG_TEXT_P(0);
+ Oid prsId;
+
+ funcctx = SRF_FIRSTCALL_INIT();
+ prsId = TSParserGetPrsid(textToQualifiedNameList(prsname), false);
+ tt_setup_firstcall(funcctx, prsId);
+ }
+
+ funcctx = SRF_PERCALL_SETUP();
+
+ if ((result = tt_process_call(funcctx)) != (Datum) 0)
+ SRF_RETURN_NEXT(funcctx, result);
+ SRF_RETURN_DONE(funcctx);
+}
+
+typedef struct
+{
+ int type;
+ char *lexeme;
+} LexemeEntry;
+
+typedef struct
+{
+ int cur;
+ int len;
+ LexemeEntry *list;
+} PrsStorage;
+
+
+static void
+prs_setup_firstcall(FuncCallContext *funcctx, Oid prsid, text *txt)
+{
+ TupleDesc tupdesc;
+ MemoryContext oldcontext;
+ PrsStorage *st;
+ TSParserCacheEntry *prs = lookup_ts_parser_cache(prsid);
+ char *lex = NULL;
+ int llen = 0,
+ type = 0;
+ void *prsdata;
+
+ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+
+ st = (PrsStorage *) palloc(sizeof(PrsStorage));
+ st->cur = 0;
+ st->len = 16;
+ st->list = (LexemeEntry *) palloc(sizeof(LexemeEntry) * st->len);
+
+ prsdata = (void *) DatumGetPointer(FunctionCall2(&prs->prsstart,
+ PointerGetDatum(VARDATA(txt)),
+ Int32GetDatum(VARSIZE(txt) - VARHDRSZ)));
+
+ while ((type = DatumGetInt32(FunctionCall3(&prs->prstoken,
+ PointerGetDatum(prsdata),
+ PointerGetDatum(&lex),
+ PointerGetDatum(&llen)))) != 0)
+ {
+ if (st->cur >= st->len)
+ {
+ st->len = 2 * st->len;
+ st->list = (LexemeEntry *) repalloc(st->list, sizeof(LexemeEntry) * st->len);
+ }
+ st->list[st->cur].lexeme = palloc(llen + 1);
+ memcpy(st->list[st->cur].lexeme, lex, llen);
+ st->list[st->cur].lexeme[llen] = '\0';
+ st->list[st->cur].type = type;
+ st->cur++;
+ }
+
+ FunctionCall1(&prs->prsend, PointerGetDatum(prsdata));
+
+ st->len = st->cur;
+ st->cur = 0;
+
+ funcctx->user_fctx = (void *) st;
+ tupdesc = CreateTemplateTupleDesc(2, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 2, "token",
+ TEXTOID, -1, 0);
+
+ funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
+ MemoryContextSwitchTo(oldcontext);
+}
+
+static Datum
+prs_process_call(FuncCallContext *funcctx)
+{
+ PrsStorage *st;
+
+ st = (PrsStorage *) funcctx->user_fctx;
+ if (st->cur < st->len)
+ {
+ Datum result;
+ char *values[2];
+ char tid[16];
+ HeapTuple tuple;
+
+ values[0] = tid;
+ sprintf(tid, "%d", st->list[st->cur].type);
+ values[1] = st->list[st->cur].lexeme;
+ tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
+ result = HeapTupleGetDatum(tuple);
+
+ pfree(values[1]);
+ st->cur++;
+ return result;
+ }
+ else
+ {
+ if (st->list)
+ pfree(st->list);
+ pfree(st);
+ }
+ return (Datum) 0;
+}
+
+Datum
+ts_parse_byid(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ Datum result;
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ text *txt = PG_GETARG_TEXT_P(1);
+
+ funcctx = SRF_FIRSTCALL_INIT();
+ prs_setup_firstcall(funcctx, PG_GETARG_OID(0), txt);
+ PG_FREE_IF_COPY(txt, 1);
+ }
+
+ funcctx = SRF_PERCALL_SETUP();
+
+ if ((result = prs_process_call(funcctx)) != (Datum) 0)
+ SRF_RETURN_NEXT(funcctx, result);
+ SRF_RETURN_DONE(funcctx);
+}
+
+Datum
+ts_parse_byname(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ Datum result;
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ text *prsname = PG_GETARG_TEXT_P(0);
+ text *txt = PG_GETARG_TEXT_P(1);
+ Oid prsId;
+
+ funcctx = SRF_FIRSTCALL_INIT();
+ prsId = TSParserGetPrsid(textToQualifiedNameList(prsname), false);
+ prs_setup_firstcall(funcctx, prsId, txt);
+ }
+
+ funcctx = SRF_PERCALL_SETUP();
+
+ if ((result = prs_process_call(funcctx)) != (Datum) 0)
+ SRF_RETURN_NEXT(funcctx, result);
+ SRF_RETURN_DONE(funcctx);
+}
+
+Datum
+ts_headline_byid_opt(PG_FUNCTION_ARGS)
+{
+ text *in = PG_GETARG_TEXT_P(1);
+ TSQuery query = PG_GETARG_TSQUERY(2);
+ text *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_P(3) : NULL;
+ HeadlineText prs;
+ text *out;
+ TSConfigCacheEntry *cfg;
+ TSParserCacheEntry *prsobj;
+
+ cfg = lookup_ts_config_cache(PG_GETARG_OID(0));
+ prsobj = lookup_ts_parser_cache(cfg->prsId);
+
+ memset(&prs, 0, sizeof(HeadlineText));
+ prs.lenwords = 32;
+ prs.words = (HeadlineWord *) palloc(sizeof(HeadlineWord) * prs.lenwords);
+
+ hlparsetext(cfg->cfgId, &prs, query, VARDATA(in), VARSIZE(in) - VARHDRSZ);
+
+ FunctionCall3(&(prsobj->prsheadline),
+ PointerGetDatum(&prs),
+ PointerGetDatum(opt),
+ PointerGetDatum(query));
+
+ out = generatHeadline(&prs);
+
+ PG_FREE_IF_COPY(in, 1);
+ PG_FREE_IF_COPY(query, 2);
+ if (opt)
+ PG_FREE_IF_COPY(opt, 3);
+ pfree(prs.words);
+ pfree(prs.startsel);
+ pfree(prs.stopsel);
+
+ PG_RETURN_POINTER(out);
+}
+
+Datum
+ts_headline_byid(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_byid_opt,
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1),
+ PG_GETARG_DATUM(2)));
+}
+
+Datum
+ts_headline(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_byid_opt,
+ ObjectIdGetDatum(getTSCurrentConfig(true)),
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1)));
+}
+
+Datum
+ts_headline_opt(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(DirectFunctionCall4(ts_headline_byid_opt,
+ ObjectIdGetDatum(getTSCurrentConfig(true)),
+ PG_GETARG_DATUM(0),
+ PG_GETARG_DATUM(1),
+ PG_GETARG_DATUM(2)));
+}
diff --git a/src/backend/tsearch/wparser_def.c b/src/backend/tsearch/wparser_def.c
new file mode 100644
index 00000000000..8d71e3e914e
--- /dev/null
+++ b/src/backend/tsearch/wparser_def.c
@@ -0,0 +1,1873 @@
+/*-------------------------------------------------------------------------
+ *
+ * wparser_def.c
+ * Standard word parser
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/tsearch/wparser_def.c,v 1.1 2007/08/21 01:11:18 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_public.h"
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+
+
+/* rememder !!!! */
+#define LASTNUM 23
+
+#define LATWORD 1
+#define CYRWORD 2
+#define UWORD 3
+#define EMAIL 4
+#define FURL 5
+#define HOST 6
+#define SCIENTIFIC 7
+#define VERSIONNUMBER 8
+#define PARTHYPHENWORD 9
+#define CYRPARTHYPHENWORD 10
+#define LATPARTHYPHENWORD 11
+#define SPACE 12
+#define TAG 13
+#define PROTOCOL 14
+#define HYPHENWORD 15
+#define LATHYPHENWORD 16
+#define CYRHYPHENWORD 17
+#define URI 18
+#define FILEPATH 19
+#define DECIMAL 20
+#define SIGNEDINT 21
+#define UNSIGNEDINT 22
+#define HTMLENTITY 23
+
+static const char *lex_descr[] = {
+ "",
+ "Latin word",
+ "Non-latin word",
+ "Word",
+ "Email",
+ "URL",
+ "Host",
+ "Scientific notation",
+ "VERSION",
+ "Part of hyphenated word",
+ "Non-latin part of hyphenated word",
+ "Latin part of hyphenated word",
+ "Space symbols",
+ "HTML Tag",
+ "Protocol head",
+ "Hyphenated word",
+ "Latin hyphenated word",
+ "Non-latin hyphenated word",
+ "URI",
+ "File or path name",
+ "Decimal notation",
+ "Signed integer",
+ "Unsigned integer",
+ "HTML Entity"
+};
+
+static const char *tok_alias[] = {
+ "",
+ "lword",
+ "nlword",
+ "word",
+ "email",
+ "url",
+ "host",
+ "sfloat",
+ "version",
+ "part_hword",
+ "nlpart_hword",
+ "lpart_hword",
+ "blank",
+ "tag",
+ "protocol",
+ "hword",
+ "lhword",
+ "nlhword",
+ "uri",
+ "file",
+ "float",
+ "int",
+ "uint",
+ "entity"
+};
+
+typedef enum
+{
+ TPS_Base = 0,
+ TPS_InUWord,
+ TPS_InLatWord,
+ TPS_InCyrWord,
+ TPS_InUnsignedInt,
+ TPS_InSignedIntFirst,
+ TPS_InSignedInt,
+ TPS_InSpace,
+ TPS_InUDecimalFirst,
+ TPS_InUDecimal,
+ TPS_InDecimalFirst,
+ TPS_InDecimal,
+ TPS_InVerVersion,
+ TPS_InSVerVersion,
+ TPS_InVersionFirst,
+ TPS_InVersion,
+ TPS_InMantissaFirst,
+ TPS_InMantissaSign,
+ TPS_InMantissa,
+ TPS_InHTMLEntityFirst,
+ TPS_InHTMLEntity,
+ TPS_InHTMLEntityNumFirst,
+ TPS_InHTMLEntityNum,
+ TPS_InHTMLEntityEnd,
+ TPS_InTagFirst,
+ TPS_InXMLBegin,
+ TPS_InTagCloseFirst,
+ TPS_InTagName,
+ TPS_InTagBeginEnd,
+ TPS_InTag,
+ TPS_InTagEscapeK,
+ TPS_InTagEscapeKK,
+ TPS_InTagBackSleshed,
+ TPS_InTagEnd,
+ TPS_InCommentFirst,
+ TPS_InCommentLast,
+ TPS_InComment,
+ TPS_InCloseCommentFirst,
+ TPS_InCloseCommentLast,
+ TPS_InCommentEnd,
+ TPS_InHostFirstDomain,
+ TPS_InHostDomainSecond,
+ TPS_InHostDomain,
+ TPS_InPortFirst,
+ TPS_InPort,
+ TPS_InHostFirstAN,
+ TPS_InHost,
+ TPS_InEmail,
+ TPS_InFileFirst,
+ TPS_InFileTwiddle,
+ TPS_InPathFirst,
+ TPS_InPathFirstFirst,
+ TPS_InPathSecond,
+ TPS_InFile,
+ TPS_InFileNext,
+ TPS_InURIFirst,
+ TPS_InURIStart,
+ TPS_InURI,
+ TPS_InFURL,
+ TPS_InProtocolFirst,
+ TPS_InProtocolSecond,
+ TPS_InProtocolEnd,
+ TPS_InHyphenLatWordFirst,
+ TPS_InHyphenLatWord,
+ TPS_InHyphenCyrWordFirst,
+ TPS_InHyphenCyrWord,
+ TPS_InHyphenUWordFirst,
+ TPS_InHyphenUWord,
+ TPS_InHyphenValueFirst,
+ TPS_InHyphenValue,
+ TPS_InHyphenValueExact,
+ TPS_InParseHyphen,
+ TPS_InParseHyphenHyphen,
+ TPS_InHyphenCyrWordPart,
+ TPS_InHyphenLatWordPart,
+ TPS_InHyphenUWordPart,
+ TPS_InHyphenUnsignedInt,
+ TPS_InHDecimalPartFirst,
+ TPS_InHDecimalPart,
+ TPS_InHVersionPartFirst,
+ TPS_InHVersionPart,
+ TPS_Null /* last state (fake value) */
+} TParserState;
+
+/* forward declaration */
+struct TParser;
+
+
+typedef int (*TParserCharTest) (struct TParser *); /* any p_is* functions
+ * except p_iseq */
+typedef void (*TParserSpecial) (struct TParser *); /* special handler for
+ * special cases... */
+
+typedef struct
+{
+ TParserCharTest isclass;
+ char c;
+ uint16 flags;
+ TParserState tostate;
+ int type;
+ TParserSpecial special;
+} TParserStateActionItem;
+
+typedef struct
+{
+ TParserState state;
+ TParserStateActionItem *action;
+} TParserStateAction;
+
+typedef struct TParserPosition
+{
+ int posbyte; /* position of parser in bytes */
+ int poschar; /* osition of parser in characters */
+ int charlen; /* length of current char */
+ int lenbytelexeme;
+ int lencharlexeme;
+ TParserState state;
+ struct TParserPosition *prev;
+ int flags;
+ TParserStateActionItem *pushedAtAction;
+} TParserPosition;
+
+typedef struct TParser
+{
+ /* string and position information */
+ char *str; /* multibyte string */
+ int lenstr; /* length of mbstring */
+#ifdef TS_USE_WIDE
+ wchar_t *wstr; /* wide character string */
+ int lenwstr; /* length of wsting */
+#endif
+
+ /* State of parse */
+ int charmaxlen;
+ bool usewide;
+ TParserPosition *state;
+ bool ignore;
+ bool wanthost;
+
+ /* silly char */
+ char c;
+
+ /* out */
+ char *lexeme;
+ int lenbytelexeme;
+ int lencharlexeme;
+ int type;
+
+} TParser;
+
+static TParserPosition *
+newTParserPosition(TParserPosition * prev)
+{
+ TParserPosition *res = (TParserPosition *) palloc(sizeof(TParserPosition));
+
+ if (prev)
+ memcpy(res, prev, sizeof(TParserPosition));
+ else
+ memset(res, 0, sizeof(TParserPosition));
+
+ res->prev = prev;
+
+ res->pushedAtAction = NULL;
+
+ return res;
+}
+
+static TParser *
+TParserInit(char *str, int len)
+{
+ TParser *prs = (TParser *) palloc0(sizeof(TParser));
+
+ prs->charmaxlen = pg_database_encoding_max_length();
+ prs->str = str;
+ prs->lenstr = len;
+
+#ifdef TS_USE_WIDE
+
+ /*
+ * Use wide char code only when max encoding length > 1.
+ */
+
+ if (prs->charmaxlen > 1)
+ {
+ prs->usewide = true;
+ prs->wstr = (wchar_t *) palloc(sizeof(wchar_t) * (prs->lenstr + 1));
+ prs->lenwstr = char2wchar(prs->wstr, prs->str, prs->lenstr);
+ }
+ else
+#endif
+ prs->usewide = false;
+
+ prs->state = newTParserPosition(NULL);
+ prs->state->state = TPS_Base;
+
+ return prs;
+}
+
+static bool TParserGet(TParser * prs);
+
+static void
+TParserClose(TParser * prs)
+{
+ while (prs->state)
+ {
+ TParserPosition *ptr = prs->state->prev;
+
+ pfree(prs->state);
+ prs->state = ptr;
+ }
+
+#ifdef TS_USE_WIDE
+ if (prs->wstr)
+ pfree(prs->wstr);
+#endif
+
+ pfree(prs);
+}
+
+/*
+ * defining support function, equvalent is* macroses, but
+ * working with any possible encodings and locales. Note,
+ * that with multibyte encoding and C-locale isw* function may fail
+ * or give wrong result. Note 2: multibyte encoding and C-local
+ * often are used for Asian languages
+ */
+
+#ifdef TS_USE_WIDE
+
+#define p_iswhat(type) \
+static int \
+p_is##type(TParser *prs) { \
+ Assert( prs->state ); \
+ if ( prs->usewide ) \
+ { \
+ if ( lc_ctype_is_c() ) \
+ return is##type( 0xff & *( prs->wstr + prs->state->poschar) ); \
+ \
+ return isw##type( *(wint_t*)( prs->wstr + prs->state->poschar ) ); \
+ } \
+ \
+ return is##type( *(unsigned char*)( prs->str + prs->state->posbyte ) ); \
+} \
+ \
+static int \
+p_isnot##type(TParser *prs) { \
+ return !p_is##type(prs); \
+}
+
+static int
+p_isalnum(TParser * prs)
+{
+ Assert(prs->state);
+
+ if (prs->usewide)
+ {
+ if (lc_ctype_is_c())
+ {
+ unsigned int c = *(prs->wstr + prs->state->poschar);
+
+ /*
+ * any non-ascii symbol with multibyte encoding with C-locale is
+ * an alpha character
+ */
+ if (c > 0x7f)
+ return 1;
+
+ return isalnum(0xff & c);
+ }
+
+ return iswalnum((wint_t) *(prs->wstr + prs->state->poschar));
+ }
+
+ return isalnum(*(unsigned char *) (prs->str + prs->state->posbyte));
+}
+static int
+p_isnotalnum(TParser * prs)
+{
+ return !p_isalnum(prs);
+}
+
+static int
+p_isalpha(TParser * prs)
+{
+ Assert(prs->state);
+
+ if (prs->usewide)
+ {
+ if (lc_ctype_is_c())
+ {
+ unsigned int c = *(prs->wstr + prs->state->poschar);
+
+ /*
+ * any non-ascii symbol with multibyte encoding with C-locale is
+ * an alpha character
+ */
+ if (c > 0x7f)
+ return 1;
+
+ return isalpha(0xff & c);
+ }
+
+ return iswalpha((wint_t) *(prs->wstr + prs->state->poschar));
+ }
+
+ return isalpha(*(unsigned char *) (prs->str + prs->state->posbyte));
+}
+
+static int
+p_isnotalpha(TParser * prs)
+{
+ return !p_isalpha(prs);
+}
+
+/* p_iseq should be used only for ascii symbols */
+
+static int
+p_iseq(TParser * prs, char c)
+{
+ Assert(prs->state);
+ return ((prs->state->charlen == 1 && *(prs->str + prs->state->posbyte) == c)) ? 1 : 0;
+}
+#else /* TS_USE_WIDE */
+
+#define p_iswhat(type) \
+static int \
+p_is##type(TParser *prs) { \
+ Assert( prs->state ); \
+ return is##type( (unsigned char)*( prs->str + prs->state->posbyte ) ); \
+} \
+ \
+static int \
+p_isnot##type(TParser *prs) { \
+ return !p_is##type(prs); \
+}
+
+
+static int
+p_iseq(TParser * prs, char c)
+{
+ Assert(prs->state);
+ return (*(prs->str + prs->state->posbyte) == c) ? 1 : 0;
+}
+
+p_iswhat(alnum)
+p_iswhat(alpha)
+#endif /* TS_USE_WIDE */
+
+p_iswhat(digit)
+p_iswhat(lower)
+p_iswhat(print)
+p_iswhat(punct)
+p_iswhat(space)
+p_iswhat(upper)
+p_iswhat(xdigit)
+
+static int
+p_isEOF(TParser * prs)
+{
+ Assert(prs->state);
+ return (prs->state->posbyte == prs->lenstr || prs->state->charlen == 0) ? 1 : 0;
+}
+
+static int
+p_iseqC(TParser * prs)
+{
+ return p_iseq(prs, prs->c);
+}
+
+static int
+p_isneC(TParser * prs)
+{
+ return !p_iseq(prs, prs->c);
+}
+
+static int
+p_isascii(TParser * prs)
+{
+ return (prs->state->charlen == 1 && isascii((unsigned char) *(prs->str + prs->state->posbyte))) ? 1 : 0;
+}
+
+static int
+p_islatin(TParser * prs)
+{
+ return (p_isalpha(prs) && p_isascii(prs)) ? 1 : 0;
+}
+
+static int
+p_isnonlatin(TParser * prs)
+{
+ return (p_isalpha(prs) && !p_isascii(prs)) ? 1 : 0;
+}
+
+void _make_compiler_happy(void);
+void
+_make_compiler_happy(void)
+{
+ p_isalnum(NULL);
+ p_isnotalnum(NULL);
+ p_isalpha(NULL);
+ p_isnotalpha(NULL);
+ p_isdigit(NULL);
+ p_isnotdigit(NULL);
+ p_islower(NULL);
+ p_isnotlower(NULL);
+ p_isprint(NULL);
+ p_isnotprint(NULL);
+ p_ispunct(NULL);
+ p_isnotpunct(NULL);
+ p_isspace(NULL);
+ p_isnotspace(NULL);
+ p_isupper(NULL);
+ p_isnotupper(NULL);
+ p_isxdigit(NULL);
+ p_isnotxdigit(NULL);
+ p_isEOF(NULL);
+ p_iseqC(NULL);
+ p_isneC(NULL);
+}
+
+
+static void
+SpecialTags(TParser * prs)
+{
+ switch (prs->state->lencharlexeme)
+ {
+ case 8: /* </script */
+ if (pg_strncasecmp(prs->lexeme, "</script", 8) == 0)
+ prs->ignore = false;
+ break;
+ case 7: /* <script || </style */
+ if (pg_strncasecmp(prs->lexeme, "</style", 7) == 0)
+ prs->ignore = false;
+ else if (pg_strncasecmp(prs->lexeme, "<script", 7) == 0)
+ prs->ignore = true;
+ break;
+ case 6: /* <style */
+ if (pg_strncasecmp(prs->lexeme, "<style", 6) == 0)
+ prs->ignore = true;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+SpecialFURL(TParser * prs)
+{
+ prs->wanthost = true;
+ prs->state->posbyte -= prs->state->lenbytelexeme;
+ prs->state->poschar -= prs->state->lencharlexeme;
+}
+
+static void
+SpecialHyphen(TParser * prs)
+{
+ prs->state->posbyte -= prs->state->lenbytelexeme;
+ prs->state->poschar -= prs->state->lencharlexeme;
+}
+
+static void
+SpecialVerVersion(TParser * prs)
+{
+ prs->state->posbyte -= prs->state->lenbytelexeme;
+ prs->state->poschar -= prs->state->lencharlexeme;
+ prs->state->lenbytelexeme = 0;
+ prs->state->lencharlexeme = 0;
+}
+
+static int
+p_isstophost(TParser * prs)
+{
+ if (prs->wanthost)
+ {
+ prs->wanthost = false;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+p_isignore(TParser * prs)
+{
+ return (prs->ignore) ? 1 : 0;
+}
+
+static int
+p_ishost(TParser * prs)
+{
+ TParser *tmpprs = TParserInit(prs->str + prs->state->posbyte, prs->lenstr - prs->state->posbyte);
+ int res = 0;
+
+ if (TParserGet(tmpprs) && tmpprs->type == HOST)
+ {
+ prs->state->posbyte += tmpprs->lenbytelexeme;
+ prs->state->poschar += tmpprs->lencharlexeme;
+ prs->state->lenbytelexeme += tmpprs->lenbytelexeme;
+ prs->state->lencharlexeme += tmpprs->lencharlexeme;
+ prs->state->charlen = tmpprs->state->charlen;
+ res = 1;
+ }
+ TParserClose(tmpprs);
+
+ return res;
+}
+
+static int
+p_isURI(TParser * prs)
+{
+ TParser *tmpprs = TParserInit(prs->str + prs->state->posbyte, prs->lenstr - prs->state->posbyte);
+ int res = 0;
+
+ tmpprs->state = newTParserPosition(tmpprs->state);
+ tmpprs->state->state = TPS_InFileFirst;
+
+ if (TParserGet(tmpprs) && (tmpprs->type == URI || tmpprs->type == FILEPATH))
+ {
+ prs->state->posbyte += tmpprs->lenbytelexeme;
+ prs->state->poschar += tmpprs->lencharlexeme;
+ prs->state->lenbytelexeme += tmpprs->lenbytelexeme;
+ prs->state->lencharlexeme += tmpprs->lencharlexeme;
+ prs->state->charlen = tmpprs->state->charlen;
+ res = 1;
+ }
+ TParserClose(tmpprs);
+
+ return res;
+}
+
+/*
+ * Table of state/action of parser
+ */
+
+#define A_NEXT 0x0000
+#define A_BINGO 0x0001
+#define A_POP 0x0002
+#define A_PUSH 0x0004
+#define A_RERUN 0x0008
+#define A_CLEAR 0x0010
+#define A_MERGE 0x0020
+#define A_CLRALL 0x0040
+
+static TParserStateActionItem actionTPS_Base[] = {
+ {p_isEOF, 0, A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '<', A_PUSH, TPS_InTagFirst, 0, NULL},
+ {p_isignore, 0, A_NEXT, TPS_InSpace, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InLatWord, 0, NULL},
+ {p_isnonlatin, 0, A_NEXT, TPS_InCyrWord, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InUnsignedInt, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InSignedIntFirst, 0, NULL},
+ {p_iseqC, '+', A_PUSH, TPS_InSignedIntFirst, 0, NULL},
+ {p_iseqC, '&', A_PUSH, TPS_InHTMLEntityFirst, 0, NULL},
+ {p_iseqC, '~', A_PUSH, TPS_InFileTwiddle, 0, NULL},
+ {p_iseqC, '/', A_PUSH, TPS_InFileFirst, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InPathFirstFirst, 0, NULL},
+ {NULL, 0, A_NEXT, TPS_InSpace, 0, NULL}
+};
+
+
+static TParserStateActionItem actionTPS_InUWord[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, UWORD, NULL},
+ {p_isalnum, 0, A_NEXT, TPS_InUWord, 0, NULL},
+ {p_iseqC, '@', A_PUSH, TPS_InEmail, 0, NULL},
+ {p_iseqC, '/', A_PUSH, TPS_InFileFirst, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InFileNext, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHyphenUWordFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, UWORD, NULL}
+};
+
+static TParserStateActionItem actionTPS_InLatWord[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, LATWORD, NULL},
+ {p_islatin, 0, A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHostFirstDomain, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InFileNext, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHostFirstAN, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHyphenLatWordFirst, 0, NULL},
+ {p_iseqC, '@', A_PUSH, TPS_InEmail, 0, NULL},
+ {p_iseqC, ':', A_PUSH, TPS_InProtocolFirst, 0, NULL},
+ {p_iseqC, '/', A_PUSH, TPS_InFileFirst, 0, NULL},
+ {p_isdigit, 0, A_PUSH, TPS_InHost, 0, NULL},
+ {p_isalnum, 0, A_NEXT, TPS_InUWord, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, LATWORD, NULL}
+};
+
+static TParserStateActionItem actionTPS_InCyrWord[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, CYRWORD, NULL},
+ {p_isnonlatin, 0, A_NEXT, TPS_Null, 0, NULL},
+ {p_isalnum, 0, A_NEXT, TPS_InUWord, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHyphenCyrWordFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, CYRWORD, NULL}
+};
+
+static TParserStateActionItem actionTPS_InUnsignedInt[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, UNSIGNEDINT, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHostFirstDomain, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InUDecimalFirst, 0, NULL},
+ {p_iseqC, 'e', A_PUSH, TPS_InMantissaFirst, 0, NULL},
+ {p_iseqC, 'E', A_PUSH, TPS_InMantissaFirst, 0, NULL},
+ {p_islatin, 0, A_PUSH, TPS_InHost, 0, NULL},
+ {p_isalpha, 0, A_NEXT, TPS_InUWord, 0, NULL},
+ {p_iseqC, '/', A_PUSH, TPS_InFileFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, UNSIGNEDINT, NULL}
+};
+
+static TParserStateActionItem actionTPS_InSignedIntFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT | A_CLEAR, TPS_InSignedInt, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InSignedInt[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, SIGNEDINT, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InDecimalFirst, 0, NULL},
+ {p_iseqC, 'e', A_PUSH, TPS_InMantissaFirst, 0, NULL},
+ {p_iseqC, 'E', A_PUSH, TPS_InMantissaFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, SIGNEDINT, NULL}
+};
+
+static TParserStateActionItem actionTPS_InSpace[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, SPACE, NULL},
+ {p_iseqC, '<', A_BINGO, TPS_Base, SPACE, NULL},
+ {p_isignore, 0, A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '-', A_BINGO, TPS_Base, SPACE, NULL},
+ {p_iseqC, '+', A_BINGO, TPS_Base, SPACE, NULL},
+ {p_iseqC, '&', A_BINGO, TPS_Base, SPACE, NULL},
+ {p_iseqC, '/', A_BINGO, TPS_Base, SPACE, NULL},
+ {p_isnotalnum, 0, A_NEXT, TPS_InSpace, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, SPACE, NULL}
+};
+
+static TParserStateActionItem actionTPS_InUDecimalFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_CLEAR, TPS_InUDecimal, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InUDecimal[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, DECIMAL, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InUDecimal, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InVersionFirst, 0, NULL},
+ {p_iseqC, 'e', A_PUSH, TPS_InMantissaFirst, 0, NULL},
+ {p_iseqC, 'E', A_PUSH, TPS_InMantissaFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, DECIMAL, NULL}
+};
+
+static TParserStateActionItem actionTPS_InDecimalFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_CLEAR, TPS_InDecimal, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InDecimal[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, DECIMAL, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InDecimal, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InVerVersion, 0, NULL},
+ {p_iseqC, 'e', A_PUSH, TPS_InMantissaFirst, 0, NULL},
+ {p_iseqC, 'E', A_PUSH, TPS_InMantissaFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, DECIMAL, NULL}
+};
+
+static TParserStateActionItem actionTPS_InVerVersion[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_RERUN, TPS_InSVerVersion, 0, SpecialVerVersion},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InSVerVersion[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_BINGO | A_CLRALL, TPS_InUnsignedInt, SPACE, NULL},
+ {NULL, 0, A_NEXT, TPS_Null, 0, NULL}
+};
+
+
+static TParserStateActionItem actionTPS_InVersionFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_CLEAR, TPS_InVersion, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InVersion[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, VERSIONNUMBER, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InVersion, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InVersionFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, VERSIONNUMBER, NULL}
+};
+
+static TParserStateActionItem actionTPS_InMantissaFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_CLEAR, TPS_InMantissa, 0, NULL},
+ {p_iseqC, '+', A_NEXT, TPS_InMantissaSign, 0, NULL},
+ {p_iseqC, '-', A_NEXT, TPS_InMantissaSign, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InMantissaSign[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_CLEAR, TPS_InMantissa, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InMantissa[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, SCIENTIFIC, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InMantissa, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, SCIENTIFIC, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHTMLEntityFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '#', A_NEXT, TPS_InHTMLEntityNumFirst, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHTMLEntity, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHTMLEntity[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHTMLEntity, 0, NULL},
+ {p_iseqC, ';', A_NEXT, TPS_InHTMLEntityEnd, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHTMLEntityNumFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHTMLEntityNum, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHTMLEntityNum[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHTMLEntityNum, 0, NULL},
+ {p_iseqC, ';', A_NEXT, TPS_InHTMLEntityEnd, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHTMLEntityEnd[] = {
+ {NULL, 0, A_BINGO | A_CLEAR, TPS_Base, HTMLENTITY, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTagFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '/', A_PUSH, TPS_InTagCloseFirst, 0, NULL},
+ {p_iseqC, '!', A_PUSH, TPS_InCommentFirst, 0, NULL},
+ {p_iseqC, '?', A_PUSH, TPS_InXMLBegin, 0, NULL},
+ {p_islatin, 0, A_PUSH, TPS_InTagName, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InXMLBegin[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ /* <?xml ... */
+ {p_iseqC, 'x', A_NEXT, TPS_InTag, 0, NULL},
+ {p_iseqC, 'X', A_NEXT, TPS_InTag, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTagCloseFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InTagName, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTagName[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ /* <br/> case */
+ {p_iseqC, '/', A_NEXT, TPS_InTagBeginEnd, 0, NULL},
+ {p_iseqC, '>', A_NEXT, TPS_InTagEnd, 0, SpecialTags},
+ {p_isspace, 0, A_NEXT, TPS_InTag, 0, SpecialTags},
+ {p_islatin, 0, A_NEXT, TPS_Null, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTagBeginEnd[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '>', A_NEXT, TPS_InTagEnd, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTag[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '>', A_NEXT, TPS_InTagEnd, 0, SpecialTags},
+ {p_iseqC, '\'', A_NEXT, TPS_InTagEscapeK, 0, NULL},
+ {p_iseqC, '"', A_NEXT, TPS_InTagEscapeKK, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '=', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '-', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '#', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '/', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, ':', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '.', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '&', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '?', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '%', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '~', A_NEXT, TPS_Null, 0, NULL},
+ {p_isspace, 0, A_NEXT, TPS_Null, 0, SpecialTags},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTagEscapeK[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '\\', A_PUSH, TPS_InTagBackSleshed, 0, NULL},
+ {p_iseqC, '\'', A_NEXT, TPS_InTag, 0, NULL},
+ {NULL, 0, A_NEXT, TPS_InTagEscapeK, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTagEscapeKK[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '\\', A_PUSH, TPS_InTagBackSleshed, 0, NULL},
+ {p_iseqC, '"', A_NEXT, TPS_InTag, 0, NULL},
+ {NULL, 0, A_NEXT, TPS_InTagEscapeKK, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTagBackSleshed[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {NULL, 0, A_MERGE, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InTagEnd[] = {
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_Base, TAG, NULL}
+};
+
+static TParserStateActionItem actionTPS_InCommentFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '-', A_NEXT, TPS_InCommentLast, 0, NULL},
+ /* <!DOCTYPE ...> */
+ {p_iseqC, 'D', A_NEXT, TPS_InTag, 0, NULL},
+ {p_iseqC, 'd', A_NEXT, TPS_InTag, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InCommentLast[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '-', A_NEXT, TPS_InComment, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InComment[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '-', A_NEXT, TPS_InCloseCommentFirst, 0, NULL},
+ {NULL, 0, A_NEXT, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InCloseCommentFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '-', A_NEXT, TPS_InCloseCommentLast, 0, NULL},
+ {NULL, 0, A_NEXT, TPS_InComment, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InCloseCommentLast[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '-', A_NEXT, TPS_Null, 0, NULL},
+ {p_iseqC, '>', A_NEXT, TPS_InCommentEnd, 0, NULL},
+ {NULL, 0, A_NEXT, TPS_InComment, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InCommentEnd[] = {
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_Base, TAG, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHostFirstDomain[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHostDomainSecond, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHost, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHostDomainSecond[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHostDomain, 0, NULL},
+ {p_isdigit, 0, A_PUSH, TPS_InHost, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHostFirstAN, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHostFirstDomain, 0, NULL},
+ {p_iseqC, '@', A_PUSH, TPS_InEmail, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHostDomain[] = {
+ {p_isEOF, 0, A_BINGO | A_CLRALL, TPS_Base, HOST, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHostDomain, 0, NULL},
+ {p_isdigit, 0, A_PUSH, TPS_InHost, 0, NULL},
+ {p_iseqC, ':', A_PUSH, TPS_InPortFirst, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHostFirstAN, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHostFirstDomain, 0, NULL},
+ {p_iseqC, '@', A_PUSH, TPS_InEmail, 0, NULL},
+ {p_isdigit, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isstophost, 0, A_BINGO | A_CLRALL, TPS_InURIStart, HOST, NULL},
+ {p_iseqC, '/', A_PUSH, TPS_InFURL, 0, NULL},
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_Base, HOST, NULL}
+};
+
+static TParserStateActionItem actionTPS_InPortFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InPort, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InPort[] = {
+ {p_isEOF, 0, A_BINGO | A_CLRALL, TPS_Base, HOST, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InPort, 0, NULL},
+ {p_isstophost, 0, A_BINGO | A_CLRALL, TPS_InURIStart, HOST, NULL},
+ {p_iseqC, '/', A_PUSH, TPS_InFURL, 0, NULL},
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_Base, HOST, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHostFirstAN[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHost, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHost, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHost[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHost, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHost, 0, NULL},
+ {p_iseqC, '@', A_PUSH, TPS_InEmail, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHostFirstDomain, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHostFirstAN, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InEmail[] = {
+ {p_ishost, 0, A_BINGO | A_CLRALL, TPS_Base, EMAIL, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InFileFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InFile, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '.', A_NEXT, TPS_InPathFirst, 0, NULL},
+ {p_iseqC, '_', A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '?', A_PUSH, TPS_InURIFirst, 0, NULL},
+ {p_iseqC, '~', A_PUSH, TPS_InFileTwiddle, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InFileTwiddle[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InFile, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '_', A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '/', A_NEXT, TPS_InFileFirst, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InPathFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InFile, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '_', A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '.', A_NEXT, TPS_InPathSecond, 0, NULL},
+ {p_iseqC, '/', A_NEXT, TPS_InFileFirst, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InPathFirstFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '.', A_NEXT, TPS_InPathSecond, 0, NULL},
+ {p_iseqC, '/', A_NEXT, TPS_InFileFirst, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InPathSecond[] = {
+ {p_isEOF, 0, A_BINGO | A_CLEAR, TPS_Base, FILEPATH, NULL},
+ {p_iseqC, '/', A_NEXT | A_PUSH, TPS_InFileFirst, 0, NULL},
+ {p_iseqC, '/', A_BINGO | A_CLEAR, TPS_Base, FILEPATH, NULL},
+ {p_isspace, 0, A_BINGO | A_CLEAR, TPS_Base, FILEPATH, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InFile[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, FILEPATH, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InFile, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InFileNext, 0, NULL},
+ {p_iseqC, '_', A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '-', A_NEXT, TPS_InFile, 0, NULL},
+ {p_iseqC, '/', A_PUSH, TPS_InFileFirst, 0, NULL},
+ {p_iseqC, '?', A_PUSH, TPS_InURIFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, FILEPATH, NULL}
+};
+
+static TParserStateActionItem actionTPS_InFileNext[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_CLEAR, TPS_InFile, 0, NULL},
+ {p_isdigit, 0, A_CLEAR, TPS_InFile, 0, NULL},
+ {p_iseqC, '_', A_CLEAR, TPS_InFile, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InURIFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '"', A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '\'', A_POP, TPS_Null, 0, NULL},
+ {p_isnotspace, 0, A_CLEAR, TPS_InURI, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL},
+};
+
+static TParserStateActionItem actionTPS_InURIStart[] = {
+ {NULL, 0, A_NEXT, TPS_InURI, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InURI[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, URI, NULL},
+ {p_iseqC, '"', A_BINGO, TPS_Base, URI, NULL},
+ {p_iseqC, '\'', A_BINGO, TPS_Base, URI, NULL},
+ {p_isnotspace, 0, A_NEXT, TPS_InURI, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_Base, URI, NULL}
+};
+
+static TParserStateActionItem actionTPS_InFURL[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isURI, 0, A_BINGO | A_CLRALL, TPS_Base, FURL, SpecialFURL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InProtocolFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '/', A_NEXT, TPS_InProtocolSecond, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InProtocolSecond[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_iseqC, '/', A_NEXT, TPS_InProtocolEnd, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InProtocolEnd[] = {
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_Base, PROTOCOL, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenLatWordFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHyphenLatWord, 0, NULL},
+ {p_isnonlatin, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenValue, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenLatWord[] = {
+ {p_isEOF, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, LATHYPHENWORD, SpecialHyphen},
+ {p_islatin, 0, A_NEXT, TPS_InHyphenLatWord, 0, NULL},
+ {p_isnonlatin, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHyphenLatWordFirst, 0, NULL},
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, LATHYPHENWORD, SpecialHyphen}
+};
+
+static TParserStateActionItem actionTPS_InHyphenCyrWordFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isnonlatin, 0, A_NEXT, TPS_InHyphenCyrWord, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenValue, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenCyrWord[] = {
+ {p_isEOF, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, CYRHYPHENWORD, SpecialHyphen},
+ {p_isnonlatin, 0, A_NEXT, TPS_InHyphenCyrWord, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHyphenCyrWordFirst, 0, NULL},
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, CYRHYPHENWORD, SpecialHyphen}
+};
+
+static TParserStateActionItem actionTPS_InHyphenUWordFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenValue, 0, NULL},
+ {p_isalnum, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenUWord[] = {
+ {p_isEOF, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, HYPHENWORD, SpecialHyphen},
+ {p_isalnum, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHyphenUWordFirst, 0, NULL},
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, HYPHENWORD, SpecialHyphen}
+};
+
+static TParserStateActionItem actionTPS_InHyphenValueFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenValueExact, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenValue[] = {
+ {p_isEOF, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, HYPHENWORD, SpecialHyphen},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenValue, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHyphenValueFirst, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHyphenUWordFirst, 0, NULL},
+ {p_isalpha, 0, A_NEXT, TPS_InHyphenUWord, 0, NULL},
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, HYPHENWORD, SpecialHyphen}
+};
+
+static TParserStateActionItem actionTPS_InHyphenValueExact[] = {
+ {p_isEOF, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, HYPHENWORD, SpecialHyphen},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenValueExact, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHyphenValueFirst, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InHyphenUWordFirst, 0, NULL},
+ {NULL, 0, A_BINGO | A_CLRALL, TPS_InParseHyphen, HYPHENWORD, SpecialHyphen}
+};
+
+static TParserStateActionItem actionTPS_InParseHyphen[] = {
+ {p_isEOF, 0, A_RERUN, TPS_Base, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHyphenLatWordPart, 0, NULL},
+ {p_isnonlatin, 0, A_NEXT, TPS_InHyphenCyrWordPart, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenUnsignedInt, 0, NULL},
+ {p_iseqC, '-', A_PUSH, TPS_InParseHyphenHyphen, 0, NULL},
+ {NULL, 0, A_RERUN, TPS_Base, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InParseHyphenHyphen[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isalnum, 0, A_BINGO | A_CLEAR, TPS_InParseHyphen, SPACE, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenCyrWordPart[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, CYRPARTHYPHENWORD, NULL},
+ {p_isnonlatin, 0, A_NEXT, TPS_InHyphenCyrWordPart, 0, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHyphenUWordPart, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenUWordPart, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_InParseHyphen, CYRPARTHYPHENWORD, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenLatWordPart[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, LATPARTHYPHENWORD, NULL},
+ {p_islatin, 0, A_NEXT, TPS_InHyphenLatWordPart, 0, NULL},
+ {p_isnonlatin, 0, A_NEXT, TPS_InHyphenUWordPart, 0, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenUWordPart, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_InParseHyphen, LATPARTHYPHENWORD, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenUWordPart[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, PARTHYPHENWORD, NULL},
+ {p_isalnum, 0, A_NEXT, TPS_InHyphenUWordPart, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_InParseHyphen, PARTHYPHENWORD, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHyphenUnsignedInt[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, UNSIGNEDINT, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHyphenUnsignedInt, 0, NULL},
+ {p_isalpha, 0, A_NEXT, TPS_InHyphenUWordPart, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHDecimalPartFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_InParseHyphen, UNSIGNEDINT, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHDecimalPartFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_CLEAR, TPS_InHDecimalPart, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHDecimalPart[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, DECIMAL, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHDecimalPart, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHVersionPartFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_InParseHyphen, DECIMAL, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHVersionPartFirst[] = {
+ {p_isEOF, 0, A_POP, TPS_Null, 0, NULL},
+ {p_isdigit, 0, A_CLEAR, TPS_InHVersionPart, 0, NULL},
+ {NULL, 0, A_POP, TPS_Null, 0, NULL}
+};
+
+static TParserStateActionItem actionTPS_InHVersionPart[] = {
+ {p_isEOF, 0, A_BINGO, TPS_Base, VERSIONNUMBER, NULL},
+ {p_isdigit, 0, A_NEXT, TPS_InHVersionPart, 0, NULL},
+ {p_iseqC, '.', A_PUSH, TPS_InHVersionPartFirst, 0, NULL},
+ {NULL, 0, A_BINGO, TPS_InParseHyphen, VERSIONNUMBER, NULL}
+};
+
+/*
+ * order should be the same as in typedef enum {} TParserState!!
+ */
+
+static const TParserStateAction Actions[] = {
+ {TPS_Base, actionTPS_Base},
+ {TPS_InUWord, actionTPS_InUWord},
+ {TPS_InLatWord, actionTPS_InLatWord},
+ {TPS_InCyrWord, actionTPS_InCyrWord},
+ {TPS_InUnsignedInt, actionTPS_InUnsignedInt},
+ {TPS_InSignedIntFirst, actionTPS_InSignedIntFirst},
+ {TPS_InSignedInt, actionTPS_InSignedInt},
+ {TPS_InSpace, actionTPS_InSpace},
+ {TPS_InUDecimalFirst, actionTPS_InUDecimalFirst},
+ {TPS_InUDecimal, actionTPS_InUDecimal},
+ {TPS_InDecimalFirst, actionTPS_InDecimalFirst},
+ {TPS_InDecimal, actionTPS_InDecimal},
+ {TPS_InVerVersion, actionTPS_InVerVersion},
+ {TPS_InSVerVersion, actionTPS_InSVerVersion},
+ {TPS_InVersionFirst, actionTPS_InVersionFirst},
+ {TPS_InVersion, actionTPS_InVersion},
+ {TPS_InMantissaFirst, actionTPS_InMantissaFirst},
+ {TPS_InMantissaSign, actionTPS_InMantissaSign},
+ {TPS_InMantissa, actionTPS_InMantissa},
+ {TPS_InHTMLEntityFirst, actionTPS_InHTMLEntityFirst},
+ {TPS_InHTMLEntity, actionTPS_InHTMLEntity},
+ {TPS_InHTMLEntityNumFirst, actionTPS_InHTMLEntityNumFirst},
+ {TPS_InHTMLEntityNum, actionTPS_InHTMLEntityNum},
+ {TPS_InHTMLEntityEnd, actionTPS_InHTMLEntityEnd},
+ {TPS_InTagFirst, actionTPS_InTagFirst},
+ {TPS_InXMLBegin, actionTPS_InXMLBegin},
+ {TPS_InTagCloseFirst, actionTPS_InTagCloseFirst},
+ {TPS_InTagName, actionTPS_InTagName},
+ {TPS_InTagBeginEnd, actionTPS_InTagBeginEnd},
+ {TPS_InTag, actionTPS_InTag},
+ {TPS_InTagEscapeK, actionTPS_InTagEscapeK},
+ {TPS_InTagEscapeKK, actionTPS_InTagEscapeKK},
+ {TPS_InTagBackSleshed, actionTPS_InTagBackSleshed},
+ {TPS_InTagEnd, actionTPS_InTagEnd},
+ {TPS_InCommentFirst, actionTPS_InCommentFirst},
+ {TPS_InCommentLast, actionTPS_InCommentLast},
+ {TPS_InComment, actionTPS_InComment},
+ {TPS_InCloseCommentFirst, actionTPS_InCloseCommentFirst},
+ {TPS_InCloseCommentLast, actionTPS_InCloseCommentLast},
+ {TPS_InCommentEnd, actionTPS_InCommentEnd},
+ {TPS_InHostFirstDomain, actionTPS_InHostFirstDomain},
+ {TPS_InHostDomainSecond, actionTPS_InHostDomainSecond},
+ {TPS_InHostDomain, actionTPS_InHostDomain},
+ {TPS_InPortFirst, actionTPS_InPortFirst},
+ {TPS_InPort, actionTPS_InPort},
+ {TPS_InHostFirstAN, actionTPS_InHostFirstAN},
+ {TPS_InHost, actionTPS_InHost},
+ {TPS_InEmail, actionTPS_InEmail},
+ {TPS_InFileFirst, actionTPS_InFileFirst},
+ {TPS_InFileTwiddle, actionTPS_InFileTwiddle},
+ {TPS_InPathFirst, actionTPS_InPathFirst},
+ {TPS_InPathFirstFirst, actionTPS_InPathFirstFirst},
+ {TPS_InPathSecond, actionTPS_InPathSecond},
+ {TPS_InFile, actionTPS_InFile},
+ {TPS_InFileNext, actionTPS_InFileNext},
+ {TPS_InURIFirst, actionTPS_InURIFirst},
+ {TPS_InURIStart, actionTPS_InURIStart},
+ {TPS_InURI, actionTPS_InURI},
+ {TPS_InFURL, actionTPS_InFURL},
+ {TPS_InProtocolFirst, actionTPS_InProtocolFirst},
+ {TPS_InProtocolSecond, actionTPS_InProtocolSecond},
+ {TPS_InProtocolEnd, actionTPS_InProtocolEnd},
+ {TPS_InHyphenLatWordFirst, actionTPS_InHyphenLatWordFirst},
+ {TPS_InHyphenLatWord, actionTPS_InHyphenLatWord},
+ {TPS_InHyphenCyrWordFirst, actionTPS_InHyphenCyrWordFirst},
+ {TPS_InHyphenCyrWord, actionTPS_InHyphenCyrWord},
+ {TPS_InHyphenUWordFirst, actionTPS_InHyphenUWordFirst},
+ {TPS_InHyphenUWord, actionTPS_InHyphenUWord},
+ {TPS_InHyphenValueFirst, actionTPS_InHyphenValueFirst},
+ {TPS_InHyphenValue, actionTPS_InHyphenValue},
+ {TPS_InHyphenValueExact, actionTPS_InHyphenValueExact},
+ {TPS_InParseHyphen, actionTPS_InParseHyphen},
+ {TPS_InParseHyphenHyphen, actionTPS_InParseHyphenHyphen},
+ {TPS_InHyphenCyrWordPart, actionTPS_InHyphenCyrWordPart},
+ {TPS_InHyphenLatWordPart, actionTPS_InHyphenLatWordPart},
+ {TPS_InHyphenUWordPart, actionTPS_InHyphenUWordPart},
+ {TPS_InHyphenUnsignedInt, actionTPS_InHyphenUnsignedInt},
+ {TPS_InHDecimalPartFirst, actionTPS_InHDecimalPartFirst},
+ {TPS_InHDecimalPart, actionTPS_InHDecimalPart},
+ {TPS_InHVersionPartFirst, actionTPS_InHVersionPartFirst},
+ {TPS_InHVersionPart, actionTPS_InHVersionPart},
+ {TPS_Null, NULL}
+};
+
+
+static bool
+TParserGet(TParser * prs)
+{
+ TParserStateActionItem *item = NULL;
+
+ if (prs->state->posbyte >= prs->lenstr)
+ return false;
+
+ Assert(prs->state);
+ prs->lexeme = prs->str + prs->state->posbyte;
+ prs->state->pushedAtAction = NULL;
+
+ /* look at string */
+ while (prs->state->posbyte <= prs->lenstr)
+ {
+ if (prs->state->posbyte == prs->lenstr)
+ prs->state->charlen = 0;
+ else
+ prs->state->charlen = (prs->charmaxlen == 1) ? prs->charmaxlen :
+ pg_mblen(prs->str + prs->state->posbyte);
+
+ Assert(prs->state->posbyte + prs->state->charlen <= prs->lenstr);
+ Assert(prs->state->state >= TPS_Base && prs->state->state < TPS_Null);
+ Assert(Actions[prs->state->state].state == prs->state->state);
+
+ item = Actions[prs->state->state].action;
+ Assert(item != NULL);
+
+ if (item < prs->state->pushedAtAction)
+ item = prs->state->pushedAtAction;
+
+ /* find action by character class */
+ while (item->isclass)
+ {
+ prs->c = item->c;
+ if (item->isclass(prs) != 0)
+ {
+ if (item > prs->state->pushedAtAction) /* remember: after
+ * pushing we were by
+ * false way */
+ break;
+ }
+ item++;
+ }
+
+ prs->state->pushedAtAction = NULL;
+
+ /* call special handler if exists */
+ if (item->special)
+ item->special(prs);
+
+ /* BINGO, lexeme is found */
+ if (item->flags & A_BINGO)
+ {
+ Assert(item->type > 0);
+ prs->lenbytelexeme = prs->state->lenbytelexeme;
+ prs->lencharlexeme = prs->state->lencharlexeme;
+ prs->state->lenbytelexeme = prs->state->lencharlexeme = 0;
+ prs->type = item->type;
+ }
+
+ /* do various actions by flags */
+ if (item->flags & A_POP)
+ { /* pop stored state in stack */
+ TParserPosition *ptr = prs->state->prev;
+
+ pfree(prs->state);
+ prs->state = ptr;
+ Assert(prs->state);
+ }
+ else if (item->flags & A_PUSH)
+ { /* push (store) state in stack */
+ prs->state->pushedAtAction = item; /* remember where we push */
+ prs->state = newTParserPosition(prs->state);
+ }
+ else if (item->flags & A_CLEAR)
+ { /* clear previous pushed state */
+ TParserPosition *ptr;
+
+ Assert(prs->state->prev);
+ ptr = prs->state->prev->prev;
+ pfree(prs->state->prev);
+ prs->state->prev = ptr;
+ }
+ else if (item->flags & A_CLRALL)
+ { /* clear all previous pushed state */
+ TParserPosition *ptr;
+
+ while (prs->state->prev)
+ {
+ ptr = prs->state->prev->prev;
+ pfree(prs->state->prev);
+ prs->state->prev = ptr;
+ }
+ }
+ else if (item->flags & A_MERGE)
+ { /* merge posinfo with current and pushed state */
+ TParserPosition *ptr = prs->state;
+
+ Assert(prs->state->prev);
+ prs->state = prs->state->prev;
+
+ prs->state->posbyte = ptr->posbyte;
+ prs->state->poschar = ptr->poschar;
+ prs->state->charlen = ptr->charlen;
+ prs->state->lenbytelexeme = ptr->lenbytelexeme;
+ prs->state->lencharlexeme = ptr->lencharlexeme;
+ pfree(ptr);
+ }
+
+ /* set new state if pointed */
+ if (item->tostate != TPS_Null)
+ prs->state->state = item->tostate;
+
+ /* check for go away */
+ if ((item->flags & A_BINGO) || (prs->state->posbyte >= prs->lenstr && (item->flags & A_RERUN) == 0))
+ break;
+
+ /* go to begining of loop if we should rerun or we just restore state */
+ if (item->flags & (A_RERUN | A_POP))
+ continue;
+
+ /* move forward */
+ if (prs->state->charlen)
+ {
+ prs->state->posbyte += prs->state->charlen;
+ prs->state->lenbytelexeme += prs->state->charlen;
+ prs->state->poschar++;
+ prs->state->lencharlexeme++;
+ }
+ }
+
+ return (item && (item->flags & A_BINGO)) ? true : false;
+}
+
+Datum
+prsd_lextype(PG_FUNCTION_ARGS)
+{
+ LexDescr *descr = (LexDescr *) palloc(sizeof(LexDescr) * (LASTNUM + 1));
+ int i;
+
+ for (i = 1; i <= LASTNUM; i++)
+ {
+ descr[i - 1].lexid = i;
+ descr[i - 1].alias = pstrdup(tok_alias[i]);
+ descr[i - 1].descr = pstrdup(lex_descr[i]);
+ }
+
+ descr[LASTNUM].lexid = 0;
+
+ PG_RETURN_POINTER(descr);
+}
+
+Datum
+prsd_start(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_POINTER(TParserInit((char *) PG_GETARG_POINTER(0), PG_GETARG_INT32(1)));
+}
+
+Datum
+prsd_nexttoken(PG_FUNCTION_ARGS)
+{
+ TParser *p = (TParser *) PG_GETARG_POINTER(0);
+ char **t = (char **) PG_GETARG_POINTER(1);
+ int *tlen = (int *) PG_GETARG_POINTER(2);
+
+ if (!TParserGet(p))
+ PG_RETURN_INT32(0);
+
+ *t = p->lexeme;
+ *tlen = p->lenbytelexeme;
+
+ PG_RETURN_INT32(p->type);
+}
+
+Datum
+prsd_end(PG_FUNCTION_ARGS)
+{
+ TParser *p = (TParser *) PG_GETARG_POINTER(0);
+
+ TParserClose(p);
+ PG_RETURN_VOID();
+}
+
+#define LEAVETOKEN(x) ( (x)==12 )
+#define COMPLEXTOKEN(x) ( (x)==5 || (x)==15 || (x)==16 || (x)==17 )
+#define ENDPUNCTOKEN(x) ( (x)==12 )
+
+
+#define TS_IDIGNORE(x) ( (x)==13 || (x)==14 || (x)==12 || (x)==23 )
+#define HLIDIGNORE(x) ( (x)==5 || (x)==13 || (x)==15 || (x)==16 || (x)==17 )
+#define HTMLHLIDIGNORE(x) ( (x)==5 || (x)==15 || (x)==16 || (x)==17 )
+#define NONWORDTOKEN(x) ( (x)==12 || HLIDIGNORE(x) )
+#define NOENDTOKEN(x) ( NONWORDTOKEN(x) || (x)==7 || (x)==8 || (x)==20 || (x)==21 || (x)==22 || TS_IDIGNORE(x) )
+
+typedef struct
+{
+ HeadlineWordEntry *words;
+ int len;
+} hlCheck;
+
+static bool
+checkcondition_HL(void *checkval, QueryItem * val)
+{
+ int i;
+
+ for (i = 0; i < ((hlCheck *) checkval)->len; i++)
+ {
+ if (((hlCheck *) checkval)->words[i].item == val)
+ return true;
+ }
+ return false;
+}
+
+
+static bool
+hlCover(HeadlineParsedText * prs, TSQuery query, int *p, int *q)
+{
+ int i,
+ j;
+ QueryItem *item = GETQUERY(query);
+ int pos = *p;
+
+ *q = 0;
+ *p = 0x7fffffff;
+
+ for (j = 0; j < query->size; j++)
+ {
+ if (item->type != VAL)
+ {
+ item++;
+ continue;
+ }
+ for (i = pos; i < prs->curwords; i++)
+ {
+ if (prs->words[i].item == item)
+ {
+ if (i > *q)
+ *q = i;
+ break;
+ }
+ }
+ item++;
+ }
+
+ if (*q == 0)
+ return false;
+
+ item = GETQUERY(query);
+ for (j = 0; j < query->size; j++)
+ {
+ if (item->type != VAL)
+ {
+ item++;
+ continue;
+ }
+ for (i = *q; i >= pos; i--)
+ {
+ if (prs->words[i].item == item)
+ {
+ if (i < *p)
+ *p = i;
+ break;
+ }
+ }
+ item++;
+ }
+
+ if (*p <= *q)
+ {
+ hlCheck ch;
+
+ ch.words = &(prs->words[*p]);
+ ch.len = *q - *p + 1;
+ if (TS_execute(GETQUERY(query), &ch, false, checkcondition_HL))
+ return true;
+ else
+ {
+ (*p)++;
+ return hlCover(prs, query, p, q);
+ }
+ }
+
+ return false;
+}
+
+Datum
+prsd_headline(PG_FUNCTION_ARGS)
+{
+ HeadlineParsedText *prs = (HeadlineParsedText *) PG_GETARG_POINTER(0);
+ text *opt = (text *) PG_GETARG_POINTER(1); /* can't be toasted */
+ TSQuery query = PG_GETARG_TSQUERY(2);
+
+ /* from opt + start and and tag */
+ int min_words = 15;
+ int max_words = 35;
+ int shortword = 3;
+
+ int p = 0,
+ q = 0;
+ int bestb = -1,
+ beste = -1;
+ int bestlen = -1;
+ int pose = 0,
+ posb,
+ poslen,
+ curlen;
+
+ int i;
+ int highlight = 0;
+
+ /* config */
+ prs->startsel = NULL;
+ prs->stopsel = NULL;
+ if (opt)
+ {
+ Map *map,
+ *mptr;
+
+ parse_keyvalpairs(opt, &map);
+ mptr = map;
+
+ while (mptr && mptr->key)
+ {
+ if (pg_strcasecmp(mptr->key, "MaxWords") == 0)
+ max_words = pg_atoi(mptr->value, 4, 1);
+ else if (pg_strcasecmp(mptr->key, "MinWords") == 0)
+ min_words = pg_atoi(mptr->value, 4, 1);
+ else if (pg_strcasecmp(mptr->key, "ShortWord") == 0)
+ shortword = pg_atoi(mptr->value, 4, 1);
+ else if (pg_strcasecmp(mptr->key, "StartSel") == 0)
+ prs->startsel = pstrdup(mptr->value);
+ else if (pg_strcasecmp(mptr->key, "StopSel") == 0)
+ prs->stopsel = pstrdup(mptr->value);
+ else if (pg_strcasecmp(mptr->key, "HighlightAll") == 0)
+ highlight = (
+ pg_strcasecmp(mptr->value, "1") == 0 ||
+ pg_strcasecmp(mptr->value, "on") == 0 ||
+ pg_strcasecmp(mptr->value, "true") == 0 ||
+ pg_strcasecmp(mptr->value, "t") == 0 ||
+ pg_strcasecmp(mptr->value, "y") == 0 ||
+ pg_strcasecmp(mptr->value, "yes") == 0) ?
+ 1 : 0;
+
+ pfree(mptr->key);
+ pfree(mptr->value);
+
+ mptr++;
+ }
+ pfree(map);
+
+ if (highlight == 0)
+ {
+ if (min_words >= max_words)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("MinWords should be less than MaxWords")));
+ if (min_words <= 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("MinWords should be positive")));
+ if (shortword < 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("ShortWord should be >= 0")));
+ }
+ }
+
+ if (highlight == 0)
+ {
+ while (hlCover(prs, query, &p, &q))
+ {
+ /* find cover len in words */
+ curlen = 0;
+ poslen = 0;
+ for (i = p; i <= q && curlen < max_words; i++)
+ {
+ if (!NONWORDTOKEN(prs->words[i].type))
+ curlen++;
+ if (prs->words[i].item && !prs->words[i].repeated)
+ poslen++;
+ pose = i;
+ }
+
+ if (poslen < bestlen && !(NOENDTOKEN(prs->words[beste].type) || prs->words[beste].len <= shortword))
+ {
+ /* best already finded, so try one more cover */
+ p++;
+ continue;
+ }
+
+ posb = p;
+ if (curlen < max_words)
+ { /* find good end */
+ for (i = i - 1; i < prs->curwords && curlen < max_words; i++)
+ {
+ if (i != q)
+ {
+ if (!NONWORDTOKEN(prs->words[i].type))
+ curlen++;
+ if (prs->words[i].item && !prs->words[i].repeated)
+ poslen++;
+ }
+ pose = i;
+ if (NOENDTOKEN(prs->words[i].type) || prs->words[i].len <= shortword)
+ continue;
+ if (curlen >= min_words)
+ break;
+ }
+ if (curlen < min_words && i >= prs->curwords)
+ { /* got end of text and our cover is shoter
+ * than min_words */
+ for (i = p; i >= 0; i--)
+ {
+ if (!NONWORDTOKEN(prs->words[i].type))
+ curlen++;
+ if (prs->words[i].item && !prs->words[i].repeated)
+ poslen++;
+ if (NOENDTOKEN(prs->words[i].type) || prs->words[i].len <= shortword)
+ continue;
+ if (curlen >= min_words)
+ break;
+ }
+ posb = (i >= 0) ? i : 0;
+ }
+ }
+ else
+ { /* shorter cover :((( */
+ for (; curlen > min_words; i--)
+ {
+ if (!NONWORDTOKEN(prs->words[i].type))
+ curlen--;
+ if (prs->words[i].item && !prs->words[i].repeated)
+ poslen--;
+ pose = i;
+ if (NOENDTOKEN(prs->words[i].type) || prs->words[i].len <= shortword)
+ continue;
+ break;
+ }
+ }
+
+ if (bestlen < 0 || (poslen > bestlen && !(NOENDTOKEN(prs->words[pose].type) || prs->words[pose].len <= shortword)) ||
+ (bestlen >= 0 && !(NOENDTOKEN(prs->words[pose].type) || prs->words[pose].len <= shortword) &&
+ (NOENDTOKEN(prs->words[beste].type) || prs->words[beste].len <= shortword)))
+ {
+ bestb = posb;
+ beste = pose;
+ bestlen = poslen;
+ }
+
+ p++;
+ }
+
+ if (bestlen < 0)
+ {
+ curlen = 0;
+ for (i = 0; i < prs->curwords && curlen < min_words; i++)
+ {
+ if (!NONWORDTOKEN(prs->words[i].type))
+ curlen++;
+ pose = i;
+ }
+ bestb = 0;
+ beste = pose;
+ }
+ }
+ else
+ {
+ bestb = 0;
+ beste = prs->curwords - 1;
+ }
+
+ for (i = bestb; i <= beste; i++)
+ {
+ if (prs->words[i].item)
+ prs->words[i].selected = 1;
+ if (highlight == 0)
+ {
+ if (HLIDIGNORE(prs->words[i].type))
+ prs->words[i].replace = 1;
+ }
+ else
+ {
+ if (HTMLHLIDIGNORE(prs->words[i].type))
+ prs->words[i].replace = 1;
+ }
+
+ prs->words[i].in = (prs->words[i].repeated) ? 0 : 1;
+ }
+
+ if (!prs->startsel)
+ prs->startsel = pstrdup("<b>");
+ if (!prs->stopsel)
+ prs->stopsel = pstrdup("</b>");
+ prs->startsellen = strlen(prs->startsel);
+ prs->stopsellen = strlen(prs->stopsel);
+
+ PG_RETURN_POINTER(prs);
+}
diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index 12d158a49bd..73fcebb496d 100644
--- a/src/backend/utils/adt/Makefile
+++ b/src/backend/utils/adt/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for utils/adt
#
-# $PostgreSQL: pgsql/src/backend/utils/adt/Makefile,v 1.64 2007/04/02 03:49:39 tgl Exp $
+# $PostgreSQL: pgsql/src/backend/utils/adt/Makefile,v 1.65 2007/08/21 01:11:18 tgl Exp $
#
subdir = src/backend/utils/adt
@@ -25,8 +25,11 @@ OBJS = acl.o arrayfuncs.o array_userfuncs.o arrayutils.o bool.o \
tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \
network.o mac.o inet_net_ntop.o inet_net_pton.o \
ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \
- ascii.o quote.o pgstatfuncs.o encode.o dbsize.o genfile.o xml.o \
- uuid.o
+ ascii.o quote.o pgstatfuncs.o encode.o dbsize.o genfile.o \
+ tsginidx.o tsgistidx.o tsquery.o tsquery_cleanup.o tsquery_gist.o \
+ tsquery_op.o tsquery_rewrite.o tsquery_util.o tsrank.o \
+ tsvector.o tsvector_op.o \
+ uuid.o xml.o
like.o: like.c like_match.c
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 7ec9db3ec9b..e49f323daa8 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.102 2007/06/26 16:48:09 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/regproc.c,v 1.103 2007/08/21 01:11:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,6 +27,8 @@
#include "catalog/namespace.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_dict.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "parser/parse_type.h"
@@ -1066,6 +1068,231 @@ regtypesend(PG_FUNCTION_ARGS)
/*
+ * regconfigin - converts "tsconfigname" to tsconfig OID
+ *
+ * We also accept a numeric OID, for symmetry with the output routine.
+ *
+ * '-' signifies unknown (OID 0). In all other cases, the input must
+ * match an existing pg_ts_config entry.
+ *
+ * This function is not needed in bootstrap mode, so we don't worry about
+ * making it work then.
+ */
+Datum
+regconfigin(PG_FUNCTION_ARGS)
+{
+ char *cfg_name_or_oid = PG_GETARG_CSTRING(0);
+ Oid result;
+ List *names;
+
+ /* '-' ? */
+ if (strcmp(cfg_name_or_oid, "-") == 0)
+ PG_RETURN_OID(InvalidOid);
+
+ /* Numeric OID? */
+ if (cfg_name_or_oid[0] >= '0' &&
+ cfg_name_or_oid[0] <= '9' &&
+ strspn(cfg_name_or_oid, "0123456789") == strlen(cfg_name_or_oid))
+ {
+ result = DatumGetObjectId(DirectFunctionCall1(oidin,
+ CStringGetDatum(cfg_name_or_oid)));
+ PG_RETURN_OID(result);
+ }
+
+ /*
+ * Normal case: parse the name into components and see if it matches any
+ * pg_ts_config entries in the current search path.
+ */
+ names = stringToQualifiedNameList(cfg_name_or_oid);
+
+ result = TSConfigGetCfgid(names, false);
+
+ PG_RETURN_OID(result);
+}
+
+/*
+ * regconfigout - converts tsconfig OID to "tsconfigname"
+ */
+Datum
+regconfigout(PG_FUNCTION_ARGS)
+{
+ Oid cfgid = PG_GETARG_OID(0);
+ char *result;
+ HeapTuple cfgtup;
+
+ if (cfgid == InvalidOid)
+ {
+ result = pstrdup("-");
+ PG_RETURN_CSTRING(result);
+ }
+
+ cfgtup = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(cfgid),
+ 0, 0, 0);
+
+ if (HeapTupleIsValid(cfgtup))
+ {
+ Form_pg_ts_config cfgform = (Form_pg_ts_config) GETSTRUCT(cfgtup);
+ char *cfgname = NameStr(cfgform->cfgname);
+ char *nspname;
+
+ /*
+ * Would this config be found by regconfigin? If not, qualify it.
+ */
+ if (TSConfigIsVisible(cfgid))
+ nspname = NULL;
+ else
+ nspname = get_namespace_name(cfgform->cfgnamespace);
+
+ result = quote_qualified_identifier(nspname, cfgname);
+
+ ReleaseSysCache(cfgtup);
+ }
+ else
+ {
+ /* If OID doesn't match any pg_ts_config row, return it numerically */
+ result = (char *) palloc(NAMEDATALEN);
+ snprintf(result, NAMEDATALEN, "%u", cfgid);
+ }
+
+ PG_RETURN_CSTRING(result);
+}
+
+/*
+ * regconfigrecv - converts external binary format to regconfig
+ */
+Datum
+regconfigrecv(PG_FUNCTION_ARGS)
+{
+ /* Exactly the same as oidrecv, so share code */
+ return oidrecv(fcinfo);
+}
+
+/*
+ * regconfigsend - converts regconfig to binary format
+ */
+Datum
+regconfigsend(PG_FUNCTION_ARGS)
+{
+ /* Exactly the same as oidsend, so share code */
+ return oidsend(fcinfo);
+}
+
+
+/*
+ * regdictionaryin - converts "tsdictionaryname" to tsdictionary OID
+ *
+ * We also accept a numeric OID, for symmetry with the output routine.
+ *
+ * '-' signifies unknown (OID 0). In all other cases, the input must
+ * match an existing pg_ts_dict entry.
+ *
+ * This function is not needed in bootstrap mode, so we don't worry about
+ * making it work then.
+ */
+Datum
+regdictionaryin(PG_FUNCTION_ARGS)
+{
+ char *dict_name_or_oid = PG_GETARG_CSTRING(0);
+ Oid result;
+ List *names;
+
+ /* '-' ? */
+ if (strcmp(dict_name_or_oid, "-") == 0)
+ PG_RETURN_OID(InvalidOid);
+
+ /* Numeric OID? */
+ if (dict_name_or_oid[0] >= '0' &&
+ dict_name_or_oid[0] <= '9' &&
+ strspn(dict_name_or_oid, "0123456789") == strlen(dict_name_or_oid))
+ {
+ result = DatumGetObjectId(DirectFunctionCall1(oidin,
+ CStringGetDatum(dict_name_or_oid)));
+ PG_RETURN_OID(result);
+ }
+
+ /*
+ * Normal case: parse the name into components and see if it matches any
+ * pg_ts_dict entries in the current search path.
+ */
+ names = stringToQualifiedNameList(dict_name_or_oid);
+
+ result = TSDictionaryGetDictid(names, false);
+
+ PG_RETURN_OID(result);
+}
+
+/*
+ * regdictionaryout - converts tsdictionary OID to "tsdictionaryname"
+ */
+Datum
+regdictionaryout(PG_FUNCTION_ARGS)
+{
+ Oid dictid = PG_GETARG_OID(0);
+ char *result;
+ HeapTuple dicttup;
+
+ if (dictid == InvalidOid)
+ {
+ result = pstrdup("-");
+ PG_RETURN_CSTRING(result);
+ }
+
+ dicttup = SearchSysCache(TSDICTOID,
+ ObjectIdGetDatum(dictid),
+ 0, 0, 0);
+
+ if (HeapTupleIsValid(dicttup))
+ {
+ Form_pg_ts_dict dictform = (Form_pg_ts_dict) GETSTRUCT(dicttup);
+ char *dictname = NameStr(dictform->dictname);
+ char *nspname;
+
+ /*
+ * Would this dictionary be found by regdictionaryin?
+ * If not, qualify it.
+ */
+ if (TSDictionaryIsVisible(dictid))
+ nspname = NULL;
+ else
+ nspname = get_namespace_name(dictform->dictnamespace);
+
+ result = quote_qualified_identifier(nspname, dictname);
+
+ ReleaseSysCache(dicttup);
+ }
+ else
+ {
+ /* If OID doesn't match any pg_ts_dict row, return it numerically */
+ result = (char *) palloc(NAMEDATALEN);
+ snprintf(result, NAMEDATALEN, "%u", dictid);
+ }
+
+ PG_RETURN_CSTRING(result);
+}
+
+/*
+ * regdictionaryrecv - converts external binary format to regdictionary
+ */
+Datum
+regdictionaryrecv(PG_FUNCTION_ARGS)
+{
+ /* Exactly the same as oidrecv, so share code */
+ return oidrecv(fcinfo);
+}
+
+/*
+ * regdictionarysend - converts regdictionary to binary format
+ */
+Datum
+regdictionarysend(PG_FUNCTION_ARGS)
+{
+ /* Exactly the same as oidsend, so share code */
+ return oidsend(fcinfo);
+}
+
+
+/*
* text_regclass: convert text to regclass
*
* This could be replaced by CoerceViaIO, except that we need to treat
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 1ba0b4eac48..60da08b1ec4 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.234 2007/05/05 17:05:48 mha Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.235 2007/08/21 01:11:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2822,6 +2822,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
case REGOPERATOROID:
case REGCLASSOID:
case REGTYPEOID:
+ case REGCONFIGOID:
+ case REGDICTIONARYOID:
*scaledvalue = convert_numeric_to_scalar(value, valuetypid);
*scaledlobound = convert_numeric_to_scalar(lobound, boundstypid);
*scaledhibound = convert_numeric_to_scalar(hibound, boundstypid);
@@ -2925,6 +2927,8 @@ convert_numeric_to_scalar(Datum value, Oid typid)
case REGOPERATOROID:
case REGCLASSOID:
case REGTYPEOID:
+ case REGCONFIGOID:
+ case REGDICTIONARYOID:
/* we can treat OIDs as integers... */
return (double) DatumGetObjectId(value);
}
diff --git a/src/backend/utils/adt/tsginidx.c b/src/backend/utils/adt/tsginidx.c
new file mode 100644
index 00000000000..491dd21aa81
--- /dev/null
+++ b/src/backend/utils/adt/tsginidx.c
@@ -0,0 +1,157 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsginidx.c
+ * GIN support functions for tsvector_ops
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsginidx.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/skey.h"
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+
+
+Datum
+gin_extract_tsvector(PG_FUNCTION_ARGS)
+{
+ TSVector vector = PG_GETARG_TSVECTOR(0);
+ uint32 *nentries = (uint32 *) PG_GETARG_POINTER(1);
+ Datum *entries = NULL;
+
+ *nentries = 0;
+ if (vector->size > 0)
+ {
+ int i;
+ WordEntry *we = ARRPTR(vector);
+
+ *nentries = (uint32) vector->size;
+ entries = (Datum *) palloc(sizeof(Datum) * vector->size);
+
+ for (i = 0; i < vector->size; i++)
+ {
+ text *txt = (text *) palloc(VARHDRSZ + we->len);
+
+ SET_VARSIZE(txt, VARHDRSZ + we->len);
+ memcpy(VARDATA(txt), STRPTR(vector) + we->pos, we->len);
+
+ entries[i] = PointerGetDatum(txt);
+
+ we++;
+ }
+ }
+
+ PG_FREE_IF_COPY(vector, 0);
+ PG_RETURN_POINTER(entries);
+}
+
+Datum
+gin_extract_query(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY(0);
+ uint32 *nentries = (uint32 *) PG_GETARG_POINTER(1);
+ StrategyNumber strategy = PG_GETARG_UINT16(2);
+ Datum *entries = NULL;
+
+ *nentries = 0;
+
+ if (query->size > 0)
+ {
+ int4 i,
+ j = 0,
+ len;
+ QueryItem *item;
+
+ item = clean_NOT(GETQUERY(query), &len);
+ if (!item)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("query requires full scan, which is not supported by GIN indexes")));
+
+ item = GETQUERY(query);
+
+ for (i = 0; i < query->size; i++)
+ if (item[i].type == VAL)
+ (*nentries)++;
+
+ entries = (Datum *) palloc(sizeof(Datum) * (*nentries));
+
+ for (i = 0; i < query->size; i++)
+ if (item[i].type == VAL)
+ {
+ text *txt;
+
+ txt = (text *) palloc(VARHDRSZ + item[i].length);
+
+ SET_VARSIZE(txt, VARHDRSZ + item[i].length);
+ memcpy(VARDATA(txt), GETOPERAND(query) + item[i].distance, item[i].length);
+
+ entries[j++] = PointerGetDatum(txt);
+
+ if (strategy != TSearchWithClassStrategyNumber && item[i].weight != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("@@ operator does not support lexeme class restrictions"),
+ errhint("Use the @@@ operator instead.")));
+ }
+ }
+ else
+ *nentries = -1; /* nothing can be found */
+
+ PG_FREE_IF_COPY(query, 0);
+
+ PG_RETURN_POINTER(entries);
+}
+
+typedef struct
+{
+ QueryItem *frst;
+ bool *mapped_check;
+} GinChkVal;
+
+static bool
+checkcondition_gin(void *checkval, QueryItem * val)
+{
+ GinChkVal *gcv = (GinChkVal *) checkval;
+
+ return gcv->mapped_check[val - gcv->frst];
+}
+
+Datum
+gin_ts_consistent(PG_FUNCTION_ARGS)
+{
+ bool *check = (bool *) PG_GETARG_POINTER(0);
+ /* StrategyNumber strategy = PG_GETARG_UINT16(1); */
+ TSQuery query = PG_GETARG_TSQUERY(2);
+ bool res = FALSE;
+
+ if (query->size > 0)
+ {
+ int4 i,
+ j = 0;
+ QueryItem *item;
+ GinChkVal gcv;
+
+ gcv.frst = item = GETQUERY(query);
+ gcv.mapped_check = (bool *) palloc(sizeof(bool) * query->size);
+
+ for (i = 0; i < query->size; i++)
+ if (item[i].type == VAL)
+ gcv.mapped_check[i] = check[j++];
+
+ res = TS_execute(
+ GETQUERY(query),
+ &gcv,
+ true,
+ checkcondition_gin
+ );
+ }
+
+ PG_RETURN_BOOL(res);
+}
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
new file mode 100644
index 00000000000..04c2b4c442f
--- /dev/null
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -0,0 +1,784 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsgistidx.c
+ * GiST support functions for tsvector_ops
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsgistidx.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "access/gist.h"
+#include "access/tuptoaster.h"
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+#include "utils/pg_crc.h"
+
+
+#define SIGLENINT 31 /* >121 => key will toast, so it will not work
+ * !!! */
+
+#define SIGLEN ( sizeof(int4) * SIGLENINT )
+#define SIGLENBIT (SIGLEN * BITS_PER_BYTE)
+
+typedef char BITVEC[SIGLEN];
+typedef char *BITVECP;
+
+#define LOOPBYTE(a) \
+ for(i=0;i<SIGLEN;i++) {\
+ a;\
+}
+
+#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
+#define GETBITBYTE(x,i) ( ((char)(x)) >> (i) & 0x01 )
+#define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITS_PER_BYTE ) )
+#define SETBIT(x,i) GETBYTE(x,i) |= ( 0x01 << ( (i) % BITS_PER_BYTE ) )
+#define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITS_PER_BYTE )) & 0x01 )
+
+#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT)
+#define HASH(sign, val) SETBIT((sign), HASHVAL(val))
+
+#define GETENTRY(vec,pos) ((SignTSVector *) DatumGetPointer((vec)->vector[(pos)].key))
+
+/*
+ * type of GiST index key
+ */
+
+typedef struct
+{
+ int32 vl_len_; /* varlena header (do not touch directly!) */ ;
+ int4 flag;
+ char data[1];
+} SignTSVector;
+
+#define ARRKEY 0x01
+#define SIGNKEY 0x02
+#define ALLISTRUE 0x04
+
+#define ISARRKEY(x) ( ((SignTSVector*)(x))->flag & ARRKEY )
+#define ISSIGNKEY(x) ( ((SignTSVector*)(x))->flag & SIGNKEY )
+#define ISALLTRUE(x) ( ((SignTSVector*)(x))->flag & ALLISTRUE )
+
+#define GTHDRSIZE ( VARHDRSZ + sizeof(int4) )
+#define CALCGTSIZE(flag, len) ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int4)) : (((flag) & ALLISTRUE) ? 0 : SIGLEN) ) )
+
+#define GETSIGN(x) ( (BITVECP)( (char*)(x)+GTHDRSIZE ) )
+#define GETARR(x) ( (int4*)( (char*)(x)+GTHDRSIZE ) )
+#define ARRNELEM(x) ( ( VARSIZE(x) - GTHDRSIZE )/sizeof(int4) )
+
+/* Number of one-bits in an unsigned byte */
+static const uint8 number_of_ones[256] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
+
+static int4 sizebitvec(BITVECP sign);
+
+Datum
+gtsvectorin(PG_FUNCTION_ARGS)
+{
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("gtsvector_in not implemented")));
+ PG_RETURN_DATUM(0);
+}
+
+#define SINGOUTSTR "%d true bits, %d false bits"
+#define ARROUTSTR "%d unique words"
+#define EXTRALEN ( 2*13 )
+
+static int outbuf_maxlen = 0;
+
+Datum
+gtsvectorout(PG_FUNCTION_ARGS)
+{
+ SignTSVector *key = (SignTSVector *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_POINTER(0)));
+ char *outbuf;
+
+ if (outbuf_maxlen == 0)
+ outbuf_maxlen = 2 * EXTRALEN + Max(strlen(SINGOUTSTR), strlen(ARROUTSTR)) + 1;
+ outbuf = palloc(outbuf_maxlen);
+
+ if (ISARRKEY(key))
+ sprintf(outbuf, ARROUTSTR, (int) ARRNELEM(key));
+ else
+ {
+ int cnttrue = (ISALLTRUE(key)) ? SIGLENBIT : sizebitvec(GETSIGN(key));
+
+ sprintf(outbuf, SINGOUTSTR, cnttrue, (int) SIGLENBIT - cnttrue);
+ }
+
+ PG_FREE_IF_COPY(key, 0);
+ PG_RETURN_POINTER(outbuf);
+}
+
+static int
+compareint(const void *a, const void *b)
+{
+ if (*((int4 *) a) == *((int4 *) b))
+ return 0;
+ return (*((int4 *) a) > *((int4 *) b)) ? 1 : -1;
+}
+
+static int
+uniqueint(int4 *a, int4 l)
+{
+ int4 *ptr,
+ *res;
+
+ if (l == 1)
+ return l;
+
+ ptr = res = a;
+
+ qsort((void *) a, l, sizeof(int4), compareint);
+
+ while (ptr - a < l)
+ if (*ptr != *res)
+ *(++res) = *ptr++;
+ else
+ ptr++;
+ return res + 1 - a;
+}
+
+static void
+makesign(BITVECP sign, SignTSVector * a)
+{
+ int4 k,
+ len = ARRNELEM(a);
+ int4 *ptr = GETARR(a);
+
+ MemSet((void *) sign, 0, sizeof(BITVEC));
+ for (k = 0; k < len; k++)
+ HASH(sign, ptr[k]);
+}
+
+Datum
+gtsvector_compress(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *retval = entry;
+
+ if (entry->leafkey)
+ { /* tsvector */
+ SignTSVector *res;
+ TSVector val = DatumGetTSVector(entry->key);
+ int4 len;
+ int4 *arr;
+ WordEntry *ptr = ARRPTR(val);
+ char *words = STRPTR(val);
+
+ len = CALCGTSIZE(ARRKEY, val->size);
+ res = (SignTSVector *) palloc(len);
+ SET_VARSIZE(res, len);
+ res->flag = ARRKEY;
+ arr = GETARR(res);
+ len = val->size;
+ while (len--)
+ {
+ pg_crc32 c;
+
+ INIT_CRC32(c);
+ COMP_CRC32(c, words + ptr->pos, ptr->len);
+ FIN_CRC32(c);
+
+ *arr = *(int4 *) &c;
+ arr++;
+ ptr++;
+ }
+
+ len = uniqueint(GETARR(res), val->size);
+ if (len != val->size)
+ {
+ /*
+ * there is a collision of hash-function; len is always less than
+ * val->size
+ */
+ len = CALCGTSIZE(ARRKEY, len);
+ res = (SignTSVector *) repalloc((void *) res, len);
+ SET_VARSIZE(res, len);
+ }
+
+ /* make signature, if array is too long */
+ if (VARSIZE(res) > TOAST_INDEX_TARGET)
+ {
+ SignTSVector *ressign;
+
+ len = CALCGTSIZE(SIGNKEY, 0);
+ ressign = (SignTSVector *) palloc(len);
+ SET_VARSIZE(ressign, len);
+ ressign->flag = SIGNKEY;
+ makesign(GETSIGN(ressign), res);
+ res = ressign;
+ }
+
+ retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
+ gistentryinit(*retval, PointerGetDatum(res),
+ entry->rel, entry->page,
+ entry->offset, FALSE);
+ }
+ else if (ISSIGNKEY(DatumGetPointer(entry->key)) &&
+ !ISALLTRUE(DatumGetPointer(entry->key)))
+ {
+ int4 i,
+ len;
+ SignTSVector *res;
+ BITVECP sign = GETSIGN(DatumGetPointer(entry->key));
+
+ LOOPBYTE(
+ if ((sign[i] & 0xff) != 0xff)
+ PG_RETURN_POINTER(retval);
+ );
+
+ len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0);
+ res = (SignTSVector *) palloc(len);
+ SET_VARSIZE(res, len);
+ res->flag = SIGNKEY | ALLISTRUE;
+
+ retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
+ gistentryinit(*retval, PointerGetDatum(res),
+ entry->rel, entry->page,
+ entry->offset, FALSE);
+ }
+ PG_RETURN_POINTER(retval);
+}
+
+Datum
+gtsvector_decompress(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ SignTSVector *key = (SignTSVector *) DatumGetPointer(PG_DETOAST_DATUM(entry->key));
+
+ if (key != (SignTSVector *) DatumGetPointer(entry->key))
+ {
+ GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
+
+ gistentryinit(*retval, PointerGetDatum(key),
+ entry->rel, entry->page,
+ entry->offset, FALSE);
+
+ PG_RETURN_POINTER(retval);
+ }
+
+ PG_RETURN_POINTER(entry);
+}
+
+typedef struct
+{
+ int4 *arrb;
+ int4 *arre;
+} CHKVAL;
+
+/*
+ * is there value 'val' in array or not ?
+ */
+static bool
+checkcondition_arr(void *checkval, QueryItem * val)
+{
+ int4 *StopLow = ((CHKVAL *) checkval)->arrb;
+ int4 *StopHigh = ((CHKVAL *) checkval)->arre;
+ int4 *StopMiddle;
+
+ /* Loop invariant: StopLow <= val < StopHigh */
+
+ while (StopLow < StopHigh)
+ {
+ StopMiddle = StopLow + (StopHigh - StopLow) / 2;
+ if (*StopMiddle == val->val)
+ return (true);
+ else if (*StopMiddle < val->val)
+ StopLow = StopMiddle + 1;
+ else
+ StopHigh = StopMiddle;
+ }
+
+ return (false);
+}
+
+static bool
+checkcondition_bit(void *checkval, QueryItem * val)
+{
+ return GETBIT(checkval, HASHVAL(val->val));
+}
+
+Datum
+gtsvector_consistent(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY(1);
+ SignTSVector *key = (SignTSVector *) DatumGetPointer(
+ ((GISTENTRY *) PG_GETARG_POINTER(0))->key
+ );
+
+ if (!query->size)
+ PG_RETURN_BOOL(false);
+
+ if (ISSIGNKEY(key))
+ {
+ if (ISALLTRUE(key))
+ PG_RETURN_BOOL(true);
+
+ PG_RETURN_BOOL(TS_execute(
+ GETQUERY(query),
+ (void *) GETSIGN(key), false,
+ checkcondition_bit
+ ));
+ }
+ else
+ { /* only leaf pages */
+ CHKVAL chkval;
+
+ chkval.arrb = GETARR(key);
+ chkval.arre = chkval.arrb + ARRNELEM(key);
+ PG_RETURN_BOOL(TS_execute(
+ GETQUERY(query),
+ (void *) &chkval, true,
+ checkcondition_arr
+ ));
+ }
+}
+
+static int4
+unionkey(BITVECP sbase, SignTSVector * add)
+{
+ int4 i;
+
+ if (ISSIGNKEY(add))
+ {
+ BITVECP sadd = GETSIGN(add);
+
+ if (ISALLTRUE(add))
+ return 1;
+
+ LOOPBYTE(
+ sbase[i] |= sadd[i];
+ );
+ }
+ else
+ {
+ int4 *ptr = GETARR(add);
+
+ for (i = 0; i < ARRNELEM(add); i++)
+ HASH(sbase, ptr[i]);
+ }
+ return 0;
+}
+
+
+Datum
+gtsvector_union(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ int *size = (int *) PG_GETARG_POINTER(1);
+ BITVEC base;
+ int4 i,
+ len;
+ int4 flag = 0;
+ SignTSVector *result;
+
+ MemSet((void *) base, 0, sizeof(BITVEC));
+ for (i = 0; i < entryvec->n; i++)
+ {
+ if (unionkey(base, GETENTRY(entryvec, i)))
+ {
+ flag = ALLISTRUE;
+ break;
+ }
+ }
+
+ flag |= SIGNKEY;
+ len = CALCGTSIZE(flag, 0);
+ result = (SignTSVector *) palloc(len);
+ *size = len;
+ SET_VARSIZE(result, len);
+ result->flag = flag;
+ if (!ISALLTRUE(result))
+ memcpy((void *) GETSIGN(result), (void *) base, sizeof(BITVEC));
+
+ PG_RETURN_POINTER(result);
+}
+
+Datum
+gtsvector_same(PG_FUNCTION_ARGS)
+{
+ SignTSVector *a = (SignTSVector *) PG_GETARG_POINTER(0);
+ SignTSVector *b = (SignTSVector *) PG_GETARG_POINTER(1);
+ bool *result = (bool *) PG_GETARG_POINTER(2);
+
+ if (ISSIGNKEY(a))
+ { /* then b also ISSIGNKEY */
+ if (ISALLTRUE(a) && ISALLTRUE(b))
+ *result = true;
+ else if (ISALLTRUE(a))
+ *result = false;
+ else if (ISALLTRUE(b))
+ *result = false;
+ else
+ {
+ int4 i;
+ BITVECP sa = GETSIGN(a),
+ sb = GETSIGN(b);
+
+ *result = true;
+ LOOPBYTE(
+ if (sa[i] != sb[i])
+ {
+ *result = false;
+ break;
+ }
+ );
+ }
+ }
+ else
+ { /* a and b ISARRKEY */
+ int4 lena = ARRNELEM(a),
+ lenb = ARRNELEM(b);
+
+ if (lena != lenb)
+ *result = false;
+ else
+ {
+ int4 *ptra = GETARR(a),
+ *ptrb = GETARR(b);
+ int4 i;
+
+ *result = true;
+ for (i = 0; i < lena; i++)
+ if (ptra[i] != ptrb[i])
+ {
+ *result = false;
+ break;
+ }
+ }
+ }
+
+ PG_RETURN_POINTER(result);
+}
+
+static int4
+sizebitvec(BITVECP sign)
+{
+ int4 size = 0,
+ i;
+
+ LOOPBYTE(
+ size += number_of_ones[(unsigned char) sign[i]];
+ );
+ return size;
+}
+
+static int
+hemdistsign(BITVECP a, BITVECP b)
+{
+ int i,
+ diff,
+ dist = 0;
+
+ LOOPBYTE(
+ diff = (unsigned char) (a[i] ^ b[i]);
+ dist += number_of_ones[diff];
+ );
+ return dist;
+}
+
+static int
+hemdist(SignTSVector * a, SignTSVector * b)
+{
+ if (ISALLTRUE(a))
+ {
+ if (ISALLTRUE(b))
+ return 0;
+ else
+ return SIGLENBIT - sizebitvec(GETSIGN(b));
+ }
+ else if (ISALLTRUE(b))
+ return SIGLENBIT - sizebitvec(GETSIGN(a));
+
+ return hemdistsign(GETSIGN(a), GETSIGN(b));
+}
+
+Datum
+gtsvector_penalty(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */
+ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
+ float *penalty = (float *) PG_GETARG_POINTER(2);
+ SignTSVector *origval = (SignTSVector *) DatumGetPointer(origentry->key);
+ SignTSVector *newval = (SignTSVector *) DatumGetPointer(newentry->key);
+ BITVECP orig = GETSIGN(origval);
+
+ *penalty = 0.0;
+
+ if (ISARRKEY(newval))
+ {
+ BITVEC sign;
+
+ makesign(sign, newval);
+
+ if (ISALLTRUE(origval))
+ *penalty = ((float) (SIGLENBIT - sizebitvec(sign))) / (float) (SIGLENBIT + 1);
+ else
+ *penalty = hemdistsign(sign, orig);
+ }
+ else
+ *penalty = hemdist(origval, newval);
+ PG_RETURN_POINTER(penalty);
+}
+
+typedef struct
+{
+ bool allistrue;
+ BITVEC sign;
+} CACHESIGN;
+
+static void
+fillcache(CACHESIGN * item, SignTSVector * key)
+{
+ item->allistrue = false;
+ if (ISARRKEY(key))
+ makesign(item->sign, key);
+ else if (ISALLTRUE(key))
+ item->allistrue = true;
+ else
+ memcpy((void *) item->sign, (void *) GETSIGN(key), sizeof(BITVEC));
+}
+
+#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
+typedef struct
+{
+ OffsetNumber pos;
+ int4 cost;
+} SPLITCOST;
+
+static int
+comparecost(const void *a, const void *b)
+{
+ if (((SPLITCOST *) a)->cost == ((SPLITCOST *) b)->cost)
+ return 0;
+ else
+ return (((SPLITCOST *) a)->cost > ((SPLITCOST *) b)->cost) ? 1 : -1;
+}
+
+
+static int
+hemdistcache(CACHESIGN * a, CACHESIGN * b)
+{
+ if (a->allistrue)
+ {
+ if (b->allistrue)
+ return 0;
+ else
+ return SIGLENBIT - sizebitvec(b->sign);
+ }
+ else if (b->allistrue)
+ return SIGLENBIT - sizebitvec(a->sign);
+
+ return hemdistsign(a->sign, b->sign);
+}
+
+Datum
+gtsvector_picksplit(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
+ OffsetNumber k,
+ j;
+ SignTSVector *datum_l,
+ *datum_r;
+ BITVECP union_l,
+ union_r;
+ int4 size_alpha,
+ size_beta;
+ int4 size_waste,
+ waste = -1;
+ int4 nbytes;
+ OffsetNumber seed_1 = 0,
+ seed_2 = 0;
+ OffsetNumber *left,
+ *right;
+ OffsetNumber maxoff;
+ BITVECP ptr;
+ int i;
+ CACHESIGN *cache;
+ SPLITCOST *costvector;
+
+ maxoff = entryvec->n - 2;
+ nbytes = (maxoff + 2) * sizeof(OffsetNumber);
+ v->spl_left = (OffsetNumber *) palloc(nbytes);
+ v->spl_right = (OffsetNumber *) palloc(nbytes);
+
+ cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2));
+ fillcache(&cache[FirstOffsetNumber], GETENTRY(entryvec, FirstOffsetNumber));
+
+ for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
+ {
+ for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
+ {
+ if (k == FirstOffsetNumber)
+ fillcache(&cache[j], GETENTRY(entryvec, j));
+
+ size_waste = hemdistcache(&(cache[j]), &(cache[k]));
+ if (size_waste > waste)
+ {
+ waste = size_waste;
+ seed_1 = k;
+ seed_2 = j;
+ }
+ }
+ }
+
+ left = v->spl_left;
+ v->spl_nleft = 0;
+ right = v->spl_right;
+ v->spl_nright = 0;
+
+ if (seed_1 == 0 || seed_2 == 0)
+ {
+ seed_1 = 1;
+ seed_2 = 2;
+ }
+
+ /* form initial .. */
+ if (cache[seed_1].allistrue)
+ {
+ datum_l = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
+ SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
+ datum_l->flag = SIGNKEY | ALLISTRUE;
+ }
+ else
+ {
+ datum_l = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY, 0));
+ SET_VARSIZE(datum_l, CALCGTSIZE(SIGNKEY, 0));
+ datum_l->flag = SIGNKEY;
+ memcpy((void *) GETSIGN(datum_l), (void *) cache[seed_1].sign, sizeof(BITVEC));
+ }
+ if (cache[seed_2].allistrue)
+ {
+ datum_r = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
+ SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY | ALLISTRUE, 0));
+ datum_r->flag = SIGNKEY | ALLISTRUE;
+ }
+ else
+ {
+ datum_r = (SignTSVector *) palloc(CALCGTSIZE(SIGNKEY, 0));
+ SET_VARSIZE(datum_r, CALCGTSIZE(SIGNKEY, 0));
+ datum_r->flag = SIGNKEY;
+ memcpy((void *) GETSIGN(datum_r), (void *) cache[seed_2].sign, sizeof(BITVEC));
+ }
+
+ union_l = GETSIGN(datum_l);
+ union_r = GETSIGN(datum_r);
+ maxoff = OffsetNumberNext(maxoff);
+ fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff));
+ /* sort before ... */
+ costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
+ for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
+ {
+ costvector[j - 1].pos = j;
+ size_alpha = hemdistcache(&(cache[seed_1]), &(cache[j]));
+ size_beta = hemdistcache(&(cache[seed_2]), &(cache[j]));
+ costvector[j - 1].cost = Abs(size_alpha - size_beta);
+ }
+ qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+
+ for (k = 0; k < maxoff; k++)
+ {
+ j = costvector[k].pos;
+ if (j == seed_1)
+ {
+ *left++ = j;
+ v->spl_nleft++;
+ continue;
+ }
+ else if (j == seed_2)
+ {
+ *right++ = j;
+ v->spl_nright++;
+ continue;
+ }
+
+ if (ISALLTRUE(datum_l) || cache[j].allistrue)
+ {
+ if (ISALLTRUE(datum_l) && cache[j].allistrue)
+ size_alpha = 0;
+ else
+ size_alpha = SIGLENBIT - sizebitvec(
+ (cache[j].allistrue) ? GETSIGN(datum_l) : GETSIGN(cache[j].sign)
+ );
+ }
+ else
+ size_alpha = hemdistsign(cache[j].sign, GETSIGN(datum_l));
+
+ if (ISALLTRUE(datum_r) || cache[j].allistrue)
+ {
+ if (ISALLTRUE(datum_r) && cache[j].allistrue)
+ size_beta = 0;
+ else
+ size_beta = SIGLENBIT - sizebitvec(
+ (cache[j].allistrue) ? GETSIGN(datum_r) : GETSIGN(cache[j].sign)
+ );
+ }
+ else
+ size_beta = hemdistsign(cache[j].sign, GETSIGN(datum_r));
+
+ if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
+ {
+ if (ISALLTRUE(datum_l) || cache[j].allistrue)
+ {
+ if (!ISALLTRUE(datum_l))
+ MemSet((void *) GETSIGN(datum_l), 0xff, sizeof(BITVEC));
+ }
+ else
+ {
+ ptr = cache[j].sign;
+ LOOPBYTE(
+ union_l[i] |= ptr[i];
+ );
+ }
+ *left++ = j;
+ v->spl_nleft++;
+ }
+ else
+ {
+ if (ISALLTRUE(datum_r) || cache[j].allistrue)
+ {
+ if (!ISALLTRUE(datum_r))
+ MemSet((void *) GETSIGN(datum_r), 0xff, sizeof(BITVEC));
+ }
+ else
+ {
+ ptr = cache[j].sign;
+ LOOPBYTE(
+ union_r[i] |= ptr[i];
+ );
+ }
+ *right++ = j;
+ v->spl_nright++;
+ }
+ }
+
+ *right = *left = FirstOffsetNumber;
+ v->spl_ldatum = PointerGetDatum(datum_l);
+ v->spl_rdatum = PointerGetDatum(datum_r);
+
+ PG_RETURN_POINTER(v);
+}
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
new file mode 100644
index 00000000000..1f8abb3298e
--- /dev/null
+++ b/src/backend/utils/adt/tsquery.c
@@ -0,0 +1,767 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsquery.c
+ * I/O functions for tsquery
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsquery.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "libpq/pqformat.h"
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+#include "utils/memutils.h"
+#include "utils/pg_crc.h"
+
+/* parser's states */
+#define WAITOPERAND 1
+#define WAITOPERATOR 2
+#define WAITFIRSTOPERAND 3
+#define WAITSINGLEOPERAND 4
+
+/*
+ * node of query tree, also used
+ * for storing polish notation in parser
+ */
+typedef struct ParseQueryNode
+{
+ int2 weight;
+ int2 type;
+ int4 val;
+ int2 distance;
+ int2 length;
+ struct ParseQueryNode *next;
+} ParseQueryNode;
+
+static char *
+get_weight(char *buf, int2 *weight)
+{
+ *weight = 0;
+
+ if (!t_iseq(buf, ':'))
+ return buf;
+
+ buf++;
+ while (*buf && pg_mblen(buf) == 1)
+ {
+ switch (*buf)
+ {
+ case 'a':
+ case 'A':
+ *weight |= 1 << 3;
+ break;
+ case 'b':
+ case 'B':
+ *weight |= 1 << 2;
+ break;
+ case 'c':
+ case 'C':
+ *weight |= 1 << 1;
+ break;
+ case 'd':
+ case 'D':
+ *weight |= 1;
+ break;
+ default:
+ return buf;
+ }
+ buf++;
+ }
+
+ return buf;
+}
+
+/*
+ * get token from query string
+ */
+static int4
+gettoken_query(TSQueryParserState * state, int4 *val, int4 *lenval, char **strval, int2 *weight)
+{
+ while (1)
+ {
+ switch (state->state)
+ {
+ case WAITFIRSTOPERAND:
+ case WAITOPERAND:
+ if (t_iseq(state->buf, '!'))
+ {
+ (state->buf)++; /* can safely ++, t_iseq guarantee
+ * that pg_mblen()==1 */
+ *val = (int4) '!';
+ state->state = WAITOPERAND;
+ return OPR;
+ }
+ else if (t_iseq(state->buf, '('))
+ {
+ state->count++;
+ (state->buf)++;
+ state->state = WAITOPERAND;
+ return OPEN;
+ }
+ else if (t_iseq(state->buf, ':'))
+ {
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error at start of operand in tsearch query: \"%s\"",
+ state->buffer)));
+ }
+ else if (!t_isspace(state->buf))
+ {
+ state->valstate.prsbuf = state->buf;
+ if (gettoken_tsvector(&(state->valstate)))
+ {
+ *strval = state->valstate.word;
+ *lenval = state->valstate.curpos - state->valstate.word;
+ state->buf = get_weight(state->valstate.prsbuf, weight);
+ state->state = WAITOPERATOR;
+ return VAL;
+ }
+ else if (state->state == WAITFIRSTOPERAND)
+ return END;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("no operand in tsearch query: \"%s\"",
+ state->buffer)));
+ }
+ break;
+ case WAITOPERATOR:
+ if (t_iseq(state->buf, '&') || t_iseq(state->buf, '|'))
+ {
+ state->state = WAITOPERAND;
+ *val = (int4) *(state->buf);
+ (state->buf)++;
+ return OPR;
+ }
+ else if (t_iseq(state->buf, ')'))
+ {
+ (state->buf)++;
+ state->count--;
+ return (state->count < 0) ? ERR : CLOSE;
+ }
+ else if (*(state->buf) == '\0')
+ return (state->count) ? ERR : END;
+ else if (!t_isspace(state->buf))
+ return ERR;
+ break;
+ case WAITSINGLEOPERAND:
+ if (*(state->buf) == '\0')
+ return END;
+ *strval = state->buf;
+ *lenval = strlen(state->buf);
+ state->buf += strlen(state->buf);
+ state->count++;
+ return VAL;
+ default:
+ return ERR;
+ break;
+ }
+ state->buf += pg_mblen(state->buf);
+ }
+ return END;
+}
+
+/*
+ * push new one in polish notation reverse view
+ */
+void
+pushquery(TSQueryParserState * state, int4 type, int4 val, int4 distance, int4 lenval, int2 weight)
+{
+ ParseQueryNode *tmp = (ParseQueryNode *) palloc(sizeof(ParseQueryNode));
+
+ tmp->weight = weight;
+ tmp->type = type;
+ tmp->val = val;
+ if (distance >= MAXSTRPOS)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("value is too big in tsearch query: \"%s\"",
+ state->buffer)));
+ if (lenval >= MAXSTRLEN)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("operand is too long in tsearch query: \"%s\"",
+ state->buffer)));
+ tmp->distance = distance;
+ tmp->length = lenval;
+ tmp->next = state->str;
+ state->str = tmp;
+ state->num++;
+}
+
+/*
+ * This function is used for tsquery parsing
+ */
+void
+pushval_asis(TSQueryParserState * state, int type, char *strval, int lenval, int2 weight)
+{
+ pg_crc32 c;
+
+ if (lenval >= MAXSTRLEN)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("word is too long in tsearch query: \"%s\"",
+ state->buffer)));
+
+ INIT_CRC32(c);
+ COMP_CRC32(c, strval, lenval);
+ FIN_CRC32(c);
+ pushquery(state, type, *(int4 *) &c,
+ state->curop - state->op, lenval, weight);
+
+ while (state->curop - state->op + lenval + 1 >= state->lenop)
+ {
+ int4 tmp = state->curop - state->op;
+
+ state->lenop *= 2;
+ state->op = (char *) repalloc((void *) state->op, state->lenop);
+ state->curop = state->op + tmp;
+ }
+ memcpy((void *) state->curop, (void *) strval, lenval);
+ state->curop += lenval;
+ *(state->curop) = '\0';
+ state->curop++;
+ state->sumlen += lenval + 1 /* \0 */ ;
+ return;
+}
+
+#define STACKDEPTH 32
+/*
+ * make polish notation of query
+ */
+static int4
+makepol(TSQueryParserState * state, void (*pushval) (TSQueryParserState *, int, char *, int, int2))
+{
+ int4 val = 0,
+ type;
+ int4 lenval = 0;
+ char *strval = NULL;
+ int4 stack[STACKDEPTH];
+ int4 lenstack = 0;
+ int2 weight = 0;
+
+ while ((type = gettoken_query(state, &val, &lenval, &strval, &weight)) != END)
+ {
+ switch (type)
+ {
+ case VAL:
+ pushval(state, VAL, strval, lenval, weight);
+ while (lenstack && (stack[lenstack - 1] == (int4) '&' ||
+ stack[lenstack - 1] == (int4) '!'))
+ {
+ lenstack--;
+ pushquery(state, OPR, stack[lenstack], 0, 0, 0);
+ }
+ break;
+ case OPR:
+ if (lenstack && val == (int4) '|')
+ pushquery(state, OPR, val, 0, 0, 0);
+ else
+ {
+ if (lenstack == STACKDEPTH) /* internal error */
+ elog(ERROR, "tsquery stack too small");
+ stack[lenstack] = val;
+ lenstack++;
+ }
+ break;
+ case OPEN:
+ if (makepol(state, pushval) == ERR)
+ return ERR;
+ if (lenstack && (stack[lenstack - 1] == (int4) '&' ||
+ stack[lenstack - 1] == (int4) '!'))
+ {
+ lenstack--;
+ pushquery(state, OPR, stack[lenstack], 0, 0, 0);
+ }
+ break;
+ case CLOSE:
+ while (lenstack)
+ {
+ lenstack--;
+ pushquery(state, OPR, stack[lenstack], 0, 0, 0);
+ };
+ return END;
+ break;
+ case ERR:
+ default:
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsearch query: \"%s\"",
+ state->buffer)));
+ return ERR;
+
+ }
+ }
+ while (lenstack)
+ {
+ lenstack--;
+ pushquery(state, OPR, stack[lenstack], 0, 0, 0);
+ };
+ return END;
+}
+
+static void
+findoprnd(QueryItem * ptr, int4 *pos)
+{
+ if (ptr[*pos].type == VAL || ptr[*pos].type == VALSTOP)
+ {
+ ptr[*pos].left = 0;
+ (*pos)++;
+ }
+ else if (ptr[*pos].val == (int4) '!')
+ {
+ ptr[*pos].left = 1;
+ (*pos)++;
+ findoprnd(ptr, pos);
+ }
+ else
+ {
+ QueryItem *curitem = &ptr[*pos];
+ int4 tmp = *pos;
+
+ (*pos)++;
+ findoprnd(ptr, pos);
+ curitem->left = *pos - tmp;
+ findoprnd(ptr, pos);
+ }
+}
+
+
+/*
+ * input
+ */
+TSQuery
+parse_tsquery(char *buf, void (*pushval) (TSQueryParserState *, int, char *, int, int2), Oid cfg_id, bool isplain)
+{
+ TSQueryParserState state;
+ int4 i;
+ TSQuery query;
+ int4 commonlen;
+ QueryItem *ptr;
+ ParseQueryNode *tmp;
+ int4 pos = 0;
+
+ /* init state */
+ state.buffer = buf;
+ state.buf = buf;
+ state.state = (isplain) ? WAITSINGLEOPERAND : WAITFIRSTOPERAND;
+ state.count = 0;
+ state.num = 0;
+ state.str = NULL;
+ state.cfg_id = cfg_id;
+
+ /* init value parser's state */
+ state.valstate.oprisdelim = true;
+ state.valstate.len = 32;
+ state.valstate.word = (char *) palloc(state.valstate.len);
+
+ /* init list of operand */
+ state.sumlen = 0;
+ state.lenop = 64;
+ state.curop = state.op = (char *) palloc(state.lenop);
+ *(state.curop) = '\0';
+
+ /* parse query & make polish notation (postfix, but in reverse order) */
+ makepol(&state, pushval);
+ pfree(state.valstate.word);
+ if (!state.num)
+ {
+ ereport(NOTICE,
+ (errmsg("tsearch query doesn't contain lexeme(s): \"%s\"",
+ state.buffer)));
+ query = (TSQuery) palloc(HDRSIZETQ);
+ SET_VARSIZE(query, HDRSIZETQ);
+ query->size = 0;
+ return query;
+ }
+
+ /* make finish struct */
+ commonlen = COMPUTESIZE(state.num, state.sumlen);
+ query = (TSQuery) palloc(commonlen);
+ SET_VARSIZE(query, commonlen);
+ query->size = state.num;
+ ptr = GETQUERY(query);
+
+ /* set item in polish notation */
+ for (i = 0; i < state.num; i++)
+ {
+ ptr[i].weight = state.str->weight;
+ ptr[i].type = state.str->type;
+ ptr[i].val = state.str->val;
+ ptr[i].distance = state.str->distance;
+ ptr[i].length = state.str->length;
+ tmp = state.str->next;
+ pfree(state.str);
+ state.str = tmp;
+ }
+
+ /* set user friendly-operand view */
+ memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen);
+ pfree(state.op);
+
+ /* set left operand's position for every operator */
+ pos = 0;
+ findoprnd(ptr, &pos);
+
+ return query;
+}
+
+/*
+ * in without morphology
+ */
+Datum
+tsqueryin(PG_FUNCTION_ARGS)
+{
+ char *in = PG_GETARG_CSTRING(0);
+
+ pg_verifymbstr(in, strlen(in), false);
+
+ PG_RETURN_TSQUERY(parse_tsquery(in, pushval_asis, InvalidOid, false));
+}
+
+/*
+ * out function
+ */
+typedef struct
+{
+ QueryItem *curpol;
+ char *buf;
+ char *cur;
+ char *op;
+ int4 buflen;
+} INFIX;
+
+#define RESIZEBUF(inf,addsize) \
+while( ( (inf)->cur - (inf)->buf ) + (addsize) + 1 >= (inf)->buflen ) \
+{ \
+ int4 len = (inf)->cur - (inf)->buf; \
+ (inf)->buflen *= 2; \
+ (inf)->buf = (char*) repalloc( (void*)(inf)->buf, (inf)->buflen ); \
+ (inf)->cur = (inf)->buf + len; \
+}
+
+/*
+ * recursive walk on tree and print it in
+ * infix (human-readable) view
+ */
+static void
+infix(INFIX * in, bool first)
+{
+ if (in->curpol->type == VAL)
+ {
+ char *op = in->op + in->curpol->distance;
+ int clen;
+
+ RESIZEBUF(in, in->curpol->length * (pg_database_encoding_max_length() + 1) + 2 + 5);
+ *(in->cur) = '\'';
+ in->cur++;
+ while (*op)
+ {
+ if (t_iseq(op, '\''))
+ {
+ *(in->cur) = '\'';
+ in->cur++;
+ }
+ COPYCHAR(in->cur, op);
+
+ clen = pg_mblen(op);
+ op += clen;
+ in->cur += clen;
+ }
+ *(in->cur) = '\'';
+ in->cur++;
+ if (in->curpol->weight)
+ {
+ *(in->cur) = ':';
+ in->cur++;
+ if (in->curpol->weight & (1 << 3))
+ {
+ *(in->cur) = 'A';
+ in->cur++;
+ }
+ if (in->curpol->weight & (1 << 2))
+ {
+ *(in->cur) = 'B';
+ in->cur++;
+ }
+ if (in->curpol->weight & (1 << 1))
+ {
+ *(in->cur) = 'C';
+ in->cur++;
+ }
+ if (in->curpol->weight & 1)
+ {
+ *(in->cur) = 'D';
+ in->cur++;
+ }
+ }
+ *(in->cur) = '\0';
+ in->curpol++;
+ }
+ else if (in->curpol->val == (int4) '!')
+ {
+ bool isopr = false;
+
+ RESIZEBUF(in, 1);
+ *(in->cur) = '!';
+ in->cur++;
+ *(in->cur) = '\0';
+ in->curpol++;
+ if (in->curpol->type == OPR)
+ {
+ isopr = true;
+ RESIZEBUF(in, 2);
+ sprintf(in->cur, "( ");
+ in->cur = strchr(in->cur, '\0');
+ }
+ infix(in, isopr);
+ if (isopr)
+ {
+ RESIZEBUF(in, 2);
+ sprintf(in->cur, " )");
+ in->cur = strchr(in->cur, '\0');
+ }
+ }
+ else
+ {
+ int4 op = in->curpol->val;
+ INFIX nrm;
+
+ in->curpol++;
+ if (op == (int4) '|' && !first)
+ {
+ RESIZEBUF(in, 2);
+ sprintf(in->cur, "( ");
+ in->cur = strchr(in->cur, '\0');
+ }
+
+ nrm.curpol = in->curpol;
+ nrm.op = in->op;
+ nrm.buflen = 16;
+ nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
+
+ /* get right operand */
+ infix(&nrm, false);
+
+ /* get & print left operand */
+ in->curpol = nrm.curpol;
+ infix(in, false);
+
+ /* print operator & right operand */
+ RESIZEBUF(in, 3 + (nrm.cur - nrm.buf));
+ sprintf(in->cur, " %c %s", op, nrm.buf);
+ in->cur = strchr(in->cur, '\0');
+ pfree(nrm.buf);
+
+ if (op == (int4) '|' && !first)
+ {
+ RESIZEBUF(in, 2);
+ sprintf(in->cur, " )");
+ in->cur = strchr(in->cur, '\0');
+ }
+ }
+}
+
+
+Datum
+tsqueryout(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY(0);
+ INFIX nrm;
+
+ if (query->size == 0)
+ {
+ char *b = palloc(1);
+
+ *b = '\0';
+ PG_RETURN_POINTER(b);
+ }
+ nrm.curpol = GETQUERY(query);
+ nrm.buflen = 32;
+ nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
+ *(nrm.cur) = '\0';
+ nrm.op = GETOPERAND(query);
+ infix(&nrm, true);
+
+ PG_FREE_IF_COPY(query, 0);
+ PG_RETURN_CSTRING(nrm.buf);
+}
+
+Datum
+tsquerysend(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY(0);
+ StringInfoData buf;
+ int i;
+ QueryItem *item = GETQUERY(query);
+
+ pq_begintypsend(&buf);
+
+ pq_sendint(&buf, query->size, sizeof(int32));
+ for (i = 0; i < query->size; i++)
+ {
+ int tmp;
+
+ pq_sendint(&buf, item->type, sizeof(item->type));
+ pq_sendint(&buf, item->weight, sizeof(item->weight));
+ pq_sendint(&buf, item->left, sizeof(item->left));
+ pq_sendint(&buf, item->val, sizeof(item->val));
+
+ /*
+ * We are sure that sizeof(WordEntry) == sizeof(int32), and about
+ * layout of QueryItem
+ */
+ tmp = *(int32 *) (((char *) item) + HDRSIZEQI);
+ pq_sendint(&buf, tmp, sizeof(tmp));
+
+ item++;
+ }
+
+ item = GETQUERY(query);
+ for (i = 0; i < query->size; i++)
+ {
+ if (item->type == VAL)
+ pq_sendbytes(&buf, GETOPERAND(query) + item->distance, item->length);
+ item++;
+ }
+
+ PG_FREE_IF_COPY(query, 0);
+
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
+Datum
+tsqueryrecv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ TSQuery query;
+ int i,
+ size,
+ tmp,
+ len = HDRSIZETQ;
+ QueryItem *item;
+ int datalen = 0;
+ char *ptr;
+
+ size = pq_getmsgint(buf, sizeof(uint32));
+ if (size < 0 || size > (MaxAllocSize / sizeof(QueryItem)))
+ elog(ERROR, "invalid size of tsquery");
+ len += sizeof(QueryItem) * size;
+
+ query = (TSQuery) palloc(len);
+ query->size = size;
+ item = GETQUERY(query);
+
+ for (i = 0; i < size; i++)
+ {
+ item->type = (int8) pq_getmsgint(buf, sizeof(int8));
+ item->weight = (int8) pq_getmsgint(buf, sizeof(int8));
+ item->left = (int16) pq_getmsgint(buf, sizeof(int16));
+ item->val = (int32) pq_getmsgint(buf, sizeof(int32));
+ tmp = pq_getmsgint(buf, sizeof(int32));
+ memcpy((((char *) item) + HDRSIZEQI), &tmp, sizeof(int32));
+
+ /*
+ * Sanity checks
+ */
+ if (item->type == VAL)
+ {
+ datalen += item->length + 1; /* \0 */
+ }
+ else if (item->type == OPR)
+ {
+ if (item->val == '|' || item->val == '&')
+ {
+ if (item->left <= 0 || i + item->left >= size)
+ elog(ERROR, "invalid pointer to left operand");
+ }
+
+ if (i == size - 1)
+ elog(ERROR, "invalid pointer to right operand");
+ }
+ else
+ elog(ERROR, "unknown tsquery node type");
+
+ item++;
+ }
+
+ query = (TSQuery) repalloc(query, len + datalen);
+
+ item = GETQUERY(query);
+ ptr = GETOPERAND(query);
+ for (i = 0; i < size; i++)
+ {
+ if (item->type == VAL)
+ {
+ item->distance = ptr - GETOPERAND(query);
+ memcpy(ptr,
+ pq_getmsgbytes(buf, item->length),
+ item->length);
+ ptr += item->length;
+ *ptr++ = '\0';
+ }
+ item++;
+ }
+
+ Assert(ptr - GETOPERAND(query) == datalen);
+
+ SET_VARSIZE(query, len + datalen);
+
+ PG_RETURN_TSVECTOR(query);
+}
+
+/*
+ * debug function, used only for view query
+ * which will be executed in non-leaf pages in index
+ */
+Datum
+tsquerytree(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY(0);
+ INFIX nrm;
+ text *res;
+ QueryItem *q;
+ int4 len;
+
+ if (query->size == 0)
+ {
+ res = (text *) palloc(VARHDRSZ);
+ SET_VARSIZE(res, VARHDRSZ);
+ PG_RETURN_POINTER(res);
+ }
+
+ q = clean_NOT(GETQUERY(query), &len);
+
+ if (!q)
+ {
+ res = (text *) palloc(1 + VARHDRSZ);
+ SET_VARSIZE(res, 1 + VARHDRSZ);
+ *((char *) VARDATA(res)) = 'T';
+ }
+ else
+ {
+ nrm.curpol = q;
+ nrm.buflen = 32;
+ nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
+ *(nrm.cur) = '\0';
+ nrm.op = GETOPERAND(query);
+ infix(&nrm, true);
+
+ res = (text *) palloc(nrm.cur - nrm.buf + VARHDRSZ);
+ SET_VARSIZE(res, nrm.cur - nrm.buf + VARHDRSZ);
+ strncpy(VARDATA(res), nrm.buf, nrm.cur - nrm.buf);
+ pfree(q);
+ }
+
+ PG_FREE_IF_COPY(query, 0);
+
+ PG_RETURN_POINTER(res);
+}
diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c
new file mode 100644
index 00000000000..7991a4ad198
--- /dev/null
+++ b/src/backend/utils/adt/tsquery_cleanup.c
@@ -0,0 +1,261 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsquery_cleanup.c
+ * Cleanup query from NOT values and/or stopword
+ * Utility functions to correct work.
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_cleanup.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+
+typedef struct NODE
+{
+ struct NODE *left;
+ struct NODE *right;
+ QueryItem *valnode;
+} NODE;
+
+/*
+ * make query tree from plain view of query
+ */
+static NODE *
+maketree(QueryItem * in)
+{
+ NODE *node = (NODE *) palloc(sizeof(NODE));
+
+ node->valnode = in;
+ node->right = node->left = NULL;
+ if (in->type == OPR)
+ {
+ node->right = maketree(in + 1);
+ if (in->val != (int4) '!')
+ node->left = maketree(in + in->left);
+ }
+ return node;
+}
+
+typedef struct
+{
+ QueryItem *ptr;
+ int4 len;
+ int4 cur;
+} PLAINTREE;
+
+static void
+plainnode(PLAINTREE * state, NODE * node)
+{
+ if (state->cur == state->len)
+ {
+ state->len *= 2;
+ state->ptr = (QueryItem *) repalloc((void *) state->ptr, state->len * sizeof(QueryItem));
+ }
+ memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(QueryItem));
+ if (node->valnode->type == VAL)
+ state->cur++;
+ else if (node->valnode->val == (int4) '!')
+ {
+ state->ptr[state->cur].left = 1;
+ state->cur++;
+ plainnode(state, node->right);
+ }
+ else
+ {
+ int4 cur = state->cur;
+
+ state->cur++;
+ plainnode(state, node->right);
+ state->ptr[cur].left = state->cur - cur;
+ plainnode(state, node->left);
+ }
+ pfree(node);
+}
+
+/*
+ * make plain view of tree from 'normal' view of tree
+ */
+static QueryItem *
+plaintree(NODE * root, int4 *len)
+{
+ PLAINTREE pl;
+
+ pl.cur = 0;
+ pl.len = 16;
+ if (root && (root->valnode->type == VAL || root->valnode->type == OPR))
+ {
+ pl.ptr = (QueryItem *) palloc(pl.len * sizeof(QueryItem));
+ plainnode(&pl, root);
+ }
+ else
+ pl.ptr = NULL;
+ *len = pl.cur;
+ return pl.ptr;
+}
+
+static void
+freetree(NODE * node)
+{
+ if (!node)
+ return;
+ if (node->left)
+ freetree(node->left);
+ if (node->right)
+ freetree(node->right);
+ pfree(node);
+}
+
+/*
+ * clean tree for ! operator.
+ * It's usefull for debug, but in
+ * other case, such view is used with search in index.
+ * Operator ! always return TRUE
+ */
+static NODE *
+clean_NOT_intree(NODE * node)
+{
+ if (node->valnode->type == VAL)
+ return node;
+
+ if (node->valnode->val == (int4) '!')
+ {
+ freetree(node);
+ return NULL;
+ }
+
+ /* operator & or | */
+ if (node->valnode->val == (int4) '|')
+ {
+ if ((node->left = clean_NOT_intree(node->left)) == NULL ||
+ (node->right = clean_NOT_intree(node->right)) == NULL)
+ {
+ freetree(node);
+ return NULL;
+ }
+ }
+ else
+ {
+ NODE *res = node;
+
+ node->left = clean_NOT_intree(node->left);
+ node->right = clean_NOT_intree(node->right);
+ if (node->left == NULL && node->right == NULL)
+ {
+ pfree(node);
+ res = NULL;
+ }
+ else if (node->left == NULL)
+ {
+ res = node->right;
+ pfree(node);
+ }
+ else if (node->right == NULL)
+ {
+ res = node->left;
+ pfree(node);
+ }
+ return res;
+ }
+ return node;
+}
+
+QueryItem *
+clean_NOT(QueryItem * ptr, int4 *len)
+{
+ NODE *root = maketree(ptr);
+
+ return plaintree(clean_NOT_intree(root), len);
+}
+
+
+#ifdef V_UNKNOWN /* exists in Windows headers */
+#undef V_UNKNOWN
+#endif
+
+#define V_UNKNOWN 0
+#define V_TRUE 1
+#define V_FALSE 2
+#define V_STOP 3
+
+/*
+ * Clean query tree from values which is always in
+ * text (stopword)
+ */
+static NODE *
+clean_fakeval_intree(NODE * node, char *result)
+{
+ char lresult = V_UNKNOWN,
+ rresult = V_UNKNOWN;
+
+ if (node->valnode->type == VAL)
+ return node;
+ else if (node->valnode->type == VALSTOP)
+ {
+ pfree(node);
+ *result = V_STOP;
+ return NULL;
+ }
+
+
+ if (node->valnode->val == (int4) '!')
+ {
+ node->right = clean_fakeval_intree(node->right, &rresult);
+ if (!node->right)
+ {
+ *result = V_STOP;
+ freetree(node);
+ return NULL;
+ }
+ }
+ else
+ {
+ NODE *res = node;
+
+ node->left = clean_fakeval_intree(node->left, &lresult);
+ node->right = clean_fakeval_intree(node->right, &rresult);
+ if (lresult == V_STOP && rresult == V_STOP)
+ {
+ freetree(node);
+ *result = V_STOP;
+ return NULL;
+ }
+ else if (lresult == V_STOP)
+ {
+ res = node->right;
+ pfree(node);
+ }
+ else if (rresult == V_STOP)
+ {
+ res = node->left;
+ pfree(node);
+ }
+ return res;
+ }
+ return node;
+}
+
+QueryItem *
+clean_fakeval(QueryItem * ptr, int4 *len)
+{
+ NODE *root = maketree(ptr);
+ char result = V_UNKNOWN;
+ NODE *resroot;
+
+ resroot = clean_fakeval_intree(root, &result);
+ if (result != V_UNKNOWN)
+ {
+ elog(NOTICE, "query contains only stopword(s) or doesn't contain lexeme(s), ignored");
+ *len = 0;
+ return NULL;
+ }
+
+ return plaintree(resroot, len);
+}
diff --git a/src/backend/utils/adt/tsquery_gist.c b/src/backend/utils/adt/tsquery_gist.c
new file mode 100644
index 00000000000..0deca10075c
--- /dev/null
+++ b/src/backend/utils/adt/tsquery_gist.c
@@ -0,0 +1,259 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsquery_gist.c
+ * GiST index support for tsquery
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_gist.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "access/skey.h"
+#include "access/gist.h"
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+
+#define GETENTRY(vec,pos) ((TSQuerySign *) DatumGetPointer((vec)->vector[(pos)].key))
+
+Datum
+gtsquery_compress(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *retval = entry;
+
+ if (entry->leafkey)
+ {
+ TSQuerySign *sign = (TSQuerySign *) palloc(sizeof(TSQuerySign));
+
+ retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
+ *sign = makeTSQuerySign(DatumGetTSQuery(entry->key));
+
+ gistentryinit(*retval, PointerGetDatum(sign),
+ entry->rel, entry->page,
+ entry->offset, FALSE);
+ }
+
+ PG_RETURN_POINTER(retval);
+}
+
+Datum
+gtsquery_decompress(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(PG_GETARG_DATUM(0));
+}
+
+Datum
+gtsquery_consistent(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ TSQuerySign *key = (TSQuerySign *) DatumGetPointer(entry->key);
+ TSQuery query = PG_GETARG_TSQUERY(1);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+ TSQuerySign sq = makeTSQuerySign(query);
+ bool retval;
+
+ switch (strategy)
+ {
+ case RTContainsStrategyNumber:
+ if (GIST_LEAF(entry))
+ retval = (*key & sq) == sq;
+ else
+ retval = (*key & sq) != 0;
+ break;
+ case RTContainedByStrategyNumber:
+ if (GIST_LEAF(entry))
+ retval = (*key & sq) == *key;
+ else
+ retval = (*key & sq) != 0;
+ break;
+ default:
+ retval = FALSE;
+ }
+ PG_RETURN_BOOL(retval);
+}
+
+Datum
+gtsquery_union(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ int *size = (int *) PG_GETARG_POINTER(1);
+ TSQuerySign *sign = (TSQuerySign *) palloc(sizeof(TSQuerySign));
+ int i;
+
+ memset(sign, 0, sizeof(TSQuerySign));
+
+ for (i = 0; i < entryvec->n; i++)
+ *sign |= *GETENTRY(entryvec, i);
+
+ *size = sizeof(TSQuerySign);
+
+ PG_RETURN_POINTER(sign);
+}
+
+Datum
+gtsquery_same(PG_FUNCTION_ARGS)
+{
+ TSQuerySign *a = (TSQuerySign *) PG_GETARG_POINTER(0);
+ TSQuerySign *b = (TSQuerySign *) PG_GETARG_POINTER(1);
+
+ PG_RETURN_POINTER(*a == *b);
+}
+
+static int
+sizebitvec(TSQuerySign sign)
+{
+ int size = 0,
+ i;
+
+ for (i = 0; i < TSQS_SIGLEN; i++)
+ size += 0x01 & (sign >> i);
+
+ return size;
+}
+
+static int
+hemdist(TSQuerySign a, TSQuerySign b)
+{
+ TSQuerySign res = a ^ b;
+
+ return sizebitvec(res);
+}
+
+Datum
+gtsquery_penalty(PG_FUNCTION_ARGS)
+{
+ TSQuerySign *origval = (TSQuerySign *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
+ TSQuerySign *newval = (TSQuerySign *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
+ float *penalty = (float *) PG_GETARG_POINTER(2);
+
+ *penalty = hemdist(*origval, *newval);
+
+ PG_RETURN_POINTER(penalty);
+}
+
+
+typedef struct
+{
+ OffsetNumber pos;
+ int4 cost;
+} SPLITCOST;
+
+static int
+comparecost(const void *a, const void *b)
+{
+ if (((SPLITCOST *) a)->cost == ((SPLITCOST *) b)->cost)
+ return 0;
+ else
+ return (((SPLITCOST *) a)->cost > ((SPLITCOST *) b)->cost) ? 1 : -1;
+}
+
+#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
+
+Datum
+gtsquery_picksplit(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
+ OffsetNumber maxoff = entryvec->n - 2;
+ OffsetNumber k,
+ j;
+
+ TSQuerySign *datum_l,
+ *datum_r;
+ int4 size_alpha,
+ size_beta;
+ int4 size_waste,
+ waste = -1;
+ int4 nbytes;
+ OffsetNumber seed_1 = 0,
+ seed_2 = 0;
+ OffsetNumber *left,
+ *right;
+
+ SPLITCOST *costvector;
+
+ nbytes = (maxoff + 2) * sizeof(OffsetNumber);
+ left = v->spl_left = (OffsetNumber *) palloc(nbytes);
+ right = v->spl_right = (OffsetNumber *) palloc(nbytes);
+ v->spl_nleft = v->spl_nright = 0;
+
+ for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k))
+ for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j))
+ {
+ size_waste = hemdist(*GETENTRY(entryvec, j), *GETENTRY(entryvec, k));
+ if (size_waste > waste)
+ {
+ waste = size_waste;
+ seed_1 = k;
+ seed_2 = j;
+ }
+ }
+
+
+ if (seed_1 == 0 || seed_2 == 0)
+ {
+ seed_1 = 1;
+ seed_2 = 2;
+ }
+
+ datum_l = (TSQuerySign *) palloc(sizeof(TSQuerySign));
+ *datum_l = *GETENTRY(entryvec, seed_1);
+ datum_r = (TSQuerySign *) palloc(sizeof(TSQuerySign));
+ *datum_r = *GETENTRY(entryvec, seed_2);
+
+
+ maxoff = OffsetNumberNext(maxoff);
+ costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff);
+ for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j))
+ {
+ costvector[j - 1].pos = j;
+ size_alpha = hemdist(*GETENTRY(entryvec, seed_1), *GETENTRY(entryvec, j));
+ size_beta = hemdist(*GETENTRY(entryvec, seed_2), *GETENTRY(entryvec, j));
+ costvector[j - 1].cost = abs(size_alpha - size_beta);
+ }
+ qsort((void *) costvector, maxoff, sizeof(SPLITCOST), comparecost);
+
+ for (k = 0; k < maxoff; k++)
+ {
+ j = costvector[k].pos;
+ if (j == seed_1)
+ {
+ *left++ = j;
+ v->spl_nleft++;
+ continue;
+ }
+ else if (j == seed_2)
+ {
+ *right++ = j;
+ v->spl_nright++;
+ continue;
+ }
+ size_alpha = hemdist(*datum_l, *GETENTRY(entryvec, j));
+ size_beta = hemdist(*datum_r, *GETENTRY(entryvec, j));
+
+ if (size_alpha < size_beta + WISH_F(v->spl_nleft, v->spl_nright, 0.05))
+ {
+ *datum_l |= *GETENTRY(entryvec, j);
+ *left++ = j;
+ v->spl_nleft++;
+ }
+ else
+ {
+ *datum_r |= *GETENTRY(entryvec, j);
+ *right++ = j;
+ v->spl_nright++;
+ }
+ }
+
+ *right = *left = FirstOffsetNumber;
+ v->spl_ldatum = PointerGetDatum(datum_l);
+ v->spl_rdatum = PointerGetDatum(datum_r);
+
+ PG_RETURN_POINTER(v);
+}
diff --git a/src/backend/utils/adt/tsquery_op.c b/src/backend/utils/adt/tsquery_op.c
new file mode 100644
index 00000000000..fd97c2796df
--- /dev/null
+++ b/src/backend/utils/adt/tsquery_op.c
@@ -0,0 +1,289 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsquery_op.c
+ * Various operations with tsquery
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_op.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_utils.h"
+#include "utils/pg_crc.h"
+
+Datum
+tsquery_numnode(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY(0);
+ int nnode = query->size;
+
+ PG_FREE_IF_COPY(query, 0);
+ PG_RETURN_INT32(nnode);
+}
+
+static QTNode *
+join_tsqueries(TSQuery a, TSQuery b)
+{
+ QTNode *res = (QTNode *) palloc0(sizeof(QTNode));
+
+ res->flags |= QTN_NEEDFREE;
+
+ res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
+ res->valnode->type = OPR;
+
+ res->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
+ res->child[0] = QT2QTN(GETQUERY(b), GETOPERAND(b));
+ res->child[1] = QT2QTN(GETQUERY(a), GETOPERAND(a));
+ res->nchild = 2;
+
+ return res;
+}
+
+Datum
+tsquery_and(PG_FUNCTION_ARGS)
+{
+ TSQuery a = PG_GETARG_TSQUERY_COPY(0);
+ TSQuery b = PG_GETARG_TSQUERY_COPY(1);
+ QTNode *res;
+ TSQuery query;
+
+ if (a->size == 0)
+ {
+ PG_FREE_IF_COPY(a, 1);
+ PG_RETURN_POINTER(b);
+ }
+ else if (b->size == 0)
+ {
+ PG_FREE_IF_COPY(b, 1);
+ PG_RETURN_POINTER(a);
+ }
+
+ res = join_tsqueries(a, b);
+
+ res->valnode->val = '&';
+
+ query = QTN2QT(res);
+
+ QTNFree(res);
+ PG_FREE_IF_COPY(a, 0);
+ PG_FREE_IF_COPY(b, 1);
+
+ PG_RETURN_TSQUERY(query);
+}
+
+Datum
+tsquery_or(PG_FUNCTION_ARGS)
+{
+ TSQuery a = PG_GETARG_TSQUERY_COPY(0);
+ TSQuery b = PG_GETARG_TSQUERY_COPY(1);
+ QTNode *res;
+ TSQuery query;
+
+ if (a->size == 0)
+ {
+ PG_FREE_IF_COPY(a, 1);
+ PG_RETURN_POINTER(b);
+ }
+ else if (b->size == 0)
+ {
+ PG_FREE_IF_COPY(b, 1);
+ PG_RETURN_POINTER(a);
+ }
+
+ res = join_tsqueries(a, b);
+
+ res->valnode->val = '|';
+
+ query = QTN2QT(res);
+
+ QTNFree(res);
+ PG_FREE_IF_COPY(a, 0);
+ PG_FREE_IF_COPY(b, 1);
+
+ PG_RETURN_POINTER(query);
+}
+
+Datum
+tsquery_not(PG_FUNCTION_ARGS)
+{
+ TSQuery a = PG_GETARG_TSQUERY_COPY(0);
+ QTNode *res;
+ TSQuery query;
+
+ if (a->size == 0)
+ PG_RETURN_POINTER(a);
+
+ res = (QTNode *) palloc0(sizeof(QTNode));
+
+ res->flags |= QTN_NEEDFREE;
+
+ res->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
+ res->valnode->type = OPR;
+ res->valnode->val = '!';
+
+ res->child = (QTNode **) palloc0(sizeof(QTNode *));
+ res->child[0] = QT2QTN(GETQUERY(a), GETOPERAND(a));
+ res->nchild = 1;
+
+ query = QTN2QT(res);
+
+ QTNFree(res);
+ PG_FREE_IF_COPY(a, 0);
+
+ PG_RETURN_POINTER(query);
+}
+
+static int
+CompareTSQ(TSQuery a, TSQuery b)
+{
+ if (a->size != b->size)
+ {
+ return (a->size < b->size) ? -1 : 1;
+ }
+ else if (VARSIZE(a) != VARSIZE(b))
+ {
+ return (VARSIZE(a) < VARSIZE(b)) ? -1 : 1;
+ }
+ else
+ {
+ QTNode *an = QT2QTN(GETQUERY(a), GETOPERAND(a));
+ QTNode *bn = QT2QTN(GETQUERY(b), GETOPERAND(b));
+ int res = QTNodeCompare(an, bn);
+
+ QTNFree(an);
+ QTNFree(bn);
+
+ return res;
+ }
+
+ return 0;
+}
+
+Datum
+tsquery_cmp(PG_FUNCTION_ARGS)
+{
+ TSQuery a = PG_GETARG_TSQUERY_COPY(0);
+ TSQuery b = PG_GETARG_TSQUERY_COPY(1);
+ int res = CompareTSQ(a, b);
+
+ PG_FREE_IF_COPY(a, 0);
+ PG_FREE_IF_COPY(b, 1);
+
+ PG_RETURN_INT32(res);
+}
+
+#define CMPFUNC( NAME, CONDITION ) \
+Datum \
+NAME(PG_FUNCTION_ARGS) { \
+ TSQuery a = PG_GETARG_TSQUERY_COPY(0); \
+ TSQuery b = PG_GETARG_TSQUERY_COPY(1); \
+ int res = CompareTSQ(a,b); \
+ \
+ PG_FREE_IF_COPY(a,0); \
+ PG_FREE_IF_COPY(b,1); \
+ \
+ PG_RETURN_BOOL( CONDITION ); \
+}
+
+CMPFUNC(tsquery_lt, res < 0);
+CMPFUNC(tsquery_le, res <= 0);
+CMPFUNC(tsquery_eq, res == 0);
+CMPFUNC(tsquery_ge, res >= 0);
+CMPFUNC(tsquery_gt, res > 0);
+CMPFUNC(tsquery_ne, res != 0);
+
+TSQuerySign
+makeTSQuerySign(TSQuery a)
+{
+ int i;
+ QueryItem *ptr = GETQUERY(a);
+ TSQuerySign sign = 0;
+
+ for (i = 0; i < a->size; i++)
+ {
+ if (ptr->type == VAL)
+ sign |= ((TSQuerySign) 1) << (ptr->val % TSQS_SIGLEN);
+ ptr++;
+ }
+
+ return sign;
+}
+
+Datum
+tsq_mcontains(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY(0);
+ TSQuery ex = PG_GETARG_TSQUERY(1);
+ TSQuerySign sq,
+ se;
+ int i,
+ j;
+ QueryItem *iq,
+ *ie;
+
+ if (query->size < ex->size)
+ {
+ PG_FREE_IF_COPY(query, 0);
+ PG_FREE_IF_COPY(ex, 1);
+
+ PG_RETURN_BOOL(false);
+ }
+
+ sq = makeTSQuerySign(query);
+ se = makeTSQuerySign(ex);
+
+ if ((sq & se) != se)
+ {
+ PG_FREE_IF_COPY(query, 0);
+ PG_FREE_IF_COPY(ex, 1);
+
+ PG_RETURN_BOOL(false);
+ }
+
+ ie = GETQUERY(ex);
+
+ for (i = 0; i < ex->size; i++)
+ {
+ iq = GETQUERY(query);
+ if (ie[i].type != VAL)
+ continue;
+ for (j = 0; j < query->size; j++)
+ if (iq[j].type == VAL && ie[i].val == iq[j].val)
+ {
+ j = query->size + 1;
+ break;
+ }
+ if (j == query->size)
+ {
+ PG_FREE_IF_COPY(query, 0);
+ PG_FREE_IF_COPY(ex, 1);
+
+ PG_RETURN_BOOL(false);
+ }
+ }
+
+ PG_FREE_IF_COPY(query, 0);
+ PG_FREE_IF_COPY(ex, 1);
+
+ PG_RETURN_BOOL(true);
+}
+
+Datum
+tsq_mcontained(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(
+ DirectFunctionCall2(
+ tsq_mcontains,
+ PG_GETARG_DATUM(1),
+ PG_GETARG_DATUM(0)
+ )
+ );
+}
diff --git a/src/backend/utils/adt/tsquery_rewrite.c b/src/backend/utils/adt/tsquery_rewrite.c
new file mode 100644
index 00000000000..f0d22c644ae
--- /dev/null
+++ b/src/backend/utils/adt/tsquery_rewrite.c
@@ -0,0 +1,524 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsquery_rewrite.c
+ * Utilities for reconstructing tsquery
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_rewrite.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "executor/spi.h"
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+
+
+static int
+addone(int *counters, int last, int total)
+{
+ counters[last]++;
+ if (counters[last] >= total)
+ {
+ if (last == 0)
+ return 0;
+ if (addone(counters, last - 1, total - 1) == 0)
+ return 0;
+ counters[last] = counters[last - 1] + 1;
+ }
+ return 1;
+}
+
+static QTNode *
+findeq(QTNode *node, QTNode *ex, QTNode *subs, bool *isfind)
+{
+
+ if ((node->sign & ex->sign) != ex->sign || node->valnode->type != ex->valnode->type || node->valnode->val != ex->valnode->val)
+ return node;
+
+ if (node->flags & QTN_NOCHANGE)
+ return node;
+
+ if (node->valnode->type == OPR)
+ {
+ if (node->nchild == ex->nchild)
+ {
+ if (QTNEq(node, ex))
+ {
+ QTNFree(node);
+ if (subs)
+ {
+ node = QTNCopy(subs);
+ node->flags |= QTN_NOCHANGE;
+ }
+ else
+ node = NULL;
+ *isfind = true;
+ }
+ }
+ else if (node->nchild > ex->nchild)
+ {
+ int *counters = (int *) palloc(sizeof(int) * node->nchild);
+ int i;
+ QTNode *tnode = (QTNode *) palloc(sizeof(QTNode));
+
+ memset(tnode, 0, sizeof(QTNode));
+ tnode->child = (QTNode **) palloc(sizeof(QTNode *) * ex->nchild);
+ tnode->nchild = ex->nchild;
+ tnode->valnode = (QueryItem *) palloc(sizeof(QueryItem));
+ *(tnode->valnode) = *(ex->valnode);
+
+ for (i = 0; i < ex->nchild; i++)
+ counters[i] = i;
+
+ do
+ {
+ tnode->sign = 0;
+ for (i = 0; i < ex->nchild; i++)
+ {
+ tnode->child[i] = node->child[counters[i]];
+ tnode->sign |= tnode->child[i]->sign;
+ }
+
+ if (QTNEq(tnode, ex))
+ {
+ int j = 0;
+
+ pfree(tnode->valnode);
+ pfree(tnode->child);
+ pfree(tnode);
+ if (subs)
+ {
+ tnode = QTNCopy(subs);
+ tnode->flags = QTN_NOCHANGE | QTN_NEEDFREE;
+ }
+ else
+ tnode = NULL;
+
+ node->child[counters[0]] = tnode;
+
+ for (i = 1; i < ex->nchild; i++)
+ node->child[counters[i]] = NULL;
+ for (i = 0; i < node->nchild; i++)
+ {
+ if (node->child[i])
+ {
+ node->child[j] = node->child[i];
+ j++;
+ }
+ }
+
+ node->nchild = j;
+
+ *isfind = true;
+
+ break;
+ }
+ } while (addone(counters, ex->nchild - 1, node->nchild));
+ if (tnode && (tnode->flags & QTN_NOCHANGE) == 0)
+ {
+ pfree(tnode->valnode);
+ pfree(tnode->child);
+ pfree(tnode);
+ }
+ else
+ QTNSort(node);
+ pfree(counters);
+ }
+ }
+ else if (QTNEq(node, ex))
+ {
+ QTNFree(node);
+ if (subs)
+ {
+ node = QTNCopy(subs);
+ node->flags |= QTN_NOCHANGE;
+ }
+ else
+ {
+ node = NULL;
+ }
+ *isfind = true;
+ }
+
+ return node;
+}
+
+static QTNode *
+dofindsubquery(QTNode *root, QTNode *ex, QTNode *subs, bool *isfind)
+{
+ root = findeq(root, ex, subs, isfind);
+
+ if (root && (root->flags & QTN_NOCHANGE) == 0 && root->valnode->type == OPR)
+ {
+ int i;
+
+ for (i = 0; i < root->nchild; i++)
+ root->child[i] = dofindsubquery(root->child[i], ex, subs, isfind);
+ }
+
+ return root;
+}
+
+static QTNode *
+dropvoidsubtree(QTNode * root)
+{
+
+ if (!root)
+ return NULL;
+
+ if (root->valnode->type == OPR)
+ {
+ int i,
+ j = 0;
+
+ for (i = 0; i < root->nchild; i++)
+ {
+ if (root->child[i])
+ {
+ root->child[j] = root->child[i];
+ j++;
+ }
+ }
+
+ root->nchild = j;
+
+ if (root->valnode->val == (int4) '!' && root->nchild == 0)
+ {
+ QTNFree(root);
+ root = NULL;
+ }
+ else if (root->nchild == 1)
+ {
+ QTNode *nroot = root->child[0];
+
+ pfree(root);
+ root = nroot;
+ }
+ }
+
+ return root;
+}
+
+static QTNode *
+findsubquery(QTNode *root, QTNode *ex, QTNode *subs, bool *isfind)
+{
+ bool DidFind = false;
+
+ root = dofindsubquery(root, ex, subs, &DidFind);
+
+ if (!subs && DidFind)
+ root = dropvoidsubtree(root);
+
+ if (isfind)
+ *isfind = DidFind;
+
+ return root;
+}
+
+Datum
+ts_rewrite_accum(PG_FUNCTION_ARGS)
+{
+ TSQuery acc;
+ ArrayType *qa;
+ TSQuery q;
+ QTNode *qex = NULL,
+ *subs = NULL,
+ *acctree = NULL;
+ bool isfind = false;
+ Datum *elemsp;
+ int nelemsp;
+ MemoryContext aggcontext;
+ MemoryContext oldcontext;
+
+ aggcontext = ((AggState *) fcinfo->context)->aggcontext;
+
+ if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
+ {
+ acc = (TSQuery) MemoryContextAlloc(aggcontext, HDRSIZETQ);
+ SET_VARSIZE(acc, HDRSIZETQ);
+ acc->size = 0;
+ }
+ else
+ acc = PG_GETARG_TSQUERY(0);
+
+ if (PG_ARGISNULL(1) || PG_GETARG_POINTER(1) == NULL)
+ PG_RETURN_TSQUERY(acc);
+ else
+ qa = PG_GETARG_ARRAYTYPE_P_COPY(1);
+
+ if (ARR_NDIM(qa) != 1)
+ elog(ERROR, "array must be one-dimensional, not %d dimensions",
+ ARR_NDIM(qa));
+ if (ArrayGetNItems(ARR_NDIM(qa), ARR_DIMS(qa)) != 3)
+ elog(ERROR, "array should have only three elements");
+ if (ARR_ELEMTYPE(qa) != TSQUERYOID)
+ elog(ERROR, "array should contain tsquery type");
+
+ deconstruct_array(qa, TSQUERYOID, -1, false, 'i', &elemsp, NULL, &nelemsp);
+
+ q = DatumGetTSQuery(elemsp[0]);
+ if (q->size == 0)
+ {
+ pfree(elemsp);
+ PG_RETURN_POINTER(acc);
+ }
+
+ if (!acc->size)
+ {
+ if (VARSIZE(acc) > HDRSIZETQ)
+ {
+ pfree(elemsp);
+ PG_RETURN_POINTER(acc);
+ }
+ else
+ acctree = QT2QTN(GETQUERY(q), GETOPERAND(q));
+ }
+ else
+ acctree = QT2QTN(GETQUERY(acc), GETOPERAND(acc));
+
+ QTNTernary(acctree);
+ QTNSort(acctree);
+
+ q = DatumGetTSQuery(elemsp[1]);
+ if (q->size == 0)
+ {
+ pfree(elemsp);
+ PG_RETURN_POINTER(acc);
+ }
+ qex = QT2QTN(GETQUERY(q), GETOPERAND(q));
+ QTNTernary(qex);
+ QTNSort(qex);
+
+ q = DatumGetTSQuery(elemsp[2]);
+ if (q->size)
+ subs = QT2QTN(GETQUERY(q), GETOPERAND(q));
+
+ acctree = findsubquery(acctree, qex, subs, &isfind);
+
+ if (isfind || !acc->size)
+ {
+ /* pfree( acc ); do not pfree(p), because nodeAgg.c will */
+ if (acctree)
+ {
+ QTNBinary(acctree);
+ oldcontext = MemoryContextSwitchTo(aggcontext);
+ acc = QTN2QT(acctree);
+ MemoryContextSwitchTo(oldcontext);
+ }
+ else
+ {
+ acc = (TSQuery) MemoryContextAlloc(aggcontext, HDRSIZETQ);
+ SET_VARSIZE(acc, HDRSIZETQ);
+ acc->size = 0;
+ }
+ }
+
+ pfree(elemsp);
+ QTNFree(qex);
+ QTNFree(subs);
+ QTNFree(acctree);
+
+ PG_RETURN_TSQUERY(acc);
+}
+
+Datum
+ts_rewrite_finish(PG_FUNCTION_ARGS)
+{
+ TSQuery acc = PG_GETARG_TSQUERY(0);
+ TSQuery rewrited;
+
+ if (acc == NULL || PG_ARGISNULL(0) || acc->size == 0)
+ {
+ rewrited = (TSQuery) palloc(HDRSIZETQ);
+ SET_VARSIZE(rewrited, HDRSIZETQ);
+ rewrited->size = 0;
+ }
+ else
+ {
+ rewrited = (TSQuery) palloc(VARSIZE(acc));
+ memcpy(rewrited, acc, VARSIZE(acc));
+ pfree(acc);
+ }
+
+ PG_RETURN_POINTER(rewrited);
+}
+
+Datum
+tsquery_rewrite(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY_COPY(0);
+ text *in = PG_GETARG_TEXT_P(1);
+ TSQuery rewrited = query;
+ MemoryContext outercontext = CurrentMemoryContext;
+ MemoryContext oldcontext;
+ QTNode *tree;
+ char *buf;
+ void *plan;
+ Portal portal;
+ bool isnull;
+ int i;
+
+ if (query->size == 0)
+ {
+ PG_FREE_IF_COPY(in, 1);
+ PG_RETURN_POINTER(rewrited);
+ }
+
+ tree = QT2QTN(GETQUERY(query), GETOPERAND(query));
+ QTNTernary(tree);
+ QTNSort(tree);
+
+ buf = TextPGetCString(in);
+
+ SPI_connect();
+
+ if ((plan = SPI_prepare(buf, 0, NULL)) == NULL)
+ elog(ERROR, "SPI_prepare(\"%s\") failed", buf);
+
+ if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, false)) == NULL)
+ elog(ERROR, "SPI_cursor_open(\"%s\") failed", buf);
+
+ SPI_cursor_fetch(portal, true, 100);
+
+ if (SPI_tuptable->tupdesc->natts != 2 ||
+ SPI_gettypeid(SPI_tuptable->tupdesc, 1) != TSQUERYOID ||
+ SPI_gettypeid(SPI_tuptable->tupdesc, 2) != TSQUERYOID)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("ts_rewrite query must return two tsquery columns")));
+
+ while (SPI_processed > 0 && tree)
+ {
+ for (i = 0; i < SPI_processed && tree; i++)
+ {
+ Datum qdata = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1, &isnull);
+ Datum sdata;
+
+ if (isnull)
+ continue;
+
+ sdata = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 2, &isnull);
+
+ if (!isnull)
+ {
+ TSQuery qtex = DatumGetTSQuery(qdata);
+ TSQuery qtsubs = DatumGetTSQuery(sdata);
+ QTNode *qex,
+ *qsubs = NULL;
+
+ if (qtex->size == 0)
+ {
+ if (qtex != (TSQuery) DatumGetPointer(qdata))
+ pfree(qtex);
+ if (qtsubs != (TSQuery) DatumGetPointer(sdata))
+ pfree(qtsubs);
+ continue;
+ }
+
+ qex = QT2QTN(GETQUERY(qtex), GETOPERAND(qtex));
+
+ QTNTernary(qex);
+ QTNSort(qex);
+
+ if (qtsubs->size)
+ qsubs = QT2QTN(GETQUERY(qtsubs), GETOPERAND(qtsubs));
+
+ oldcontext = MemoryContextSwitchTo(outercontext);
+ tree = findsubquery(tree, qex, qsubs, NULL);
+ MemoryContextSwitchTo(oldcontext);
+
+ QTNFree(qex);
+ if (qtex != (TSQuery) DatumGetPointer(qdata))
+ pfree(qtex);
+ QTNFree(qsubs);
+ if (qtsubs != (TSQuery) DatumGetPointer(sdata))
+ pfree(qtsubs);
+ }
+ }
+
+ SPI_freetuptable(SPI_tuptable);
+ SPI_cursor_fetch(portal, true, 100);
+ }
+
+ SPI_freetuptable(SPI_tuptable);
+ SPI_cursor_close(portal);
+ SPI_freeplan(plan);
+ SPI_finish();
+
+ if (tree)
+ {
+ QTNBinary(tree);
+ rewrited = QTN2QT(tree);
+ QTNFree(tree);
+ PG_FREE_IF_COPY(query, 0);
+ }
+ else
+ {
+ SET_VARSIZE(rewrited, HDRSIZETQ);
+ rewrited->size = 0;
+ }
+
+ pfree(buf);
+ PG_FREE_IF_COPY(in, 1);
+ PG_RETURN_POINTER(rewrited);
+}
+
+Datum
+tsquery_rewrite_query(PG_FUNCTION_ARGS)
+{
+ TSQuery query = PG_GETARG_TSQUERY_COPY(0);
+ TSQuery ex = PG_GETARG_TSQUERY(1);
+ TSQuery subst = PG_GETARG_TSQUERY(2);
+ TSQuery rewrited = query;
+ QTNode *tree,
+ *qex,
+ *subs = NULL;
+
+ if (query->size == 0 || ex->size == 0)
+ {
+ PG_FREE_IF_COPY(ex, 1);
+ PG_FREE_IF_COPY(subst, 2);
+ PG_RETURN_POINTER(rewrited);
+ }
+
+ tree = QT2QTN(GETQUERY(query), GETOPERAND(query));
+ QTNTernary(tree);
+ QTNSort(tree);
+
+ qex = QT2QTN(GETQUERY(ex), GETOPERAND(ex));
+ QTNTernary(qex);
+ QTNSort(qex);
+
+ if (subst->size)
+ subs = QT2QTN(GETQUERY(subst), GETOPERAND(subst));
+
+ tree = findsubquery(tree, qex, subs, NULL);
+ QTNFree(qex);
+ QTNFree(subs);
+
+ if (!tree)
+ {
+ SET_VARSIZE(rewrited, HDRSIZETQ);
+ rewrited->size = 0;
+ PG_FREE_IF_COPY(ex, 1);
+ PG_FREE_IF_COPY(subst, 2);
+ PG_RETURN_POINTER(rewrited);
+ }
+ else
+ {
+ QTNBinary(tree);
+ rewrited = QTN2QT(tree);
+ QTNFree(tree);
+ }
+
+ PG_FREE_IF_COPY(query, 0);
+ PG_FREE_IF_COPY(ex, 1);
+ PG_FREE_IF_COPY(subst, 2);
+ PG_RETURN_POINTER(rewrited);
+}
diff --git a/src/backend/utils/adt/tsquery_util.c b/src/backend/utils/adt/tsquery_util.c
new file mode 100644
index 00000000000..ae8cc318da9
--- /dev/null
+++ b/src/backend/utils/adt/tsquery_util.c
@@ -0,0 +1,317 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsquery_util.c
+ * Utilities for tsquery datatype
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsquery_util.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+
+
+QTNode *
+QT2QTN(QueryItem * in, char *operand)
+{
+ QTNode *node = (QTNode *) palloc0(sizeof(QTNode));
+
+ node->valnode = in;
+
+ if (in->type == OPR)
+ {
+ node->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
+ node->child[0] = QT2QTN(in + 1, operand);
+ node->sign = node->child[0]->sign;
+ if (in->val == (int4) '!')
+ node->nchild = 1;
+ else
+ {
+ node->nchild = 2;
+ node->child[1] = QT2QTN(in + in->left, operand);
+ node->sign |= node->child[1]->sign;
+ }
+ }
+ else if (operand)
+ {
+ node->word = operand + in->distance;
+ node->sign = 1 << (in->val % 32);
+ }
+
+ return node;
+}
+
+void
+QTNFree(QTNode * in)
+{
+ if (!in)
+ return;
+
+ if (in->valnode->type == VAL && in->word && (in->flags & QTN_WORDFREE) != 0)
+ pfree(in->word);
+
+ if (in->child)
+ {
+ if (in->valnode)
+ {
+ if (in->valnode->type == OPR && in->nchild > 0)
+ {
+ int i;
+
+ for (i = 0; i < in->nchild; i++)
+ QTNFree(in->child[i]);
+ }
+ if (in->flags & QTN_NEEDFREE)
+ pfree(in->valnode);
+ }
+ pfree(in->child);
+ }
+
+ pfree(in);
+}
+
+int
+QTNodeCompare(QTNode * an, QTNode * bn)
+{
+ if (an->valnode->type != bn->valnode->type)
+ return (an->valnode->type > bn->valnode->type) ? -1 : 1;
+ else if (an->valnode->val != bn->valnode->val)
+ return (an->valnode->val > bn->valnode->val) ? -1 : 1;
+ else if (an->valnode->type == VAL)
+ {
+ if (an->valnode->length == bn->valnode->length)
+ return strncmp(an->word, bn->word, an->valnode->length);
+ else
+ return (an->valnode->length > bn->valnode->length) ? -1 : 1;
+ }
+ else if (an->nchild != bn->nchild)
+ {
+ return (an->nchild > bn->nchild) ? -1 : 1;
+ }
+ else
+ {
+ int i,
+ res;
+
+ for (i = 0; i < an->nchild; i++)
+ if ((res = QTNodeCompare(an->child[i], bn->child[i])) != 0)
+ return res;
+ }
+
+ return 0;
+}
+
+static int
+cmpQTN(const void *a, const void *b)
+{
+ return QTNodeCompare(*(QTNode **) a, *(QTNode **) b);
+}
+
+void
+QTNSort(QTNode * in)
+{
+ int i;
+
+ if (in->valnode->type != OPR)
+ return;
+
+ for (i = 0; i < in->nchild; i++)
+ QTNSort(in->child[i]);
+ if (in->nchild > 1)
+ qsort((void *) in->child, in->nchild, sizeof(QTNode *), cmpQTN);
+}
+
+bool
+QTNEq(QTNode * a, QTNode * b)
+{
+ uint32 sign = a->sign & b->sign;
+
+ if (!(sign == a->sign && sign == b->sign))
+ return 0;
+
+ return (QTNodeCompare(a, b) == 0) ? true : false;
+}
+
+void
+QTNTernary(QTNode * in)
+{
+ int i;
+
+ if (in->valnode->type != OPR)
+ return;
+
+ for (i = 0; i < in->nchild; i++)
+ QTNTernary(in->child[i]);
+
+ for (i = 0; i < in->nchild; i++)
+ {
+ if (in->valnode->type == in->child[i]->valnode->type && in->valnode->val == in->child[i]->valnode->val)
+ {
+ QTNode *cc = in->child[i];
+ int oldnchild = in->nchild;
+
+ in->nchild += cc->nchild - 1;
+ in->child = (QTNode **) repalloc(in->child, in->nchild * sizeof(QTNode *));
+
+ if (i + 1 != oldnchild)
+ memmove(in->child + i + cc->nchild, in->child + i + 1,
+ (oldnchild - i - 1) * sizeof(QTNode *));
+
+ memcpy(in->child + i, cc->child, cc->nchild * sizeof(QTNode *));
+ i += cc->nchild - 1;
+
+ pfree(cc);
+ }
+ }
+}
+
+void
+QTNBinary(QTNode * in)
+{
+ int i;
+
+ if (in->valnode->type != OPR)
+ return;
+
+ for (i = 0; i < in->nchild; i++)
+ QTNBinary(in->child[i]);
+
+ if (in->nchild <= 2)
+ return;
+
+ while (in->nchild > 2)
+ {
+ QTNode *nn = (QTNode *) palloc0(sizeof(QTNode));
+
+ nn->valnode = (QueryItem *) palloc0(sizeof(QueryItem));
+ nn->child = (QTNode **) palloc0(sizeof(QTNode *) * 2);
+
+ nn->nchild = 2;
+ nn->flags = QTN_NEEDFREE;
+
+ nn->child[0] = in->child[0];
+ nn->child[1] = in->child[1];
+ nn->sign = nn->child[0]->sign | nn->child[1]->sign;
+
+ nn->valnode->type = in->valnode->type;
+ nn->valnode->val = in->valnode->val;
+
+ in->child[0] = nn;
+ in->child[1] = in->child[in->nchild - 1];
+ in->nchild--;
+ }
+}
+
+static void
+cntsize(QTNode * in, int4 *sumlen, int4 *nnode)
+{
+ *nnode += 1;
+ if (in->valnode->type == OPR)
+ {
+ int i;
+
+ for (i = 0; i < in->nchild; i++)
+ cntsize(in->child[i], sumlen, nnode);
+ }
+ else
+ {
+ *sumlen += in->valnode->length + 1;
+ }
+}
+
+typedef struct
+{
+ QueryItem *curitem;
+ char *operand;
+ char *curoperand;
+} QTN2QTState;
+
+static void
+fillQT(QTN2QTState * state, QTNode * in)
+{
+ *(state->curitem) = *(in->valnode);
+
+ if (in->valnode->type == VAL)
+ {
+ memcpy(state->curoperand, in->word, in->valnode->length);
+ state->curitem->distance = state->curoperand - state->operand;
+ state->curoperand[in->valnode->length] = '\0';
+ state->curoperand += in->valnode->length + 1;
+ state->curitem++;
+ }
+ else
+ {
+ QueryItem *curitem = state->curitem;
+
+ Assert(in->nchild <= 2);
+ state->curitem++;
+
+ fillQT(state, in->child[0]);
+
+ if (in->nchild == 2)
+ {
+ curitem->left = state->curitem - curitem;
+ fillQT(state, in->child[1]);
+ }
+ }
+}
+
+TSQuery
+QTN2QT(QTNode *in)
+{
+ TSQuery out;
+ int len;
+ int sumlen = 0,
+ nnode = 0;
+ QTN2QTState state;
+
+ cntsize(in, &sumlen, &nnode);
+ len = COMPUTESIZE(nnode, sumlen);
+
+ out = (TSQuery) palloc(len);
+ SET_VARSIZE(out, len);
+ out->size = nnode;
+
+ state.curitem = GETQUERY(out);
+ state.operand = state.curoperand = GETOPERAND(out);
+
+ fillQT(&state, in);
+ return out;
+}
+
+QTNode *
+QTNCopy(QTNode *in)
+{
+ QTNode *out = (QTNode *) palloc(sizeof(QTNode));
+
+ *out = *in;
+ out->valnode = (QueryItem *) palloc(sizeof(QueryItem));
+ *(out->valnode) = *(in->valnode);
+ out->flags |= QTN_NEEDFREE;
+
+ if (in->valnode->type == VAL)
+ {
+ out->word = palloc(in->valnode->length + 1);
+ memcpy(out->word, in->word, in->valnode->length);
+ out->word[in->valnode->length] = '\0';
+ out->flags |= QTN_WORDFREE;
+ }
+ else
+ {
+ int i;
+
+ out->child = (QTNode **) palloc(sizeof(QTNode *) * in->nchild);
+
+ for (i = 0; i < in->nchild; i++)
+ out->child[i] = QTNCopy(in->child[i]);
+ }
+
+ return out;
+}
diff --git a/src/backend/utils/adt/tsrank.c b/src/backend/utils/adt/tsrank.c
new file mode 100644
index 00000000000..8b2ab884c8c
--- /dev/null
+++ b/src/backend/utils/adt/tsrank.c
@@ -0,0 +1,804 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsrank.c
+ * rank tsvector by tsquery
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsrank.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include <math.h>
+
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+#include "utils/array.h"
+
+
+static float weights[] = {0.1, 0.2, 0.4, 1.0};
+
+#define wpos(wep) ( w[ WEP_GETWEIGHT(wep) ] )
+
+#define RANK_NO_NORM 0x00
+#define RANK_NORM_LOGLENGTH 0x01
+#define RANK_NORM_LENGTH 0x02
+#define RANK_NORM_EXTDIST 0x04
+#define RANK_NORM_UNIQ 0x08
+#define RANK_NORM_LOGUNIQ 0x10
+#define DEF_NORM_METHOD RANK_NO_NORM
+
+static float calc_rank_or(float *w, TSVector t, TSQuery q);
+static float calc_rank_and(float *w, TSVector t, TSQuery q);
+
+/*
+ * Returns a weight of a word collocation
+ */
+static float4
+word_distance(int4 w)
+{
+ if (w > 100)
+ return 1e-30;
+
+ return 1.0 / (1.005 + 0.05 * exp(((float4) w) / 1.5 - 2));
+}
+
+static int
+cnt_length(TSVector t)
+{
+ WordEntry *ptr = ARRPTR(t),
+ *end = (WordEntry *) STRPTR(t);
+ int len = 0,
+ clen;
+
+ while (ptr < end)
+ {
+ if ((clen = POSDATALEN(t, ptr)) == 0)
+ len += 1;
+ else
+ len += clen;
+ ptr++;
+ }
+
+ return len;
+}
+
+static int4
+WordECompareQueryItem(char *eval, char *qval, WordEntry * ptr, QueryItem * item)
+{
+ if (ptr->len == item->length)
+ return strncmp(
+ eval + ptr->pos,
+ qval + item->distance,
+ item->length);
+
+ return (ptr->len > item->length) ? 1 : -1;
+}
+
+static WordEntry *
+find_wordentry(TSVector t, TSQuery q, QueryItem * item)
+{
+ WordEntry *StopLow = ARRPTR(t);
+ WordEntry *StopHigh = (WordEntry *) STRPTR(t);
+ WordEntry *StopMiddle;
+ int difference;
+
+ /* Loop invariant: StopLow <= item < StopHigh */
+
+ while (StopLow < StopHigh)
+ {
+ StopMiddle = StopLow + (StopHigh - StopLow) / 2;
+ difference = WordECompareQueryItem(STRPTR(t), GETOPERAND(q), StopMiddle, item);
+ if (difference == 0)
+ return StopMiddle;
+ else if (difference < 0)
+ StopLow = StopMiddle + 1;
+ else
+ StopHigh = StopMiddle;
+ }
+
+ return NULL;
+}
+
+
+static int
+compareQueryItem(const void *a, const void *b, void *arg)
+{
+ char *operand = (char *) arg;
+
+ if ((*(QueryItem **) a)->length == (*(QueryItem **) b)->length)
+ return strncmp(operand + (*(QueryItem **) a)->distance,
+ operand + (*(QueryItem **) b)->distance,
+ (*(QueryItem **) b)->length);
+
+ return ((*(QueryItem **) a)->length > (*(QueryItem **) b)->length) ? 1 : -1;
+}
+
+static QueryItem **
+SortAndUniqItems(char *operand, QueryItem * item, int *size)
+{
+ QueryItem **res,
+ **ptr,
+ **prevptr;
+
+ ptr = res = (QueryItem **) palloc(sizeof(QueryItem *) * *size);
+
+ while ((*size)--)
+ {
+ if (item->type == VAL)
+ {
+ *ptr = item;
+ ptr++;
+ }
+ item++;
+ }
+
+ *size = ptr - res;
+ if (*size < 2)
+ return res;
+
+ qsort_arg(res, *size, sizeof(QueryItem **), compareQueryItem, (void *) operand);
+
+ ptr = res + 1;
+ prevptr = res;
+
+ while (ptr - res < *size)
+ {
+ if (compareQueryItem((void *) ptr, (void *) prevptr, (void *) operand) != 0)
+ {
+ prevptr++;
+ *prevptr = *ptr;
+ }
+ ptr++;
+ }
+
+ *size = prevptr + 1 - res;
+ return res;
+}
+
+static WordEntryPos POSNULL[] = {
+ 0,
+ 0
+};
+
+static float
+calc_rank_and(float *w, TSVector t, TSQuery q)
+{
+ uint16 **pos;
+ int i,
+ k,
+ l,
+ p;
+ WordEntry *entry;
+ WordEntryPos *post,
+ *ct;
+ int4 dimt,
+ lenct,
+ dist;
+ float res = -1.0;
+ QueryItem **item;
+ int size = q->size;
+
+ item = SortAndUniqItems(GETOPERAND(q), GETQUERY(q), &size);
+ if (size < 2)
+ {
+ pfree(item);
+ return calc_rank_or(w, t, q);
+ }
+ pos = (uint16 **) palloc(sizeof(uint16 *) * q->size);
+ memset(pos, 0, sizeof(uint16 *) * q->size);
+ *(uint16 *) POSNULL = lengthof(POSNULL) - 1;
+ WEP_SETPOS(POSNULL[1], MAXENTRYPOS - 1);
+
+ for (i = 0; i < size; i++)
+ {
+ entry = find_wordentry(t, q, item[i]);
+ if (!entry)
+ continue;
+
+ if (entry->haspos)
+ pos[i] = (uint16 *) _POSDATAPTR(t, entry);
+ else
+ pos[i] = (uint16 *) POSNULL;
+
+
+ dimt = *(uint16 *) (pos[i]);
+ post = (WordEntryPos *) (pos[i] + 1);
+ for (k = 0; k < i; k++)
+ {
+ if (!pos[k])
+ continue;
+ lenct = *(uint16 *) (pos[k]);
+ ct = (WordEntryPos *) (pos[k] + 1);
+ for (l = 0; l < dimt; l++)
+ {
+ for (p = 0; p < lenct; p++)
+ {
+ dist = Abs((int) WEP_GETPOS(post[l]) - (int) WEP_GETPOS(ct[p]));
+ if (dist || (dist == 0 && (pos[i] == (uint16 *) POSNULL || pos[k] == (uint16 *) POSNULL)))
+ {
+ float curw;
+
+ if (!dist)
+ dist = MAXENTRYPOS;
+ curw = sqrt(wpos(post[l]) * wpos(ct[p]) * word_distance(dist));
+ res = (res < 0) ? curw : 1.0 - (1.0 - res) * (1.0 - curw);
+ }
+ }
+ }
+ }
+ }
+ pfree(pos);
+ pfree(item);
+ return res;
+}
+
+static float
+calc_rank_or(float *w, TSVector t, TSQuery q)
+{
+ WordEntry *entry;
+ WordEntryPos *post;
+ int4 dimt,
+ j,
+ i;
+ float res = 0.0;
+ QueryItem **item;
+ int size = q->size;
+
+ *(uint16 *) POSNULL = lengthof(POSNULL) - 1;
+ item = SortAndUniqItems(GETOPERAND(q), GETQUERY(q), &size);
+
+ for (i = 0; i < size; i++)
+ {
+ float resj,
+ wjm;
+ int4 jm;
+
+ entry = find_wordentry(t, q, item[i]);
+ if (!entry)
+ continue;
+
+ if (entry->haspos)
+ {
+ dimt = POSDATALEN(t, entry);
+ post = POSDATAPTR(t, entry);
+ }
+ else
+ {
+ dimt = *(uint16 *) POSNULL;
+ post = POSNULL + 1;
+ }
+
+ resj = 0.0;
+ wjm = -1.0;
+ jm = 0;
+ for (j = 0; j < dimt; j++)
+ {
+ resj = resj + wpos(post[j]) / ((j + 1) * (j + 1));
+ if (wpos(post[j]) > wjm)
+ {
+ wjm = wpos(post[j]);
+ jm = j;
+ }
+ }
+/*
+ limit (sum(i/i^2),i->inf) = pi^2/6
+ resj = sum(wi/i^2),i=1,noccurence,
+ wi - should be sorted desc,
+ don't sort for now, just choose maximum weight. This should be corrected
+ Oleg Bartunov
+*/
+ res = res + (wjm + resj - wjm / ((jm + 1) * (jm + 1))) / 1.64493406685;
+ }
+ if (size > 0)
+ res = res / size;
+ pfree(item);
+ return res;
+}
+
+static float
+calc_rank(float *w, TSVector t, TSQuery q, int4 method)
+{
+ QueryItem *item = GETQUERY(q);
+ float res = 0.0;
+ int len;
+
+ if (!t->size || !q->size)
+ return 0.0;
+
+ res = (item->type != VAL && item->val == (int4) '&') ?
+ calc_rank_and(w, t, q) : calc_rank_or(w, t, q);
+
+ if (res < 0)
+ res = 1e-20;
+
+ if ((method & RANK_NORM_LOGLENGTH) && t->size > 0)
+ res /= log((double) (cnt_length(t) + 1)) / log(2.0);
+
+ if (method & RANK_NORM_LENGTH)
+ {
+ len = cnt_length(t);
+ if (len > 0)
+ res /= (float) len;
+ }
+
+ if ((method & RANK_NORM_UNIQ) && t->size > 0)
+ res /= (float) (t->size);
+
+ if ((method & RANK_NORM_LOGUNIQ) && t->size > 0)
+ res /= log((double) (t->size + 1)) / log(2.0);
+
+ return res;
+}
+
+static float *
+getWeights(ArrayType *win)
+{
+ static float ws[lengthof(weights)];
+ int i;
+ float4 *arrdata;
+
+ if (win == 0)
+ return weights;
+
+ if (ARR_NDIM(win) != 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+ errmsg("array of weight must be one-dimensional")));
+
+ if (ArrayGetNItems(ARR_NDIM(win), ARR_DIMS(win)) < lengthof(weights))
+ ereport(ERROR,
+ (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+ errmsg("array of weight is too short")));
+
+ if (ARR_HASNULL(win))
+ ereport(ERROR,
+ (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
+ errmsg("array of weight must not contain nulls")));
+
+ arrdata = (float4 *) ARR_DATA_PTR(win);
+ for (i = 0; i < lengthof(weights); i++)
+ {
+ ws[i] = (arrdata[i] >= 0) ? arrdata[i] : weights[i];
+ if (ws[i] > 1.0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("weight out of range")));
+ }
+
+ return ws;
+}
+
+Datum
+ts_rank_wttf(PG_FUNCTION_ARGS)
+{
+ ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ TSVector txt = PG_GETARG_TSVECTOR(1);
+ TSQuery query = PG_GETARG_TSQUERY(2);
+ int method = PG_GETARG_INT32(3);
+ float res;
+
+ res = calc_rank(getWeights(win), txt, query, method);
+
+ PG_FREE_IF_COPY(win, 0);
+ PG_FREE_IF_COPY(txt, 1);
+ PG_FREE_IF_COPY(query, 2);
+ PG_RETURN_FLOAT4(res);
+}
+
+Datum
+ts_rank_wtt(PG_FUNCTION_ARGS)
+{
+ ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ TSVector txt = PG_GETARG_TSVECTOR(1);
+ TSQuery query = PG_GETARG_TSQUERY(2);
+ float res;
+
+ res = calc_rank(getWeights(win), txt, query, DEF_NORM_METHOD);
+
+ PG_FREE_IF_COPY(win, 0);
+ PG_FREE_IF_COPY(txt, 1);
+ PG_FREE_IF_COPY(query, 2);
+ PG_RETURN_FLOAT4(res);
+}
+
+Datum
+ts_rank_ttf(PG_FUNCTION_ARGS)
+{
+ TSVector txt = PG_GETARG_TSVECTOR(0);
+ TSQuery query = PG_GETARG_TSQUERY(1);
+ int method = PG_GETARG_INT32(2);
+ float res;
+
+ res = calc_rank(getWeights(NULL), txt, query, method);
+
+ PG_FREE_IF_COPY(txt, 0);
+ PG_FREE_IF_COPY(query, 1);
+ PG_RETURN_FLOAT4(res);
+}
+
+Datum
+ts_rank_tt(PG_FUNCTION_ARGS)
+{
+ TSVector txt = PG_GETARG_TSVECTOR(0);
+ TSQuery query = PG_GETARG_TSQUERY(1);
+ float res;
+
+ res = calc_rank(getWeights(NULL), txt, query, DEF_NORM_METHOD);
+
+ PG_FREE_IF_COPY(txt, 0);
+ PG_FREE_IF_COPY(query, 1);
+ PG_RETURN_FLOAT4(res);
+}
+
+typedef struct
+{
+ QueryItem **item;
+ int16 nitem;
+ bool needfree;
+ uint8 wclass;
+ int32 pos;
+} DocRepresentation;
+
+static int
+compareDocR(const void *a, const void *b)
+{
+ if (((DocRepresentation *) a)->pos == ((DocRepresentation *) b)->pos)
+ return 0;
+ return (((DocRepresentation *) a)->pos > ((DocRepresentation *) b)->pos) ? 1 : -1;
+}
+
+static bool
+checkcondition_QueryItem(void *checkval, QueryItem * val)
+{
+ return (bool) (val->istrue);
+}
+
+static void
+reset_istrue_flag(TSQuery query)
+{
+ QueryItem *item = GETQUERY(query);
+ int i;
+
+ /* reset istrue flag */
+ for (i = 0; i < query->size; i++)
+ {
+ if (item->type == VAL)
+ item->istrue = 0;
+ item++;
+ }
+}
+
+typedef struct
+{
+ int pos;
+ int p;
+ int q;
+ DocRepresentation *begin;
+ DocRepresentation *end;
+} Extention;
+
+
+static bool
+Cover(DocRepresentation * doc, int len, TSQuery query, Extention * ext)
+{
+ DocRepresentation *ptr;
+ int lastpos = ext->pos;
+ int i;
+ bool found = false;
+
+ reset_istrue_flag(query);
+
+ ext->p = 0x7fffffff;
+ ext->q = 0;
+ ptr = doc + ext->pos;
+
+ /* find upper bound of cover from current position, move up */
+ while (ptr - doc < len)
+ {
+ for (i = 0; i < ptr->nitem; i++)
+ ptr->item[i]->istrue = 1;
+ if (TS_execute(GETQUERY(query), NULL, false, checkcondition_QueryItem))
+ {
+ if (ptr->pos > ext->q)
+ {
+ ext->q = ptr->pos;
+ ext->end = ptr;
+ lastpos = ptr - doc;
+ found = true;
+ }
+ break;
+ }
+ ptr++;
+ }
+
+ if (!found)
+ return false;
+
+ reset_istrue_flag(query);
+
+ ptr = doc + lastpos;
+
+ /* find lower bound of cover from founded upper bound, move down */
+ while (ptr >= doc + ext->pos)
+ {
+ for (i = 0; i < ptr->nitem; i++)
+ ptr->item[i]->istrue = 1;
+ if (TS_execute(GETQUERY(query), NULL, true, checkcondition_QueryItem))
+ {
+ if (ptr->pos < ext->p)
+ {
+ ext->begin = ptr;
+ ext->p = ptr->pos;
+ }
+ break;
+ }
+ ptr--;
+ }
+
+ if (ext->p <= ext->q)
+ {
+ /*
+ * set position for next try to next lexeme after begining of founded
+ * cover
+ */
+ ext->pos = (ptr - doc) + 1;
+ return true;
+ }
+
+ ext->pos++;
+ return Cover(doc, len, query, ext);
+}
+
+static DocRepresentation *
+get_docrep(TSVector txt, TSQuery query, int *doclen)
+{
+ QueryItem *item = GETQUERY(query);
+ WordEntry *entry;
+ WordEntryPos *post;
+ int4 dimt,
+ j,
+ i;
+ int len = query->size * 4,
+ cur = 0;
+ DocRepresentation *doc;
+ char *operand;
+
+ *(uint16 *) POSNULL = lengthof(POSNULL) - 1;
+ doc = (DocRepresentation *) palloc(sizeof(DocRepresentation) * len);
+ operand = GETOPERAND(query);
+ reset_istrue_flag(query);
+
+ for (i = 0; i < query->size; i++)
+ {
+ if (item[i].type != VAL || item[i].istrue)
+ continue;
+
+ entry = find_wordentry(txt, query, &(item[i]));
+ if (!entry)
+ continue;
+
+ if (entry->haspos)
+ {
+ dimt = POSDATALEN(txt, entry);
+ post = POSDATAPTR(txt, entry);
+ }
+ else
+ {
+ dimt = *(uint16 *) POSNULL;
+ post = POSNULL + 1;
+ }
+
+ while (cur + dimt >= len)
+ {
+ len *= 2;
+ doc = (DocRepresentation *) repalloc(doc, sizeof(DocRepresentation) * len);
+ }
+
+ for (j = 0; j < dimt; j++)
+ {
+ if (j == 0)
+ {
+ QueryItem *kptr,
+ *iptr = item + i;
+ int k;
+
+ doc[cur].needfree = false;
+ doc[cur].nitem = 0;
+ doc[cur].item = (QueryItem **) palloc(sizeof(QueryItem *) * query->size);
+
+ for (k = 0; k < query->size; k++)
+ {
+ kptr = item + k;
+ if (k == i ||
+ (item[k].type == VAL &&
+ compareQueryItem(&kptr, &iptr, operand) == 0))
+ {
+ doc[cur].item[doc[cur].nitem] = item + k;
+ doc[cur].nitem++;
+ kptr->istrue = 1;
+ }
+ }
+ }
+ else
+ {
+ doc[cur].needfree = false;
+ doc[cur].nitem = doc[cur - 1].nitem;
+ doc[cur].item = doc[cur - 1].item;
+ }
+ doc[cur].pos = WEP_GETPOS(post[j]);
+ doc[cur].wclass = WEP_GETWEIGHT(post[j]);
+ cur++;
+ }
+ }
+
+ *doclen = cur;
+
+ if (cur > 0)
+ {
+ if (cur > 1)
+ qsort((void *) doc, cur, sizeof(DocRepresentation), compareDocR);
+ return doc;
+ }
+
+ pfree(doc);
+ return NULL;
+}
+
+static float4
+calc_rank_cd(float4 *arrdata, TSVector txt, TSQuery query, int method)
+{
+ DocRepresentation *doc;
+ int len,
+ i,
+ doclen = 0;
+ Extention ext;
+ double Wdoc = 0.0;
+ double invws[lengthof(weights)];
+ double SumDist = 0.0,
+ PrevExtPos = 0.0,
+ CurExtPos = 0.0;
+ int NExtent = 0;
+
+ for (i = 0; i < lengthof(weights); i++)
+ {
+ invws[i] = ((double) ((arrdata[i] >= 0) ? arrdata[i] : weights[i]));
+ if (invws[i] > 1.0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("weight out of range")));
+ invws[i] = 1.0 / invws[i];
+ }
+
+ doc = get_docrep(txt, query, &doclen);
+ if (!doc)
+ return 0.0;
+
+ MemSet(&ext, 0, sizeof(Extention));
+ while (Cover(doc, doclen, query, &ext))
+ {
+ double Cpos = 0.0;
+ double InvSum = 0.0;
+ int nNoise;
+ DocRepresentation *ptr = ext.begin;
+
+ while (ptr <= ext.end)
+ {
+ InvSum += invws[ptr->wclass];
+ ptr++;
+ }
+
+ Cpos = ((double) (ext.end - ext.begin + 1)) / InvSum;
+
+ /*
+ * if doc are big enough then ext.q may be equal to ext.p due to limit
+ * of posional information. In this case we approximate number of
+ * noise word as half cover's length
+ */
+ nNoise = (ext.q - ext.p) - (ext.end - ext.begin);
+ if (nNoise < 0)
+ nNoise = (ext.end - ext.begin) / 2;
+ Wdoc += Cpos / ((double) (1 + nNoise));
+
+ CurExtPos = ((double) (ext.q + ext.p)) / 2.0;
+ if (NExtent > 0 && CurExtPos > PrevExtPos /* prevent devision by
+ * zero in a case of
+ multiple lexize */ )
+ SumDist += 1.0 / (CurExtPos - PrevExtPos);
+
+ PrevExtPos = CurExtPos;
+ NExtent++;
+ }
+
+ if ((method & RANK_NORM_LOGLENGTH) && txt->size > 0)
+ Wdoc /= log((double) (cnt_length(txt) + 1));
+
+ if (method & RANK_NORM_LENGTH)
+ {
+ len = cnt_length(txt);
+ if (len > 0)
+ Wdoc /= (double) len;
+ }
+
+ if ((method & RANK_NORM_EXTDIST) && SumDist > 0)
+ Wdoc /= ((double) NExtent) / SumDist;
+
+ if ((method & RANK_NORM_UNIQ) && txt->size > 0)
+ Wdoc /= (double) (txt->size);
+
+ if ((method & RANK_NORM_LOGUNIQ) && txt->size > 0)
+ Wdoc /= log((double) (txt->size + 1)) / log(2.0);
+
+ for (i = 0; i < doclen; i++)
+ if (doc[i].needfree)
+ pfree(doc[i].item);
+ pfree(doc);
+
+ return (float4) Wdoc;
+}
+
+Datum
+ts_rankcd_wttf(PG_FUNCTION_ARGS)
+{
+ ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ TSVector txt = PG_GETARG_TSVECTOR(1);
+ TSQuery query = PG_GETARG_TSQUERY_COPY(2);
+ int method = PG_GETARG_INT32(3);
+ float res;
+
+ res = calc_rank_cd(getWeights(win), txt, query, method);
+
+ PG_FREE_IF_COPY(win, 0);
+ PG_FREE_IF_COPY(txt, 1);
+ PG_FREE_IF_COPY(query, 2);
+ PG_RETURN_FLOAT4(res);
+}
+
+Datum
+ts_rankcd_wtt(PG_FUNCTION_ARGS)
+{
+ ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ TSVector txt = PG_GETARG_TSVECTOR(1);
+ TSQuery query = PG_GETARG_TSQUERY_COPY(2);
+ float res;
+
+ res = calc_rank_cd(getWeights(win), txt, query, DEF_NORM_METHOD);
+
+ PG_FREE_IF_COPY(win, 0);
+ PG_FREE_IF_COPY(txt, 1);
+ PG_FREE_IF_COPY(query, 2);
+ PG_RETURN_FLOAT4(res);
+}
+
+Datum
+ts_rankcd_ttf(PG_FUNCTION_ARGS)
+{
+ TSVector txt = PG_GETARG_TSVECTOR(0);
+ TSQuery query = PG_GETARG_TSQUERY_COPY(1);
+ int method = PG_GETARG_INT32(2);
+ float res;
+
+ res = calc_rank_cd(getWeights(NULL), txt, query, method);
+
+ PG_FREE_IF_COPY(txt, 0);
+ PG_FREE_IF_COPY(query, 1);
+ PG_RETURN_FLOAT4(res);
+}
+
+Datum
+ts_rankcd_tt(PG_FUNCTION_ARGS)
+{
+ TSVector txt = PG_GETARG_TSVECTOR(0);
+ TSQuery query = PG_GETARG_TSQUERY_COPY(1);
+ float res;
+
+ res = calc_rank_cd(getWeights(NULL), txt, query, DEF_NORM_METHOD);
+
+ PG_FREE_IF_COPY(txt, 0);
+ PG_FREE_IF_COPY(query, 1);
+ PG_RETURN_FLOAT4(res);
+}
diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c
new file mode 100644
index 00000000000..04b6345e162
--- /dev/null
+++ b/src/backend/utils/adt/tsvector.c
@@ -0,0 +1,683 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsvector.c
+ * I/O functions for tsvector
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsvector.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "libpq/pqformat.h"
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_locale.h"
+#include "tsearch/ts_utils.h"
+#include "utils/memutils.h"
+
+
+static int
+comparePos(const void *a, const void *b)
+{
+ if (WEP_GETPOS(*(WordEntryPos *) a) == WEP_GETPOS(*(WordEntryPos *) b))
+ return 0;
+ return (WEP_GETPOS(*(WordEntryPos *) a) > WEP_GETPOS(*(WordEntryPos *) b)) ? 1 : -1;
+}
+
+static int
+uniquePos(WordEntryPos * a, int4 l)
+{
+ WordEntryPos *ptr,
+ *res;
+
+ if (l == 1)
+ return l;
+
+ res = a;
+ qsort((void *) a, l, sizeof(WordEntryPos), comparePos);
+
+ ptr = a + 1;
+ while (ptr - a < l)
+ {
+ if (WEP_GETPOS(*ptr) != WEP_GETPOS(*res))
+ {
+ res++;
+ *res = *ptr;
+ if (res - a >= MAXNUMPOS - 1 || WEP_GETPOS(*res) == MAXENTRYPOS - 1)
+ break;
+ }
+ else if (WEP_GETWEIGHT(*ptr) > WEP_GETWEIGHT(*res))
+ WEP_SETWEIGHT(*res, WEP_GETWEIGHT(*ptr));
+ ptr++;
+ }
+
+ return res + 1 - a;
+}
+
+static int
+compareentry(const void *a, const void *b, void *arg)
+{
+ char *BufferStr = (char *) arg;
+
+ if (((WordEntryIN *) a)->entry.len == ((WordEntryIN *) b)->entry.len)
+ {
+ return strncmp(&BufferStr[((WordEntryIN *) a)->entry.pos],
+ &BufferStr[((WordEntryIN *) b)->entry.pos],
+ ((WordEntryIN *) a)->entry.len);
+ }
+
+ return (((WordEntryIN *) a)->entry.len > ((WordEntryIN *) b)->entry.len) ? 1 : -1;
+}
+
+static int
+uniqueentry(WordEntryIN * a, int4 l, char *buf, int4 *outbuflen)
+{
+ WordEntryIN *ptr,
+ *res;
+
+ res = a;
+ if (l == 1)
+ {
+ if (a->entry.haspos)
+ {
+ *(uint16 *) (a->pos) = uniquePos(&(a->pos[1]), *(uint16 *) (a->pos));
+ *outbuflen = SHORTALIGN(res->entry.len) + (*(uint16 *) (a->pos) + 1) * sizeof(WordEntryPos);
+ }
+ return l;
+ }
+
+ ptr = a + 1;
+ qsort_arg((void *) a, l, sizeof(WordEntryIN), compareentry, (void *) buf);
+
+ while (ptr - a < l)
+ {
+ if (!(ptr->entry.len == res->entry.len &&
+ strncmp(&buf[ptr->entry.pos], &buf[res->entry.pos], res->entry.len) == 0))
+ {
+ if (res->entry.haspos)
+ {
+ *(uint16 *) (res->pos) = uniquePos(&(res->pos[1]), *(uint16 *) (res->pos));
+ *outbuflen += *(uint16 *) (res->pos) * sizeof(WordEntryPos);
+ }
+ *outbuflen += SHORTALIGN(res->entry.len);
+ res++;
+ memcpy(res, ptr, sizeof(WordEntryIN));
+ }
+ else if (ptr->entry.haspos)
+ {
+ if (res->entry.haspos)
+ {
+ int4 len = *(uint16 *) (ptr->pos) + 1 + *(uint16 *) (res->pos);
+
+ res->pos = (WordEntryPos *) repalloc(res->pos, len * sizeof(WordEntryPos));
+ memcpy(&(res->pos[*(uint16 *) (res->pos) + 1]),
+ &(ptr->pos[1]), *(uint16 *) (ptr->pos) * sizeof(WordEntryPos));
+ *(uint16 *) (res->pos) += *(uint16 *) (ptr->pos);
+ pfree(ptr->pos);
+ }
+ else
+ {
+ res->entry.haspos = 1;
+ res->pos = ptr->pos;
+ }
+ }
+ ptr++;
+ }
+ if (res->entry.haspos)
+ {
+ *(uint16 *) (res->pos) = uniquePos(&(res->pos[1]), *(uint16 *) (res->pos));
+ *outbuflen += *(uint16 *) (res->pos) * sizeof(WordEntryPos);
+ }
+ *outbuflen += SHORTALIGN(res->entry.len);
+
+ return res + 1 - a;
+}
+
+static int
+WordEntryCMP(WordEntry * a, WordEntry * b, char *buf)
+{
+ return compareentry(a, b, buf);
+}
+
+#define WAITWORD 1
+#define WAITENDWORD 2
+#define WAITNEXTCHAR 3
+#define WAITENDCMPLX 4
+#define WAITPOSINFO 5
+#define INPOSINFO 6
+#define WAITPOSDELIM 7
+#define WAITCHARCMPLX 8
+
+#define RESIZEPRSBUF \
+do { \
+ if ( state->curpos - state->word + pg_database_encoding_max_length() >= state->len ) \
+ { \
+ int4 clen = state->curpos - state->word; \
+ state->len *= 2; \
+ state->word = (char*)repalloc( (void*)state->word, state->len ); \
+ state->curpos = state->word + clen; \
+ } \
+} while (0)
+
+bool
+gettoken_tsvector(TSVectorParseState *state)
+{
+ int4 oldstate = 0;
+
+ state->curpos = state->word;
+ state->state = WAITWORD;
+ state->alen = 0;
+
+ while (1)
+ {
+ if (state->state == WAITWORD)
+ {
+ if (*(state->prsbuf) == '\0')
+ return false;
+ else if (t_iseq(state->prsbuf, '\''))
+ state->state = WAITENDCMPLX;
+ else if (t_iseq(state->prsbuf, '\\'))
+ {
+ state->state = WAITNEXTCHAR;
+ oldstate = WAITENDWORD;
+ }
+ else if (state->oprisdelim && ISOPERATOR(state->prsbuf))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ else if (!t_isspace(state->prsbuf))
+ {
+ COPYCHAR(state->curpos, state->prsbuf);
+ state->curpos += pg_mblen(state->prsbuf);
+ state->state = WAITENDWORD;
+ }
+ }
+ else if (state->state == WAITNEXTCHAR)
+ {
+ if (*(state->prsbuf) == '\0')
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("there is no escaped character")));
+ else
+ {
+ RESIZEPRSBUF;
+ COPYCHAR(state->curpos, state->prsbuf);
+ state->curpos += pg_mblen(state->prsbuf);
+ state->state = oldstate;
+ }
+ }
+ else if (state->state == WAITENDWORD)
+ {
+ if (t_iseq(state->prsbuf, '\\'))
+ {
+ state->state = WAITNEXTCHAR;
+ oldstate = WAITENDWORD;
+ }
+ else if (t_isspace(state->prsbuf) || *(state->prsbuf) == '\0' ||
+ (state->oprisdelim && ISOPERATOR(state->prsbuf)))
+ {
+ RESIZEPRSBUF;
+ if (state->curpos == state->word)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ *(state->curpos) = '\0';
+ return true;
+ }
+ else if (t_iseq(state->prsbuf, ':'))
+ {
+ if (state->curpos == state->word)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ *(state->curpos) = '\0';
+ if (state->oprisdelim)
+ return true;
+ else
+ state->state = INPOSINFO;
+ }
+ else
+ {
+ RESIZEPRSBUF;
+ COPYCHAR(state->curpos, state->prsbuf);
+ state->curpos += pg_mblen(state->prsbuf);
+ }
+ }
+ else if (state->state == WAITENDCMPLX)
+ {
+ if (t_iseq(state->prsbuf, '\''))
+ {
+ state->state = WAITCHARCMPLX;
+ }
+ else if (t_iseq(state->prsbuf, '\\'))
+ {
+ state->state = WAITNEXTCHAR;
+ oldstate = WAITENDCMPLX;
+ }
+ else if (*(state->prsbuf) == '\0')
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ else
+ {
+ RESIZEPRSBUF;
+ COPYCHAR(state->curpos, state->prsbuf);
+ state->curpos += pg_mblen(state->prsbuf);
+ }
+ }
+ else if (state->state == WAITCHARCMPLX)
+ {
+ if (t_iseq(state->prsbuf, '\''))
+ {
+ RESIZEPRSBUF;
+ COPYCHAR(state->curpos, state->prsbuf);
+ state->curpos += pg_mblen(state->prsbuf);
+ state->state = WAITENDCMPLX;
+ }
+ else
+ {
+ RESIZEPRSBUF;
+ *(state->curpos) = '\0';
+ if (state->curpos == state->word)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ if (state->oprisdelim)
+ {
+ /* state->prsbuf+=pg_mblen(state->prsbuf); */
+ return true;
+ }
+ else
+ state->state = WAITPOSINFO;
+ continue; /* recheck current character */
+ }
+ }
+ else if (state->state == WAITPOSINFO)
+ {
+ if (t_iseq(state->prsbuf, ':'))
+ state->state = INPOSINFO;
+ else
+ return true;
+ }
+ else if (state->state == INPOSINFO)
+ {
+ if (t_isdigit(state->prsbuf))
+ {
+ if (state->alen == 0)
+ {
+ state->alen = 4;
+ state->pos = (WordEntryPos *) palloc(sizeof(WordEntryPos) * state->alen);
+ *(uint16 *) (state->pos) = 0;
+ }
+ else if (*(uint16 *) (state->pos) + 1 >= state->alen)
+ {
+ state->alen *= 2;
+ state->pos = (WordEntryPos *) repalloc(state->pos, sizeof(WordEntryPos) * state->alen);
+ }
+ (*(uint16 *) (state->pos))++;
+ WEP_SETPOS(state->pos[*(uint16 *) (state->pos)], LIMITPOS(atoi(state->prsbuf)));
+ if (WEP_GETPOS(state->pos[*(uint16 *) (state->pos)]) == 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("wrong position info in tsvector")));
+ WEP_SETWEIGHT(state->pos[*(uint16 *) (state->pos)], 0);
+ state->state = WAITPOSDELIM;
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ }
+ else if (state->state == WAITPOSDELIM)
+ {
+ if (t_iseq(state->prsbuf, ','))
+ state->state = INPOSINFO;
+ else if (t_iseq(state->prsbuf, 'a') || t_iseq(state->prsbuf, 'A') || t_iseq(state->prsbuf, '*'))
+ {
+ if (WEP_GETWEIGHT(state->pos[*(uint16 *) (state->pos)]))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ WEP_SETWEIGHT(state->pos[*(uint16 *) (state->pos)], 3);
+ }
+ else if (t_iseq(state->prsbuf, 'b') || t_iseq(state->prsbuf, 'B'))
+ {
+ if (WEP_GETWEIGHT(state->pos[*(uint16 *) (state->pos)]))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ WEP_SETWEIGHT(state->pos[*(uint16 *) (state->pos)], 2);
+ }
+ else if (t_iseq(state->prsbuf, 'c') || t_iseq(state->prsbuf, 'C'))
+ {
+ if (WEP_GETWEIGHT(state->pos[*(uint16 *) (state->pos)]))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ WEP_SETWEIGHT(state->pos[*(uint16 *) (state->pos)], 1);
+ }
+ else if (t_iseq(state->prsbuf, 'd') || t_iseq(state->prsbuf, 'D'))
+ {
+ if (WEP_GETWEIGHT(state->pos[*(uint16 *) (state->pos)]))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ WEP_SETWEIGHT(state->pos[*(uint16 *) (state->pos)], 0);
+ }
+ else if (t_isspace(state->prsbuf) ||
+ *(state->prsbuf) == '\0')
+ return true;
+ else if (!t_isdigit(state->prsbuf))
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("syntax error in tsvector")));
+ }
+ else /* internal error */
+ elog(ERROR, "internal error in gettoken_tsvector");
+
+ /* get next char */
+ state->prsbuf += pg_mblen(state->prsbuf);
+ }
+
+ return false;
+}
+
+Datum
+tsvectorin(PG_FUNCTION_ARGS)
+{
+ char *buf = PG_GETARG_CSTRING(0);
+ TSVectorParseState state;
+ WordEntryIN *arr;
+ WordEntry *inarr;
+ int4 len = 0,
+ totallen = 64;
+ TSVector in;
+ char *tmpbuf,
+ *cur;
+ int4 i,
+ buflen = 256;
+
+ pg_verifymbstr(buf, strlen(buf), false);
+ state.prsbuf = buf;
+ state.len = 32;
+ state.word = (char *) palloc(state.len);
+ state.oprisdelim = false;
+
+ arr = (WordEntryIN *) palloc(sizeof(WordEntryIN) * totallen);
+ cur = tmpbuf = (char *) palloc(buflen);
+
+ while (gettoken_tsvector(&state))
+ {
+ /*
+ * Realloc buffers if it's needed
+ */
+ if (len >= totallen)
+ {
+ totallen *= 2;
+ arr = (WordEntryIN *) repalloc((void *) arr, sizeof(WordEntryIN) * totallen);
+ }
+
+ while ((cur - tmpbuf) + (state.curpos - state.word) >= buflen)
+ {
+ int4 dist = cur - tmpbuf;
+
+ buflen *= 2;
+ tmpbuf = (char *) repalloc((void *) tmpbuf, buflen);
+ cur = tmpbuf + dist;
+ }
+
+ if (state.curpos - state.word >= MAXSTRLEN)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("word is too long (%d bytes, max %d bytes)",
+ state.curpos - state.word, MAXSTRLEN)));
+
+ arr[len].entry.len = state.curpos - state.word;
+ if (cur - tmpbuf > MAXSTRPOS)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("position value too large")));
+ arr[len].entry.pos = cur - tmpbuf;
+ memcpy((void *) cur, (void *) state.word, arr[len].entry.len);
+ cur += arr[len].entry.len;
+
+ if (state.alen)
+ {
+ arr[len].entry.haspos = 1;
+ arr[len].pos = state.pos;
+ }
+ else
+ arr[len].entry.haspos = 0;
+ len++;
+ }
+ pfree(state.word);
+
+ if (len > 0)
+ len = uniqueentry(arr, len, tmpbuf, &buflen);
+ else
+ buflen = 0;
+ totallen = CALCDATASIZE(len, buflen);
+ in = (TSVector) palloc0(totallen);
+
+ SET_VARSIZE(in, totallen);
+ in->size = len;
+ cur = STRPTR(in);
+ inarr = ARRPTR(in);
+ for (i = 0; i < len; i++)
+ {
+ memcpy((void *) cur, (void *) &tmpbuf[arr[i].entry.pos], arr[i].entry.len);
+ arr[i].entry.pos = cur - STRPTR(in);
+ cur += SHORTALIGN(arr[i].entry.len);
+ if (arr[i].entry.haspos)
+ {
+ memcpy(cur, arr[i].pos, (*(uint16 *) arr[i].pos + 1) * sizeof(WordEntryPos));
+ cur += (*(uint16 *) arr[i].pos + 1) * sizeof(WordEntryPos);
+ pfree(arr[i].pos);
+ }
+ inarr[i] = arr[i].entry;
+ }
+
+ PG_RETURN_TSVECTOR(in);
+}
+
+Datum
+tsvectorout(PG_FUNCTION_ARGS)
+{
+ TSVector out = PG_GETARG_TSVECTOR(0);
+ char *outbuf;
+ int4 i,
+ lenbuf = 0,
+ pp;
+ WordEntry *ptr = ARRPTR(out);
+ char *curbegin,
+ *curin,
+ *curout;
+
+ lenbuf = out->size * 2 /* '' */ + out->size - 1 /* space */ + 2 /* \0 */ ;
+ for (i = 0; i < out->size; i++)
+ {
+ lenbuf += ptr[i].len * 2 * pg_database_encoding_max_length() /* for escape */ ;
+ if (ptr[i].haspos)
+ lenbuf += 1 /* : */ + 7 /* int2 + , + weight */ * POSDATALEN(out, &(ptr[i]));
+ }
+
+ curout = outbuf = (char *) palloc(lenbuf);
+ for (i = 0; i < out->size; i++)
+ {
+ curbegin = curin = STRPTR(out) + ptr->pos;
+ if (i != 0)
+ *curout++ = ' ';
+ *curout++ = '\'';
+ while (curin - curbegin < ptr->len)
+ {
+ int len = pg_mblen(curin);
+
+ if (t_iseq(curin, '\''))
+ *curout++ = '\'';
+
+ while (len--)
+ *curout++ = *curin++;
+ }
+
+ *curout++ = '\'';
+ if ((pp = POSDATALEN(out, ptr)) != 0)
+ {
+ WordEntryPos *wptr;
+
+ *curout++ = ':';
+ wptr = POSDATAPTR(out, ptr);
+ while (pp)
+ {
+ curout += sprintf(curout, "%d", WEP_GETPOS(*wptr));
+ switch (WEP_GETWEIGHT(*wptr))
+ {
+ case 3:
+ *curout++ = 'A';
+ break;
+ case 2:
+ *curout++ = 'B';
+ break;
+ case 1:
+ *curout++ = 'C';
+ break;
+ case 0:
+ default:
+ break;
+ }
+
+ if (pp > 1)
+ *curout++ = ',';
+ pp--;
+ wptr++;
+ }
+ }
+ ptr++;
+ }
+
+ *curout = '\0';
+ PG_FREE_IF_COPY(out, 0);
+ PG_RETURN_CSTRING(outbuf);
+}
+
+Datum
+tsvectorsend(PG_FUNCTION_ARGS)
+{
+ TSVector vec = PG_GETARG_TSVECTOR(0);
+ StringInfoData buf;
+ int i,
+ j;
+ WordEntry *weptr = ARRPTR(vec);
+
+ pq_begintypsend(&buf);
+
+ pq_sendint(&buf, vec->size, sizeof(int32));
+ for (i = 0; i < vec->size; i++)
+ {
+ /*
+ * We are sure that sizeof(WordEntry) == sizeof(int32)
+ */
+ pq_sendint(&buf, *(int32 *) weptr, sizeof(int32));
+
+ pq_sendbytes(&buf, STRPTR(vec) + weptr->pos, weptr->len);
+ if (weptr->haspos)
+ {
+ WordEntryPos *wepptr = POSDATAPTR(vec, weptr);
+
+ pq_sendint(&buf, POSDATALEN(vec, weptr), sizeof(WordEntryPos));
+ for (j = 0; j < POSDATALEN(vec, weptr); j++)
+ pq_sendint(&buf, wepptr[j], sizeof(WordEntryPos));
+ }
+ weptr++;
+ }
+
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
+Datum
+tsvectorrecv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ TSVector vec;
+ int i,
+ size,
+ len = DATAHDRSIZE;
+ WordEntry *weptr;
+ int datalen = 0;
+
+ size = pq_getmsgint(buf, sizeof(uint32));
+ if (size < 0 || size > (MaxAllocSize / sizeof(WordEntry)))
+ elog(ERROR, "invalid size of tsvector");
+
+ len += sizeof(WordEntry) * size;
+
+ len *= 2;
+ vec = (TSVector) palloc0(len);
+ vec->size = size;
+
+ weptr = ARRPTR(vec);
+ for (i = 0; i < size; i++)
+ {
+ int tmp;
+
+ weptr = ARRPTR(vec) + i;
+
+ /*
+ * We are sure that sizeof(WordEntry) == sizeof(int32)
+ */
+ tmp = pq_getmsgint(buf, sizeof(int32));
+ *weptr = *(WordEntry *) & tmp;
+
+ while (CALCDATASIZE(size, datalen + SHORTALIGN(weptr->len)) >= len)
+ {
+ len *= 2;
+ vec = (TSVector) repalloc(vec, len);
+ weptr = ARRPTR(vec) + i;
+ }
+
+ memcpy(STRPTR(vec) + weptr->pos,
+ pq_getmsgbytes(buf, weptr->len),
+ weptr->len);
+ datalen += SHORTALIGN(weptr->len);
+
+ if (i > 0 && WordEntryCMP(weptr, weptr - 1, STRPTR(vec)) <= 0)
+ elog(ERROR, "lexemes are unordered");
+
+ if (weptr->haspos)
+ {
+ uint16 j,
+ npos;
+ WordEntryPos *wepptr;
+
+ npos = (uint16) pq_getmsgint(buf, sizeof(int16));
+ if (npos > MAXNUMPOS)
+ elog(ERROR, "unexpected number of positions");
+
+ while (CALCDATASIZE(size, datalen + (npos + 1) * sizeof(WordEntryPos)) >= len)
+ {
+ len *= 2;
+ vec = (TSVector) repalloc(vec, len);
+ weptr = ARRPTR(vec) + i;
+ }
+
+ memcpy(_POSDATAPTR(vec, weptr), &npos, sizeof(int16));
+ wepptr = POSDATAPTR(vec, weptr);
+ for (j = 0; j < npos; j++)
+ {
+ wepptr[j] = (WordEntryPos) pq_getmsgint(buf, sizeof(int16));
+ if (j > 0 && WEP_GETPOS(wepptr[j]) <= WEP_GETPOS(wepptr[j - 1]))
+ elog(ERROR, "position information is unordered");
+ }
+
+ datalen += (npos + 1) * sizeof(WordEntry);
+ }
+ }
+
+ SET_VARSIZE(vec, CALCDATASIZE(vec->size, datalen));
+
+ PG_RETURN_TSVECTOR(vec);
+}
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
new file mode 100644
index 00000000000..341247bec75
--- /dev/null
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -0,0 +1,1334 @@
+/*-------------------------------------------------------------------------
+ *
+ * tsvector_op.c
+ * operations over tsvector
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/adt/tsvector_op.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+#include "catalog/namespace.h"
+#include "commands/trigger.h"
+#include "executor/spi.h"
+#include "funcapi.h"
+#include "mb/pg_wchar.h"
+#include "tsearch/ts_type.h"
+#include "tsearch/ts_utils.h"
+#include "utils/builtins.h"
+#include "utils/lsyscache.h"
+
+
+typedef struct
+{
+ WordEntry *arrb;
+ WordEntry *arre;
+ char *values;
+ char *operand;
+} CHKVAL;
+
+typedef struct
+{
+ uint32 cur;
+ TSVector stat;
+} StatStorage;
+
+typedef struct
+{
+ uint32 len;
+ uint32 pos;
+ uint32 ndoc;
+ uint32 nentry;
+} StatEntry;
+
+typedef struct
+{
+ int32 vl_len_; /* varlena header (do not touch directly!) */
+ int4 size;
+ int4 weight;
+ char data[1];
+} tsstat;
+
+#define STATHDRSIZE (sizeof(int4) * 4)
+#define CALCSTATSIZE(x, lenstr) ( (x) * sizeof(StatEntry) + STATHDRSIZE + (lenstr) )
+#define STATPTR(x) ( (StatEntry*) ( (char*)(x) + STATHDRSIZE ) )
+#define STATSTRPTR(x) ( (char*)(x) + STATHDRSIZE + ( sizeof(StatEntry) * ((TSVector)(x))->size ) )
+#define STATSTRSIZE(x) ( VARSIZE((TSVector)(x)) - STATHDRSIZE - ( sizeof(StatEntry) * ((TSVector)(x))->size ) )
+
+
+static Datum tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column);
+
+
+static int
+silly_cmp_tsvector(const TSVector a, const TSVector b)
+{
+ if (VARSIZE(a) < VARSIZE(b))
+ return -1;
+ else if (VARSIZE(a) > VARSIZE(b))
+ return 1;
+ else if (a->size < b->size)
+ return -1;
+ else if (a->size > b->size)
+ return 1;
+ else
+ {
+ WordEntry *aptr = ARRPTR(a);
+ WordEntry *bptr = ARRPTR(b);
+ int i = 0;
+ int res;
+
+
+ for (i = 0; i < a->size; i++)
+ {
+ if (aptr->haspos != bptr->haspos)
+ {
+ return (aptr->haspos > bptr->haspos) ? -1 : 1;
+ }
+ else if (aptr->len != bptr->len)
+ {
+ return (aptr->len > bptr->len) ? -1 : 1;
+ }
+ else if ((res = strncmp(STRPTR(a) + aptr->pos, STRPTR(b) + bptr->pos, bptr->len)) != 0)
+ {
+ return res;
+ }
+ else if (aptr->haspos)
+ {
+ WordEntryPos *ap = POSDATAPTR(a, aptr);
+ WordEntryPos *bp = POSDATAPTR(b, bptr);
+ int j;
+
+ if (POSDATALEN(a, aptr) != POSDATALEN(b, bptr))
+ return (POSDATALEN(a, aptr) > POSDATALEN(b, bptr)) ? -1 : 1;
+
+ for (j = 0; j < POSDATALEN(a, aptr); j++)
+ {
+ if (WEP_GETPOS(*ap) != WEP_GETPOS(*bp))
+ {
+ return (WEP_GETPOS(*ap) > WEP_GETPOS(*bp)) ? -1 : 1;
+ }
+ else if (WEP_GETWEIGHT(*ap) != WEP_GETWEIGHT(*bp))
+ {
+ return (WEP_GETWEIGHT(*ap) > WEP_GETWEIGHT(*bp)) ? -1 : 1;
+ }
+ ap++, bp++;
+ }
+ }
+
+ aptr++;
+ bptr++;
+ }
+ }
+
+ return 0;
+}
+
+#define TSVECTORCMPFUNC( type, action, ret ) \
+Datum \
+tsvector_##type(PG_FUNCTION_ARGS) \
+{ \
+ TSVector a = PG_GETARG_TSVECTOR(0); \
+ TSVector b = PG_GETARG_TSVECTOR(1); \
+ int res = silly_cmp_tsvector(a, b); \
+ PG_FREE_IF_COPY(a,0); \
+ PG_FREE_IF_COPY(b,1); \
+ PG_RETURN_##ret( res action 0 ); \
+}
+
+TSVECTORCMPFUNC(lt, <, BOOL);
+TSVECTORCMPFUNC(le, <=, BOOL);
+TSVECTORCMPFUNC(eq, ==, BOOL);
+TSVECTORCMPFUNC(ge, >=, BOOL);
+TSVECTORCMPFUNC(gt, >, BOOL);
+TSVECTORCMPFUNC(ne, !=, BOOL);
+TSVECTORCMPFUNC(cmp, +, INT32);
+
+Datum
+tsvector_strip(PG_FUNCTION_ARGS)
+{
+ TSVector in = PG_GETARG_TSVECTOR(0);
+ TSVector out;
+ int i,
+ len = 0;
+ WordEntry *arrin = ARRPTR(in),
+ *arrout;
+ char *cur;
+
+ for (i = 0; i < in->size; i++)
+ len += SHORTALIGN(arrin[i].len);
+
+ len = CALCDATASIZE(in->size, len);
+ out = (TSVector) palloc0(len);
+ SET_VARSIZE(out, len);
+ out->size = in->size;
+ arrout = ARRPTR(out);
+ cur = STRPTR(out);
+ for (i = 0; i < in->size; i++)
+ {
+ memcpy(cur, STRPTR(in) + arrin[i].pos, arrin[i].len);
+ arrout[i].haspos = 0;
+ arrout[i].len = arrin[i].len;
+ arrout[i].pos = cur - STRPTR(out);
+ cur += SHORTALIGN(arrout[i].len);
+ }
+
+ PG_FREE_IF_COPY(in, 0);
+ PG_RETURN_POINTER(out);
+}
+
+Datum
+tsvector_length(PG_FUNCTION_ARGS)
+{
+ TSVector in = PG_GETARG_TSVECTOR(0);
+ int4 ret = in->size;
+
+ PG_FREE_IF_COPY(in, 0);
+ PG_RETURN_INT32(ret);
+}
+
+Datum
+tsvector_setweight(PG_FUNCTION_ARGS)
+{
+ TSVector in = PG_GETARG_TSVECTOR(0);
+ char cw = PG_GETARG_CHAR(1);
+ TSVector out;
+ int i,
+ j;
+ WordEntry *entry;
+ WordEntryPos *p;
+ int w = 0;
+
+ switch (cw)
+ {
+ case 'A':
+ case 'a':
+ w = 3;
+ break;
+ case 'B':
+ case 'b':
+ w = 2;
+ break;
+ case 'C':
+ case 'c':
+ w = 1;
+ break;
+ case 'D':
+ case 'd':
+ w = 0;
+ break;
+ /* internal error */
+ default:
+ elog(ERROR, "unrecognized weight");
+ }
+
+ out = (TSVector) palloc(VARSIZE(in));
+ memcpy(out, in, VARSIZE(in));
+ entry = ARRPTR(out);
+ i = out->size;
+ while (i--)
+ {
+ if ((j = POSDATALEN(out, entry)) != 0)
+ {
+ p = POSDATAPTR(out, entry);
+ while (j--)
+ {
+ WEP_SETWEIGHT(*p, w);
+ p++;
+ }
+ }
+ entry++;
+ }
+
+ PG_FREE_IF_COPY(in, 0);
+ PG_RETURN_POINTER(out);
+}
+
+static int
+compareEntry(char *ptra, WordEntry * a, char *ptrb, WordEntry * b)
+{
+ if (a->len == b->len)
+ {
+ return strncmp(
+ ptra + a->pos,
+ ptrb + b->pos,
+ a->len);
+ }
+ return (a->len > b->len) ? 1 : -1;
+}
+
+static int4
+add_pos(TSVector src, WordEntry * srcptr, TSVector dest, WordEntry * destptr, int4 maxpos)
+{
+ uint16 *clen = (uint16 *) _POSDATAPTR(dest, destptr);
+ int i;
+ uint16 slen = POSDATALEN(src, srcptr),
+ startlen;
+ WordEntryPos *spos = POSDATAPTR(src, srcptr),
+ *dpos = POSDATAPTR(dest, destptr);
+
+ if (!destptr->haspos)
+ *clen = 0;
+
+ startlen = *clen;
+ for (i = 0; i < slen && *clen < MAXNUMPOS && (*clen == 0 || WEP_GETPOS(dpos[*clen - 1]) != MAXENTRYPOS - 1); i++)
+ {
+ WEP_SETWEIGHT(dpos[*clen], WEP_GETWEIGHT(spos[i]));
+ WEP_SETPOS(dpos[*clen], LIMITPOS(WEP_GETPOS(spos[i]) + maxpos));
+ (*clen)++;
+ }
+
+ if (*clen != startlen)
+ destptr->haspos = 1;
+ return *clen - startlen;
+}
+
+
+Datum
+tsvector_concat(PG_FUNCTION_ARGS)
+{
+ TSVector in1 = PG_GETARG_TSVECTOR(0);
+ TSVector in2 = PG_GETARG_TSVECTOR(1);
+ TSVector out;
+ WordEntry *ptr;
+ WordEntry *ptr1,
+ *ptr2;
+ WordEntryPos *p;
+ int maxpos = 0,
+ i,
+ j,
+ i1,
+ i2;
+ char *cur;
+ char *data,
+ *data1,
+ *data2;
+
+ ptr = ARRPTR(in1);
+ i = in1->size;
+ while (i--)
+ {
+ if ((j = POSDATALEN(in1, ptr)) != 0)
+ {
+ p = POSDATAPTR(in1, ptr);
+ while (j--)
+ {
+ if (WEP_GETPOS(*p) > maxpos)
+ maxpos = WEP_GETPOS(*p);
+ p++;
+ }
+ }
+ ptr++;
+ }
+
+ ptr1 = ARRPTR(in1);
+ ptr2 = ARRPTR(in2);
+ data1 = STRPTR(in1);
+ data2 = STRPTR(in2);
+ i1 = in1->size;
+ i2 = in2->size;
+ out = (TSVector) palloc0(VARSIZE(in1) + VARSIZE(in2));
+ SET_VARSIZE(out, VARSIZE(in1) + VARSIZE(in2));
+ out->size = in1->size + in2->size;
+ data = cur = STRPTR(out);
+ ptr = ARRPTR(out);
+ while (i1 && i2)
+ {
+ int cmp = compareEntry(data1, ptr1, data2, ptr2);
+
+ if (cmp < 0)
+ { /* in1 first */
+ ptr->haspos = ptr1->haspos;
+ ptr->len = ptr1->len;
+ memcpy(cur, data1 + ptr1->pos, ptr1->len);
+ ptr->pos = cur - data;
+ cur += SHORTALIGN(ptr1->len);
+ if (ptr->haspos)
+ {
+ memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
+ cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
+ }
+ ptr++;
+ ptr1++;
+ i1--;
+ }
+ else if (cmp > 0)
+ { /* in2 first */
+ ptr->haspos = ptr2->haspos;
+ ptr->len = ptr2->len;
+ memcpy(cur, data2 + ptr2->pos, ptr2->len);
+ ptr->pos = cur - data;
+ cur += SHORTALIGN(ptr2->len);
+ if (ptr->haspos)
+ {
+ int addlen = add_pos(in2, ptr2, out, ptr, maxpos);
+
+ if (addlen == 0)
+ ptr->haspos = 0;
+ else
+ cur += addlen * sizeof(WordEntryPos) + sizeof(uint16);
+ }
+ ptr++;
+ ptr2++;
+ i2--;
+ }
+ else
+ {
+ ptr->haspos = ptr1->haspos | ptr2->haspos;
+ ptr->len = ptr1->len;
+ memcpy(cur, data1 + ptr1->pos, ptr1->len);
+ ptr->pos = cur - data;
+ cur += SHORTALIGN(ptr1->len);
+ if (ptr->haspos)
+ {
+ if (ptr1->haspos)
+ {
+ memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
+ cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
+ if (ptr2->haspos)
+ cur += add_pos(in2, ptr2, out, ptr, maxpos) * sizeof(WordEntryPos);
+ }
+ else if (ptr2->haspos)
+ {
+ int addlen = add_pos(in2, ptr2, out, ptr, maxpos);
+
+ if (addlen == 0)
+ ptr->haspos = 0;
+ else
+ cur += addlen * sizeof(WordEntryPos) + sizeof(uint16);
+ }
+ }
+ ptr++;
+ ptr1++;
+ ptr2++;
+ i1--;
+ i2--;
+ }
+ }
+
+ while (i1)
+ {
+ ptr->haspos = ptr1->haspos;
+ ptr->len = ptr1->len;
+ memcpy(cur, data1 + ptr1->pos, ptr1->len);
+ ptr->pos = cur - data;
+ cur += SHORTALIGN(ptr1->len);
+ if (ptr->haspos)
+ {
+ memcpy(cur, _POSDATAPTR(in1, ptr1), POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16));
+ cur += POSDATALEN(in1, ptr1) * sizeof(WordEntryPos) + sizeof(uint16);
+ }
+ ptr++;
+ ptr1++;
+ i1--;
+ }
+
+ while (i2)
+ {
+ ptr->haspos = ptr2->haspos;
+ ptr->len = ptr2->len;
+ memcpy(cur, data2 + ptr2->pos, ptr2->len);
+ ptr->pos = cur - data;
+ cur += SHORTALIGN(ptr2->len);
+ if (ptr->haspos)
+ {
+ int addlen = add_pos(in2, ptr2, out, ptr, maxpos);
+
+ if (addlen == 0)
+ ptr->haspos = 0;
+ else
+ cur += addlen * sizeof(WordEntryPos) + sizeof(uint16);
+ }
+ ptr++;
+ ptr2++;
+ i2--;
+ }
+
+ out->size = ptr - ARRPTR(out);
+ SET_VARSIZE(out, CALCDATASIZE(out->size, cur - data));
+ if (data != STRPTR(out))
+ memmove(STRPTR(out), data, cur - data);
+
+ PG_FREE_IF_COPY(in1, 0);
+ PG_FREE_IF_COPY(in2, 1);
+ PG_RETURN_POINTER(out);
+}
+
+/*
+ * compare 2 string values
+ */
+static int4
+ValCompare(CHKVAL * chkval, WordEntry * ptr, QueryItem * item)
+{
+ if (ptr->len == item->length)
+ return strncmp(
+ &(chkval->values[ptr->pos]),
+ &(chkval->operand[item->distance]),
+ item->length);
+
+ return (ptr->len > item->length) ? 1 : -1;
+}
+
+/*
+ * check weight info
+ */
+static bool
+checkclass_str(CHKVAL * chkval, WordEntry * val, QueryItem * item)
+{
+ WordEntryPos *ptr = (WordEntryPos *) (chkval->values + val->pos + SHORTALIGN(val->len) + sizeof(uint16));
+ uint16 len = *((uint16 *) (chkval->values + val->pos + SHORTALIGN(val->len)));
+
+ while (len--)
+ {
+ if (item->weight & (1 << WEP_GETWEIGHT(*ptr)))
+ return true;
+ ptr++;
+ }
+ return false;
+}
+
+/*
+ * is there value 'val' in array or not ?
+ */
+static bool
+checkcondition_str(void *checkval, QueryItem * val)
+{
+ WordEntry *StopLow = ((CHKVAL *) checkval)->arrb;
+ WordEntry *StopHigh = ((CHKVAL *) checkval)->arre;
+ WordEntry *StopMiddle;
+ int difference;
+
+ /* Loop invariant: StopLow <= val < StopHigh */
+
+ while (StopLow < StopHigh)
+ {
+ StopMiddle = StopLow + (StopHigh - StopLow) / 2;
+ difference = ValCompare((CHKVAL *) checkval, StopMiddle, val);
+ if (difference == 0)
+ return (val->weight && StopMiddle->haspos) ?
+ checkclass_str((CHKVAL *) checkval, StopMiddle, val) : true;
+ else if (difference < 0)
+ StopLow = StopMiddle + 1;
+ else
+ StopHigh = StopMiddle;
+ }
+
+ return (false);
+}
+
+/*
+ * check for boolean condition
+ */
+bool
+TS_execute(QueryItem * curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, QueryItem * val))
+{
+ if (curitem->type == VAL)
+ return chkcond(checkval, curitem);
+ else if (curitem->val == (int4) '!')
+ {
+ return (calcnot) ?
+ ((TS_execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true)
+ : true;
+ }
+ else if (curitem->val == (int4) '&')
+ {
+ if (TS_execute(curitem + curitem->left, checkval, calcnot, chkcond))
+ return TS_execute(curitem + 1, checkval, calcnot, chkcond);
+ else
+ return false;
+ }
+ else
+ { /* |-operator */
+ if (TS_execute(curitem + curitem->left, checkval, calcnot, chkcond))
+ return true;
+ else
+ return TS_execute(curitem + 1, checkval, calcnot, chkcond);
+ }
+ return false;
+}
+
+/*
+ * boolean operations
+ */
+Datum
+ts_match_qv(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_DATUM(DirectFunctionCall2(ts_match_vq,
+ PG_GETARG_DATUM(1),
+ PG_GETARG_DATUM(0)));
+}
+
+Datum
+ts_match_vq(PG_FUNCTION_ARGS)
+{
+ TSVector val = PG_GETARG_TSVECTOR(0);
+ TSQuery query = PG_GETARG_TSQUERY(1);
+ CHKVAL chkval;
+ bool result;
+
+ if (!val->size || !query->size)
+ {
+ PG_FREE_IF_COPY(val, 0);
+ PG_FREE_IF_COPY(query, 1);
+ PG_RETURN_BOOL(false);
+ }
+
+ chkval.arrb = ARRPTR(val);
+ chkval.arre = chkval.arrb + val->size;
+ chkval.values = STRPTR(val);
+ chkval.operand = GETOPERAND(query);
+ result = TS_execute(
+ GETQUERY(query),
+ &chkval,
+ true,
+ checkcondition_str
+ );
+
+ PG_FREE_IF_COPY(val, 0);
+ PG_FREE_IF_COPY(query, 1);
+ PG_RETURN_BOOL(result);
+}
+
+Datum
+ts_match_tt(PG_FUNCTION_ARGS)
+{
+ TSVector vector;
+ TSQuery query;
+ bool res;
+
+ vector = DatumGetTSVector(DirectFunctionCall1(to_tsvector,
+ PG_GETARG_DATUM(0)));
+ query = DatumGetTSQuery(DirectFunctionCall1(plainto_tsquery,
+ PG_GETARG_DATUM(1)));
+
+ res = DatumGetBool(DirectFunctionCall2(ts_match_vq,
+ TSVectorGetDatum(vector),
+ TSQueryGetDatum(query)));
+
+ pfree(vector);
+ pfree(query);
+
+ PG_RETURN_BOOL(res);
+}
+
+Datum
+ts_match_tq(PG_FUNCTION_ARGS)
+{
+ TSVector vector;
+ TSQuery query = PG_GETARG_TSQUERY(1);
+ bool res;
+
+ vector = DatumGetTSVector(DirectFunctionCall1(to_tsvector,
+ PG_GETARG_DATUM(0)));
+
+ res = DatumGetBool(DirectFunctionCall2(ts_match_vq,
+ TSVectorGetDatum(vector),
+ TSQueryGetDatum(query)));
+
+ pfree(vector);
+ PG_FREE_IF_COPY(query, 1);
+
+ PG_RETURN_BOOL(res);
+}
+
+/*
+ * Statistics of tsvector
+ */
+static int
+check_weight(TSVector txt, WordEntry * wptr, int8 weight)
+{
+ int len = POSDATALEN(txt, wptr);
+ int num = 0;
+ WordEntryPos *ptr = POSDATAPTR(txt, wptr);
+
+ while (len--)
+ {
+ if (weight & (1 << WEP_GETWEIGHT(*ptr)))
+ num++;
+ ptr++;
+ }
+ return num;
+}
+
+static WordEntry **
+SEI_realloc(WordEntry ** in, uint32 *len)
+{
+ if (*len == 0 || in == NULL)
+ {
+ *len = 8;
+ in = palloc(sizeof(WordEntry *) * (*len));
+ }
+ else
+ {
+ *len *= 2;
+ in = repalloc(in, sizeof(WordEntry *) * (*len));
+ }
+ return in;
+}
+
+static int
+compareStatWord(StatEntry * a, WordEntry * b, tsstat * stat, TSVector txt)
+{
+ if (a->len == b->len)
+ return strncmp(
+ STATSTRPTR(stat) + a->pos,
+ STRPTR(txt) + b->pos,
+ a->len
+ );
+ return (a->len > b->len) ? 1 : -1;
+}
+
+static tsstat *
+formstat(tsstat * stat, TSVector txt, WordEntry ** entry, uint32 len)
+{
+ tsstat *newstat;
+ uint32 totallen,
+ nentry;
+ uint32 slen = 0;
+ WordEntry **ptr = entry;
+ char *curptr;
+ StatEntry *sptr,
+ *nptr;
+
+ while (ptr - entry < len)
+ {
+ slen += (*ptr)->len;
+ ptr++;
+ }
+
+ nentry = stat->size + len;
+ slen += STATSTRSIZE(stat);
+ totallen = CALCSTATSIZE(nentry, slen);
+ newstat = palloc(totallen);
+ SET_VARSIZE(newstat, totallen);
+ newstat->weight = stat->weight;
+ newstat->size = nentry;
+
+ memcpy(STATSTRPTR(newstat), STATSTRPTR(stat), STATSTRSIZE(stat));
+ curptr = STATSTRPTR(newstat) + STATSTRSIZE(stat);
+
+ ptr = entry;
+ sptr = STATPTR(stat);
+ nptr = STATPTR(newstat);
+
+ if (len == 1)
+ {
+ StatEntry *StopLow = STATPTR(stat);
+ StatEntry *StopHigh = (StatEntry *) STATSTRPTR(stat);
+
+ while (StopLow < StopHigh)
+ {
+ sptr = StopLow + (StopHigh - StopLow) / 2;
+ if (compareStatWord(sptr, *ptr, stat, txt) < 0)
+ StopLow = sptr + 1;
+ else
+ StopHigh = sptr;
+ }
+ nptr = STATPTR(newstat) + (StopLow - STATPTR(stat));
+ memcpy(STATPTR(newstat), STATPTR(stat), sizeof(StatEntry) * (StopLow - STATPTR(stat)));
+ if ((*ptr)->haspos)
+ nptr->nentry = (stat->weight) ? check_weight(txt, *ptr, stat->weight) : POSDATALEN(txt, *ptr);
+ else
+ nptr->nentry = 1;
+ nptr->ndoc = 1;
+ nptr->len = (*ptr)->len;
+ memcpy(curptr, STRPTR(txt) + (*ptr)->pos, nptr->len);
+ nptr->pos = curptr - STATSTRPTR(newstat);
+ memcpy(nptr + 1, StopLow, sizeof(StatEntry) * (((StatEntry *) STATSTRPTR(stat)) - StopLow));
+ }
+ else
+ {
+ while (sptr - STATPTR(stat) < stat->size && ptr - entry < len)
+ {
+ if (compareStatWord(sptr, *ptr, stat, txt) < 0)
+ {
+ memcpy(nptr, sptr, sizeof(StatEntry));
+ sptr++;
+ }
+ else
+ {
+ if ((*ptr)->haspos)
+ nptr->nentry = (stat->weight) ? check_weight(txt, *ptr, stat->weight) : POSDATALEN(txt, *ptr);
+ else
+ nptr->nentry = 1;
+ nptr->ndoc = 1;
+ nptr->len = (*ptr)->len;
+ memcpy(curptr, STRPTR(txt) + (*ptr)->pos, nptr->len);
+ nptr->pos = curptr - STATSTRPTR(newstat);
+ curptr += nptr->len;
+ ptr++;
+ }
+ nptr++;
+ }
+
+ memcpy(nptr, sptr, sizeof(StatEntry) * (stat->size - (sptr - STATPTR(stat))));
+
+ while (ptr - entry < len)
+ {
+ if ((*ptr)->haspos)
+ nptr->nentry = (stat->weight) ? check_weight(txt, *ptr, stat->weight) : POSDATALEN(txt, *ptr);
+ else
+ nptr->nentry = 1;
+ nptr->ndoc = 1;
+ nptr->len = (*ptr)->len;
+ memcpy(curptr, STRPTR(txt) + (*ptr)->pos, nptr->len);
+ nptr->pos = curptr - STATSTRPTR(newstat);
+ curptr += nptr->len;
+ ptr++;
+ nptr++;
+ }
+ }
+
+ return newstat;
+}
+
+static tsstat *
+ts_accum(tsstat * stat, Datum data)
+{
+ tsstat *newstat;
+ TSVector txt = DatumGetTSVector(data);
+ WordEntry **newentry = NULL;
+ uint32 len = 0,
+ cur = 0;
+ StatEntry *sptr;
+ WordEntry *wptr;
+ int n = 0;
+
+ if (stat == NULL)
+ { /* Init in first */
+ stat = palloc(STATHDRSIZE);
+ SET_VARSIZE(stat, STATHDRSIZE);
+ stat->size = 0;
+ stat->weight = 0;
+ }
+
+ /* simple check of correctness */
+ if (txt == NULL || txt->size == 0)
+ {
+ if (txt != (TSVector) DatumGetPointer(data))
+ pfree(txt);
+ return stat;
+ }
+
+ sptr = STATPTR(stat);
+ wptr = ARRPTR(txt);
+
+ if (stat->size < 100 * txt->size)
+ { /* merge */
+ while (sptr - STATPTR(stat) < stat->size && wptr - ARRPTR(txt) < txt->size)
+ {
+ int cmp = compareStatWord(sptr, wptr, stat, txt);
+
+ if (cmp < 0)
+ sptr++;
+ else if (cmp == 0)
+ {
+ if (stat->weight == 0)
+ {
+ sptr->ndoc++;
+ sptr->nentry += (wptr->haspos) ? POSDATALEN(txt, wptr) : 1;
+ }
+ else if (wptr->haspos && (n = check_weight(txt, wptr, stat->weight)) != 0)
+ {
+ sptr->ndoc++;
+ sptr->nentry += n;
+ }
+ sptr++;
+ wptr++;
+ }
+ else
+ {
+ if (stat->weight == 0 || check_weight(txt, wptr, stat->weight) != 0)
+ {
+ if (cur == len)
+ newentry = SEI_realloc(newentry, &len);
+ newentry[cur] = wptr;
+ cur++;
+ }
+ wptr++;
+ }
+ }
+
+ while (wptr - ARRPTR(txt) < txt->size)
+ {
+ if (stat->weight == 0 || check_weight(txt, wptr, stat->weight) != 0)
+ {
+ if (cur == len)
+ newentry = SEI_realloc(newentry, &len);
+ newentry[cur] = wptr;
+ cur++;
+ }
+ wptr++;
+ }
+ }
+ else
+ { /* search */
+ while (wptr - ARRPTR(txt) < txt->size)
+ {
+ StatEntry *StopLow = STATPTR(stat);
+ StatEntry *StopHigh = (StatEntry *) STATSTRPTR(stat);
+ int cmp;
+
+ while (StopLow < StopHigh)
+ {
+ sptr = StopLow + (StopHigh - StopLow) / 2;
+ cmp = compareStatWord(sptr, wptr, stat, txt);
+ if (cmp == 0)
+ {
+ if (stat->weight == 0)
+ {
+ sptr->ndoc++;
+ sptr->nentry += (wptr->haspos) ? POSDATALEN(txt, wptr) : 1;
+ }
+ else if (wptr->haspos && (n = check_weight(txt, wptr, stat->weight)) != 0)
+ {
+ sptr->ndoc++;
+ sptr->nentry += n;
+ }
+ break;
+ }
+ else if (cmp < 0)
+ StopLow = sptr + 1;
+ else
+ StopHigh = sptr;
+ }
+
+ if (StopLow >= StopHigh)
+ { /* not found */
+ if (stat->weight == 0 || check_weight(txt, wptr, stat->weight) != 0)
+ {
+ if (cur == len)
+ newentry = SEI_realloc(newentry, &len);
+ newentry[cur] = wptr;
+ cur++;
+ }
+ }
+ wptr++;
+ }
+ }
+
+
+ if (cur == 0)
+ { /* no new words */
+ if (txt != (TSVector) DatumGetPointer(data))
+ pfree(txt);
+ return stat;
+ }
+
+ newstat = formstat(stat, txt, newentry, cur);
+ pfree(newentry);
+
+ if (txt != (TSVector) DatumGetPointer(data))
+ pfree(txt);
+ return newstat;
+}
+
+static void
+ts_setup_firstcall(FunctionCallInfo fcinfo, FuncCallContext *funcctx,
+ tsstat * stat)
+{
+ TupleDesc tupdesc;
+ MemoryContext oldcontext;
+ StatStorage *st;
+
+ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+ st = palloc(sizeof(StatStorage));
+ st->cur = 0;
+ st->stat = palloc(VARSIZE(stat));
+ memcpy(st->stat, stat, VARSIZE(stat));
+ funcctx->user_fctx = (void *) st;
+
+ tupdesc = CreateTemplateTupleDesc(3, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 2, "ndoc",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 3, "nentry",
+ INT4OID, -1, 0);
+ funcctx->tuple_desc = BlessTupleDesc(tupdesc);
+ funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
+
+ MemoryContextSwitchTo(oldcontext);
+}
+
+
+static Datum
+ts_process_call(FuncCallContext *funcctx)
+{
+ StatStorage *st;
+
+ st = (StatStorage *) funcctx->user_fctx;
+
+ if (st->cur < st->stat->size)
+ {
+ Datum result;
+ char *values[3];
+ char ndoc[16];
+ char nentry[16];
+ StatEntry *entry = STATPTR(st->stat) + st->cur;
+ HeapTuple tuple;
+
+ values[0] = palloc(entry->len + 1);
+ memcpy(values[0], STATSTRPTR(st->stat) + entry->pos, entry->len);
+ (values[0])[entry->len] = '\0';
+ sprintf(ndoc, "%d", entry->ndoc);
+ values[1] = ndoc;
+ sprintf(nentry, "%d", entry->nentry);
+ values[2] = nentry;
+
+ tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
+ result = HeapTupleGetDatum(tuple);
+
+ pfree(values[0]);
+ st->cur++;
+ return result;
+ }
+ else
+ {
+ pfree(st->stat);
+ pfree(st);
+ }
+
+ return (Datum) 0;
+}
+
+static tsstat *
+ts_stat_sql(text *txt, text *ws)
+{
+ char *query = TextPGetCString(txt);
+ int i;
+ tsstat *newstat,
+ *stat;
+ bool isnull;
+ Portal portal;
+ void *plan;
+
+ if ((plan = SPI_prepare(query, 0, NULL)) == NULL)
+ /* internal error */
+ elog(ERROR, "SPI_prepare(\"%s\") failed", query);
+
+ if ((portal = SPI_cursor_open(NULL, plan, NULL, NULL, false)) == NULL)
+ /* internal error */
+ elog(ERROR, "SPI_cursor_open(\"%s\") failed", query);
+
+ SPI_cursor_fetch(portal, true, 100);
+
+ if (SPI_tuptable->tupdesc->natts != 1 ||
+ SPI_gettypeid(SPI_tuptable->tupdesc, 1) != TSVECTOROID)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("ts_stat query must return one tsvector column")));
+
+ stat = palloc(STATHDRSIZE);
+ SET_VARSIZE(stat, STATHDRSIZE);
+ stat->size = 0;
+ stat->weight = 0;
+
+ if (ws)
+ {
+ char *buf;
+
+ buf = VARDATA(ws);
+ while (buf - VARDATA(ws) < VARSIZE(ws) - VARHDRSZ)
+ {
+ if (pg_mblen(buf) == 1)
+ {
+ switch (*buf)
+ {
+ case 'A':
+ case 'a':
+ stat->weight |= 1 << 3;
+ break;
+ case 'B':
+ case 'b':
+ stat->weight |= 1 << 2;
+ break;
+ case 'C':
+ case 'c':
+ stat->weight |= 1 << 1;
+ break;
+ case 'D':
+ case 'd':
+ stat->weight |= 1;
+ break;
+ default:
+ stat->weight |= 0;
+ }
+ }
+ buf += pg_mblen(buf);
+ }
+ }
+
+ while (SPI_processed > 0)
+ {
+ for (i = 0; i < SPI_processed; i++)
+ {
+ Datum data = SPI_getbinval(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1, &isnull);
+
+ if (!isnull)
+ {
+ newstat = ts_accum(stat, data);
+ if (stat != newstat && stat)
+ pfree(stat);
+ stat = newstat;
+ }
+ }
+
+ SPI_freetuptable(SPI_tuptable);
+ SPI_cursor_fetch(portal, true, 100);
+ }
+
+ SPI_freetuptable(SPI_tuptable);
+ SPI_cursor_close(portal);
+ SPI_freeplan(plan);
+ pfree(query);
+
+ return stat;
+}
+
+Datum
+ts_stat1(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ Datum result;
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ tsstat *stat;
+ text *txt = PG_GETARG_TEXT_P(0);
+
+ funcctx = SRF_FIRSTCALL_INIT();
+ SPI_connect();
+ stat = ts_stat_sql(txt, NULL);
+ PG_FREE_IF_COPY(txt, 0);
+ ts_setup_firstcall(fcinfo, funcctx, stat);
+ SPI_finish();
+ }
+
+ funcctx = SRF_PERCALL_SETUP();
+ if ((result = ts_process_call(funcctx)) != (Datum) 0)
+ SRF_RETURN_NEXT(funcctx, result);
+ SRF_RETURN_DONE(funcctx);
+}
+
+Datum
+ts_stat2(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ Datum result;
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ tsstat *stat;
+ text *txt = PG_GETARG_TEXT_P(0);
+ text *ws = PG_GETARG_TEXT_P(1);
+
+ funcctx = SRF_FIRSTCALL_INIT();
+ SPI_connect();
+ stat = ts_stat_sql(txt, ws);
+ PG_FREE_IF_COPY(txt, 0);
+ PG_FREE_IF_COPY(ws, 1);
+ ts_setup_firstcall(fcinfo, funcctx, stat);
+ SPI_finish();
+ }
+
+ funcctx = SRF_PERCALL_SETUP();
+ if ((result = ts_process_call(funcctx)) != (Datum) 0)
+ SRF_RETURN_NEXT(funcctx, result);
+ SRF_RETURN_DONE(funcctx);
+}
+
+
+/* Check if datatype is TEXT or binary-equivalent to it */
+static bool
+istexttype(Oid typid)
+{
+ /* varchar(n) and char(n) are binary-compatible with text */
+ if (typid==TEXTOID || typid==VARCHAROID || typid==BPCHAROID)
+ return true;
+ /* Allow domains over these types, too */
+ typid = getBaseType(typid);
+ if (typid==TEXTOID || typid==VARCHAROID || typid==BPCHAROID)
+ return true;
+ return false;
+}
+
+
+/*
+ * Triggers for automatic update of a tsvector column from text column(s)
+ *
+ * Trigger arguments are either
+ * name of tsvector col, name of tsconfig to use, name(s) of text col(s)
+ * name of tsvector col, name of regconfig col, name(s) of text col(s)
+ * ie, tsconfig can either be specified by name, or indirectly as the
+ * contents of a regconfig field in the row. If the name is used, it must
+ * be explicitly schema-qualified.
+ */
+Datum
+tsvector_update_trigger_byid(PG_FUNCTION_ARGS)
+{
+ return tsvector_update_trigger(fcinfo, false);
+}
+
+Datum
+tsvector_update_trigger_bycolumn(PG_FUNCTION_ARGS)
+{
+ return tsvector_update_trigger(fcinfo, true);
+}
+
+static Datum
+tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column)
+{
+ TriggerData *trigdata;
+ Trigger *trigger;
+ Relation rel;
+ HeapTuple rettuple = NULL;
+ int tsvector_attr_num,
+ i;
+ ParsedText prs;
+ Datum datum;
+ bool isnull;
+ text *txt;
+ Oid cfgId;
+
+ /* Check call context */
+ if (!CALLED_AS_TRIGGER(fcinfo)) /* internal error */
+ elog(ERROR, "tsvector_update_trigger: not fired by trigger manager");
+
+ trigdata = (TriggerData *) fcinfo->context;
+ if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+ elog(ERROR, "tsvector_update_trigger: can't process STATEMENT events");
+ if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+ elog(ERROR, "tsvector_update_trigger: must be fired BEFORE event");
+
+ if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
+ rettuple = trigdata->tg_trigtuple;
+ else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ rettuple = trigdata->tg_newtuple;
+ else
+ elog(ERROR, "tsvector_update_trigger: must be fired for INSERT or UPDATE");
+
+ trigger = trigdata->tg_trigger;
+ rel = trigdata->tg_relation;
+
+ if (trigger->tgnargs < 3)
+ elog(ERROR, "tsvector_update_trigger: arguments must be tsvector_field, ts_config, text_field1, ...)");
+
+ /* Find the target tsvector column */
+ tsvector_attr_num = SPI_fnumber(rel->rd_att, trigger->tgargs[0]);
+ if (tsvector_attr_num == SPI_ERROR_NOATTRIBUTE)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("tsvector column \"%s\" does not exist",
+ trigger->tgargs[0])));
+ if (SPI_gettypeid(rel->rd_att, tsvector_attr_num) != TSVECTOROID)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("column \"%s\" is not of tsvector type",
+ trigger->tgargs[0])));
+
+ /* Find the configuration to use */
+ if (config_column)
+ {
+ int config_attr_num;
+
+ config_attr_num = SPI_fnumber(rel->rd_att, trigger->tgargs[1]);
+ if (config_attr_num == SPI_ERROR_NOATTRIBUTE)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("config column \"%s\" does not exist",
+ trigger->tgargs[1])));
+ if (SPI_gettypeid(rel->rd_att, config_attr_num) != REGCONFIGOID)
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("column \"%s\" is not of regconfig type",
+ trigger->tgargs[1])));
+
+ datum = SPI_getbinval(rettuple, rel->rd_att, config_attr_num, &isnull);
+ if (isnull)
+ ereport(ERROR,
+ (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
+ errmsg("config column \"%s\" must not be NULL",
+ trigger->tgargs[1])));
+ cfgId = DatumGetObjectId(datum);
+ }
+ else
+ {
+ List *names;
+
+ names = stringToQualifiedNameList(trigger->tgargs[1]);
+ /* require a schema so that results are not search path dependent */
+ if (list_length(names) < 2)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("text search configuration name \"%s\" must be schema-qualified",
+ trigger->tgargs[1])));
+ cfgId = TSConfigGetCfgid(names, false);
+ }
+
+ /* initialize parse state */
+ prs.lenwords = 32;
+ prs.curwords = 0;
+ prs.pos = 0;
+ prs.words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs.lenwords);
+
+ /* find all words in indexable column(s) */
+ for (i = 2; i < trigger->tgnargs; i++)
+ {
+ int numattr;
+
+ numattr = SPI_fnumber(rel->rd_att, trigger->tgargs[i]);
+ if (numattr == SPI_ERROR_NOATTRIBUTE)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("column \"%s\" does not exist",
+ trigger->tgargs[i])));
+ if (!istexttype(SPI_gettypeid(rel->rd_att, numattr)))
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("column \"%s\" is not of character type",
+ trigger->tgargs[i])));
+
+ datum = SPI_getbinval(rettuple, rel->rd_att, numattr, &isnull);
+ if (isnull)
+ continue;
+
+ txt = DatumGetTextP(datum);
+
+ parsetext(cfgId, &prs, VARDATA(txt), VARSIZE(txt) - VARHDRSZ);
+
+ if (txt != (text *) DatumGetPointer(datum))
+ pfree(txt);
+ }
+
+ /* make tsvector value */
+ if (prs.curwords)
+ {
+ datum = PointerGetDatum(make_tsvector(&prs));
+ rettuple = SPI_modifytuple(rel, rettuple, 1, &tsvector_attr_num,
+ &datum, NULL);
+ pfree(DatumGetPointer(datum));
+ }
+ else
+ {
+ TSVector out = palloc(CALCDATASIZE(0, 0));
+
+ SET_VARSIZE(out, CALCDATASIZE(0, 0));
+ out->size = 0;
+ datum = PointerGetDatum(out);
+ rettuple = SPI_modifytuple(rel, rettuple, 1, &tsvector_attr_num,
+ &datum, NULL);
+ pfree(prs.words);
+ }
+
+ if (rettuple == NULL) /* internal error */
+ elog(ERROR, "tsvector_update_trigger: %d returned by SPI_modifytuple",
+ SPI_result);
+
+ return PointerGetDatum(rettuple);
+}
diff --git a/src/backend/utils/cache/Makefile b/src/backend/utils/cache/Makefile
index 879f013e335..7ad1cda6c73 100644
--- a/src/backend/utils/cache/Makefile
+++ b/src/backend/utils/cache/Makefile
@@ -4,7 +4,7 @@
# Makefile for utils/cache
#
# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.21 2007/03/13 00:33:42 tgl Exp $
+# $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.22 2007/08/21 01:11:19 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -13,7 +13,7 @@ top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
OBJS = catcache.o inval.o plancache.o relcache.o \
- syscache.o lsyscache.o typcache.o
+ syscache.o lsyscache.o typcache.o ts_cache.o
all: SUBSYS.o
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 13771c77ebc..9413d5ad36e 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.137 2007/04/21 04:49:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.138 2007/08/21 01:11:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -134,6 +134,8 @@ GetCCHashEqFuncs(Oid keytype, PGFunction *hashfunc, RegProcedure *eqfunc)
case REGOPERATOROID:
case REGCLASSOID:
case REGTYPEOID:
+ case REGCONFIGOID:
+ case REGDICTIONARYOID:
*hashfunc = hashoid;
*eqfunc = F_OIDEQ;
break;
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 2d52b4299b7..db72857b73d 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.112 2007/04/02 03:49:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.113 2007/08/21 01:11:19 tgl Exp $
*
* NOTES
* These routines allow the parser/planner/executor to perform
@@ -40,6 +40,11 @@
#include "catalog/pg_proc.h"
#include "catalog/pg_rewrite.h"
#include "catalog/pg_statistic.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_config_map.h"
+#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "utils/syscache.h"
@@ -540,6 +545,114 @@ static const struct cachedesc cacheinfo[] = {
},
1024
},
+ {TSConfigMapRelationId, /* TSCONFIGMAP */
+ TSConfigMapIndexId,
+ 0,
+ 3,
+ {
+ Anum_pg_ts_config_map_mapcfg,
+ Anum_pg_ts_config_map_maptokentype,
+ Anum_pg_ts_config_map_mapseqno,
+ 0
+ },
+ 4
+ },
+ {TSConfigRelationId, /* TSCONFIGNAMENSP */
+ TSConfigNameNspIndexId,
+ 0,
+ 2,
+ {
+ Anum_pg_ts_config_cfgname,
+ Anum_pg_ts_config_cfgnamespace,
+ 0,
+ 0
+ },
+ 16
+ },
+ {TSConfigRelationId, /* TSCONFIGOID */
+ TSConfigOidIndexId,
+ 0,
+ 1,
+ {
+ ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0
+ },
+ 16
+ },
+ {TSDictionaryRelationId, /* TSDICTNAMENSP */
+ TSDictionaryNameNspIndexId,
+ 0,
+ 2,
+ {
+ Anum_pg_ts_dict_dictname,
+ Anum_pg_ts_dict_dictnamespace,
+ 0,
+ 0
+ },
+ 16
+ },
+ {TSDictionaryRelationId, /* TSDICTOID */
+ TSDictionaryOidIndexId,
+ 0,
+ 1,
+ {
+ ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0
+ },
+ 16
+ },
+ {TSParserRelationId, /* TSPARSERNAMENSP */
+ TSParserNameNspIndexId,
+ 0,
+ 2,
+ {
+ Anum_pg_ts_parser_prsname,
+ Anum_pg_ts_parser_prsnamespace,
+ 0,
+ 0
+ },
+ 4
+ },
+ {TSParserRelationId, /* TSPARSEROID */
+ TSParserOidIndexId,
+ 0,
+ 1,
+ {
+ ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0
+ },
+ 4
+ },
+ {TSTemplateRelationId, /* TSTEMPLATENAMENSP */
+ TSTemplateNameNspIndexId,
+ 0,
+ 2,
+ {
+ Anum_pg_ts_template_tmplname,
+ Anum_pg_ts_template_tmplnamespace,
+ 0,
+ 0
+ },
+ 16
+ },
+ {TSTemplateRelationId, /* TSTEMPLATEOID */
+ TSTemplateOidIndexId,
+ 0,
+ 1,
+ {
+ ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0
+ },
+ 16
+ },
{TypeRelationId, /* TYPENAMENSP */
TypeNameNspIndexId,
Anum_pg_type_typrelid,
diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c
new file mode 100644
index 00000000000..cd3a9dad571
--- /dev/null
+++ b/src/backend/utils/cache/ts_cache.c
@@ -0,0 +1,641 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_cache.c
+ * Tsearch related object caches.
+ *
+ * Tsearch performance is very sensitive to performance of parsers,
+ * dictionaries and mapping, so lookups should be cached as much
+ * as possible.
+ *
+ * Once a backend has created a cache entry for a particular TS object OID,
+ * the cache entry will exist for the life of the backend; hence it is
+ * safe to hold onto a pointer to the cache entry while doing things that
+ * might result in recognizing a cache invalidation. Beware however that
+ * subsidiary information might be deleted and reallocated somewhere else
+ * if a cache inval and reval happens! This does not look like it will be
+ * a big problem as long as parser and dictionary methods do not attempt
+ * any database access.
+ *
+ *
+ * Copyright (c) 2006-2007, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * $PostgreSQL: pgsql/src/backend/utils/cache/ts_cache.c,v 1.1 2007/08/21 01:11:19 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/genam.h"
+#include "access/heapam.h"
+#include "access/xact.h"
+#include "catalog/indexing.h"
+#include "catalog/namespace.h"
+#include "catalog/pg_ts_config.h"
+#include "catalog/pg_ts_config_map.h"
+#include "catalog/pg_ts_dict.h"
+#include "catalog/pg_ts_parser.h"
+#include "catalog/pg_ts_template.h"
+#include "catalog/pg_type.h"
+#include "miscadmin.h"
+#include "tsearch/ts_cache.h"
+#include "tsearch/ts_utils.h"
+#include "utils/array.h"
+#include "utils/builtins.h"
+#include "utils/catcache.h"
+#include "utils/fmgroids.h"
+#include "utils/inval.h"
+#include "utils/lsyscache.h"
+#include "utils/memutils.h"
+#include "utils/syscache.h"
+
+
+/*
+ * MAXTOKENTYPE/MAXDICTSPERTT are arbitrary limits on the workspace size
+ * used in lookup_ts_config_cache(). We could avoid hardwiring a limit
+ * by making the workspace dynamically enlargeable, but it seems unlikely
+ * to be worth the trouble.
+ */
+#define MAXTOKENTYPE 256
+#define MAXDICTSPERTT 100
+
+
+static HTAB *TSParserCacheHash = NULL;
+static TSParserCacheEntry *lastUsedParser = NULL;
+
+static HTAB *TSDictionaryCacheHash = NULL;
+static TSDictionaryCacheEntry *lastUsedDictionary = NULL;
+
+static HTAB *TSConfigCacheHash = NULL;
+static TSConfigCacheEntry *lastUsedConfig = NULL;
+
+/*
+ * GUC default_text_search_config, and a cache of the current config's OID
+ */
+char *TSCurrentConfig = NULL;
+
+static Oid TSCurrentConfigCache = InvalidOid;
+
+
+/*
+ * We use this catcache callback to detect when a visible change to a TS
+ * catalog entry has been made, by either our own backend or another one.
+ * We don't get enough information to know *which* specific catalog row
+ * changed, so we have to invalidate all related cache entries. Fortunately,
+ * it seems unlikely that TS configuration changes will occur often enough
+ * for this to be a performance problem.
+ *
+ * We can use the same function for all TS caches by passing the hash
+ * table address as the "arg".
+ */
+static void
+InvalidateTSCacheCallBack(Datum arg, Oid relid)
+{
+ HTAB *hash = (HTAB *) DatumGetPointer(arg);
+ HASH_SEQ_STATUS status;
+ TSAnyCacheEntry *entry;
+
+ hash_seq_init(&status, hash);
+ while ((entry = (TSAnyCacheEntry *) hash_seq_search(&status)) != NULL)
+ entry->isvalid = false;
+
+ /* Also invalidate the current-config cache if it's pg_ts_config */
+ if (hash == TSConfigCacheHash)
+ TSCurrentConfigCache = InvalidOid;
+}
+
+/*
+ * Fetch parser cache entry
+ */
+TSParserCacheEntry *
+lookup_ts_parser_cache(Oid prsId)
+{
+ TSParserCacheEntry *entry;
+
+ if (TSParserCacheHash == NULL)
+ {
+ /* First time through: initialize the hash table */
+ HASHCTL ctl;
+
+ if (!CacheMemoryContext)
+ CreateCacheMemoryContext();
+
+ MemSet(&ctl, 0, sizeof(ctl));
+ ctl.keysize = sizeof(Oid);
+ ctl.entrysize = sizeof(TSParserCacheEntry);
+ ctl.hash = oid_hash;
+ TSParserCacheHash = hash_create("Tsearch parser cache", 4,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
+ /* Flush cache on pg_ts_parser changes */
+ CacheRegisterSyscacheCallback(TSPARSEROID, InvalidateTSCacheCallBack,
+ PointerGetDatum(TSParserCacheHash));
+ }
+
+ /* Check single-entry cache */
+ if (lastUsedParser && lastUsedParser->prsId == prsId &&
+ lastUsedParser->isvalid)
+ return lastUsedParser;
+
+ /* Try to look up an existing entry */
+ entry = (TSParserCacheEntry *) hash_search(TSParserCacheHash,
+ (void *) &prsId,
+ HASH_FIND, NULL);
+ if (entry == NULL || !entry->isvalid)
+ {
+ /*
+ * If we didn't find one, we want to make one.
+ * But first look up the object to be sure the OID is real.
+ */
+ HeapTuple tp;
+ Form_pg_ts_parser prs;
+
+ tp = SearchSysCache(TSPARSEROID,
+ ObjectIdGetDatum(prsId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for text search parser %u",
+ prsId);
+ prs = (Form_pg_ts_parser) GETSTRUCT(tp);
+
+ /*
+ * Sanity checks
+ */
+ if (!OidIsValid(prs->prsstart))
+ elog(ERROR, "text search parser %u has no prsstart method", prsId);
+ if (!OidIsValid(prs->prstoken))
+ elog(ERROR, "text search parser %u has no prstoken method", prsId);
+ if (!OidIsValid(prs->prsend))
+ elog(ERROR, "text search parser %u has no prsend method", prsId);
+
+ if (entry == NULL)
+ {
+ bool found;
+
+ /* Now make the cache entry */
+ entry = (TSParserCacheEntry *)
+ hash_search(TSParserCacheHash,
+ (void *) &prsId,
+ HASH_ENTER, &found);
+ Assert(!found); /* it wasn't there a moment ago */
+ }
+
+ MemSet(entry, 0, sizeof(TSParserCacheEntry));
+ entry->prsId = prsId;
+ entry->startOid = prs->prsstart;
+ entry->tokenOid = prs->prstoken;
+ entry->endOid = prs->prsend;
+ entry->headlineOid = prs->prsheadline;
+ entry->lextypeOid = prs->prslextype;
+
+ ReleaseSysCache(tp);
+
+ fmgr_info_cxt(entry->startOid, &entry->prsstart, CacheMemoryContext);
+ fmgr_info_cxt(entry->tokenOid, &entry->prstoken, CacheMemoryContext);
+ fmgr_info_cxt(entry->endOid, &entry->prsend, CacheMemoryContext);
+ if (OidIsValid(entry->headlineOid))
+ fmgr_info_cxt(entry->headlineOid, &entry->prsheadline,
+ CacheMemoryContext);
+
+ entry->isvalid = true;
+ }
+
+ lastUsedParser = entry;
+
+ return entry;
+}
+
+/*
+ * Fetch dictionary cache entry
+ */
+TSDictionaryCacheEntry *
+lookup_ts_dictionary_cache(Oid dictId)
+{
+ TSDictionaryCacheEntry *entry;
+
+ if (TSDictionaryCacheHash == NULL)
+ {
+ /* First time through: initialize the hash table */
+ HASHCTL ctl;
+
+ if (!CacheMemoryContext)
+ CreateCacheMemoryContext();
+
+ MemSet(&ctl, 0, sizeof(ctl));
+ ctl.keysize = sizeof(Oid);
+ ctl.entrysize = sizeof(TSDictionaryCacheEntry);
+ ctl.hash = oid_hash;
+ TSDictionaryCacheHash = hash_create("Tsearch dictionary cache", 8,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
+ /* Flush cache on pg_ts_dict and pg_ts_template changes */
+ CacheRegisterSyscacheCallback(TSDICTOID, InvalidateTSCacheCallBack,
+ PointerGetDatum(TSDictionaryCacheHash));
+ CacheRegisterSyscacheCallback(TSTEMPLATEOID, InvalidateTSCacheCallBack,
+ PointerGetDatum(TSDictionaryCacheHash));
+ }
+
+ /* Check single-entry cache */
+ if (lastUsedDictionary && lastUsedDictionary->dictId == dictId &&
+ lastUsedDictionary->isvalid)
+ return lastUsedDictionary;
+
+ /* Try to look up an existing entry */
+ entry = (TSDictionaryCacheEntry *) hash_search(TSDictionaryCacheHash,
+ (void *) &dictId,
+ HASH_FIND, NULL);
+ if (entry == NULL || !entry->isvalid)
+ {
+ /*
+ * If we didn't find one, we want to make one.
+ * But first look up the object to be sure the OID is real.
+ */
+ HeapTuple tpdict,
+ tptmpl;
+ Form_pg_ts_dict dict;
+ Form_pg_ts_template template;
+ MemoryContext saveCtx = NULL;
+
+ tpdict = SearchSysCache(TSDICTOID,
+ ObjectIdGetDatum(dictId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tpdict))
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ dictId);
+ dict = (Form_pg_ts_dict) GETSTRUCT(tpdict);
+
+ /*
+ * Sanity checks
+ */
+ if (!OidIsValid(dict->dicttemplate))
+ elog(ERROR, "text search dictionary %u has no template", dictId);
+
+ /*
+ * Retrieve dictionary's template
+ */
+ tptmpl = SearchSysCache(TSTEMPLATEOID,
+ ObjectIdGetDatum(dict->dicttemplate),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tptmpl))
+ elog(ERROR, "cache lookup failed for text search template %u",
+ dict->dicttemplate);
+ template = (Form_pg_ts_template) GETSTRUCT(tptmpl);
+
+ /*
+ * Sanity checks
+ */
+ if (!OidIsValid(template->tmpllexize))
+ elog(ERROR, "text search template %u has no lexize method",
+ template->tmpllexize);
+
+ if (entry == NULL)
+ {
+ bool found;
+
+ /* Now make the cache entry */
+ entry = (TSDictionaryCacheEntry *)
+ hash_search(TSDictionaryCacheHash,
+ (void *) &dictId,
+ HASH_ENTER, &found);
+ Assert(!found); /* it wasn't there a moment ago */
+
+ /* Create private memory context the first time through */
+ saveCtx = AllocSetContextCreate(CacheMemoryContext,
+ NameStr(dict->dictname),
+ ALLOCSET_SMALL_MINSIZE,
+ ALLOCSET_SMALL_INITSIZE,
+ ALLOCSET_SMALL_MAXSIZE);
+ }
+ else
+ {
+ /* Clear the existing entry's private context */
+ saveCtx = entry->dictCtx;
+ MemoryContextResetAndDeleteChildren(saveCtx);
+ }
+
+ MemSet(entry, 0, sizeof(TSDictionaryCacheEntry));
+ entry->dictId = dictId;
+ entry->dictCtx = saveCtx;
+
+ entry->lexizeOid = template->tmpllexize;
+
+ if (OidIsValid(template->tmplinit))
+ {
+ bool isnull;
+ Datum opt;
+
+ opt = SysCacheGetAttr(TSDICTOID, tpdict,
+ Anum_pg_ts_dict_dictinitoption,
+ &isnull);
+ if (isnull)
+ opt = PointerGetDatum(NULL);
+
+ /*
+ * Init method runs in dictionary's private memory context
+ */
+ saveCtx = MemoryContextSwitchTo(entry->dictCtx);
+ entry->dictData = DatumGetPointer(OidFunctionCall1(template->tmplinit, opt));
+ MemoryContextSwitchTo(saveCtx);
+ }
+
+ ReleaseSysCache(tptmpl);
+ ReleaseSysCache(tpdict);
+
+ fmgr_info_cxt(entry->lexizeOid, &entry->lexize, entry->dictCtx);
+
+ entry->isvalid = true;
+ }
+
+ lastUsedDictionary = entry;
+
+ return entry;
+}
+
+/*
+ * Initialize config cache and prepare callbacks. This is split out of
+ * lookup_ts_config_cache because we need to activate the callback before
+ * caching TSCurrentConfigCache, too.
+ */
+static void
+init_ts_config_cache(void)
+{
+ HASHCTL ctl;
+
+ if (!CacheMemoryContext)
+ CreateCacheMemoryContext();
+
+ MemSet(&ctl, 0, sizeof(ctl));
+ ctl.keysize = sizeof(Oid);
+ ctl.entrysize = sizeof(TSConfigCacheEntry);
+ ctl.hash = oid_hash;
+ TSConfigCacheHash = hash_create("Tsearch configuration cache", 16,
+ &ctl, HASH_ELEM | HASH_FUNCTION);
+ /* Flush cache on pg_ts_config and pg_ts_config_map changes */
+ CacheRegisterSyscacheCallback(TSCONFIGOID, InvalidateTSCacheCallBack,
+ PointerGetDatum(TSConfigCacheHash));
+ CacheRegisterSyscacheCallback(TSCONFIGMAP, InvalidateTSCacheCallBack,
+ PointerGetDatum(TSConfigCacheHash));
+}
+
+/*
+ * Fetch configuration cache entry
+ */
+TSConfigCacheEntry *
+lookup_ts_config_cache(Oid cfgId)
+{
+ TSConfigCacheEntry *entry;
+
+ if (TSConfigCacheHash == NULL)
+ {
+ /* First time through: initialize the hash table */
+ init_ts_config_cache();
+ }
+
+ /* Check single-entry cache */
+ if (lastUsedConfig && lastUsedConfig->cfgId == cfgId &&
+ lastUsedConfig->isvalid)
+ return lastUsedConfig;
+
+ /* Try to look up an existing entry */
+ entry = (TSConfigCacheEntry *) hash_search(TSConfigCacheHash,
+ (void *) &cfgId,
+ HASH_FIND, NULL);
+ if (entry == NULL || !entry->isvalid)
+ {
+ /*
+ * If we didn't find one, we want to make one.
+ * But first look up the object to be sure the OID is real.
+ */
+ HeapTuple tp;
+ Form_pg_ts_config cfg;
+ Relation maprel;
+ Relation mapidx;
+ ScanKeyData mapskey;
+ IndexScanDesc mapscan;
+ HeapTuple maptup;
+ ListDictionary maplists[MAXTOKENTYPE + 1];
+ Oid mapdicts[MAXDICTSPERTT];
+ int maxtokentype;
+ int ndicts;
+ int i;
+
+ tp = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(cfgId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ cfgId);
+ cfg = (Form_pg_ts_config) GETSTRUCT(tp);
+
+ /*
+ * Sanity checks
+ */
+ if (!OidIsValid(cfg->cfgparser))
+ elog(ERROR, "text search configuration %u has no parser", cfgId);
+
+ if (entry == NULL)
+ {
+ bool found;
+
+ /* Now make the cache entry */
+ entry = (TSConfigCacheEntry *)
+ hash_search(TSConfigCacheHash,
+ (void *) &cfgId,
+ HASH_ENTER, &found);
+ Assert(!found); /* it wasn't there a moment ago */
+ }
+ else
+ {
+ /* Cleanup old contents */
+ if (entry->map)
+ {
+ for (i = 0; i < entry->lenmap; i++)
+ if (entry->map[i].dictIds)
+ pfree(entry->map[i].dictIds);
+ pfree(entry->map);
+ }
+ }
+
+ MemSet(entry, 0, sizeof(TSConfigCacheEntry));
+ entry->cfgId = cfgId;
+ entry->prsId = cfg->cfgparser;
+
+ ReleaseSysCache(tp);
+
+ /*
+ * Scan pg_ts_config_map to gather dictionary list for each token type
+ *
+ * Because the index is on (mapcfg, maptokentype, mapseqno), we will
+ * see the entries in maptokentype order, and in mapseqno order for
+ * each token type, even though we didn't explicitly ask for that.
+ */
+ MemSet(maplists, 0, sizeof(maplists));
+ maxtokentype = 0;
+ ndicts = 0;
+
+ ScanKeyInit(&mapskey,
+ Anum_pg_ts_config_map_mapcfg,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(cfgId));
+
+ maprel = heap_open(TSConfigMapRelationId, AccessShareLock);
+ mapidx = index_open(TSConfigMapIndexId, AccessShareLock);
+ mapscan = index_beginscan(maprel, mapidx, SnapshotNow, 1, &mapskey);
+
+ while ((maptup = index_getnext(mapscan, ForwardScanDirection)) != NULL)
+ {
+ Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
+ int toktype = cfgmap->maptokentype;
+
+ if (toktype <= 0 || toktype > MAXTOKENTYPE)
+ elog(ERROR, "maptokentype value %d is out of range", toktype);
+ if (toktype < maxtokentype)
+ elog(ERROR, "maptokentype entries are out of order");
+ if (toktype > maxtokentype)
+ {
+ /* starting a new token type, but first save the prior data */
+ if (ndicts > 0)
+ {
+ maplists[maxtokentype].len = ndicts;
+ maplists[maxtokentype].dictIds = (Oid *)
+ MemoryContextAlloc(CacheMemoryContext,
+ sizeof(Oid) * ndicts);
+ memcpy(maplists[maxtokentype].dictIds, mapdicts,
+ sizeof(Oid) * ndicts);
+ }
+ maxtokentype = toktype;
+ mapdicts[0] = cfgmap->mapdict;
+ ndicts = 1;
+ }
+ else
+ {
+ /* continuing data for current token type */
+ if (ndicts >= MAXDICTSPERTT)
+ elog(ERROR, "too many pg_ts_config_map entries for one token type");
+ mapdicts[ndicts++] = cfgmap->mapdict;
+ }
+ }
+
+ index_endscan(mapscan);
+ index_close(mapidx, AccessShareLock);
+ heap_close(maprel, AccessShareLock);
+
+ if (ndicts > 0)
+ {
+ /* save the last token type's dictionaries */
+ maplists[maxtokentype].len = ndicts;
+ maplists[maxtokentype].dictIds = (Oid *)
+ MemoryContextAlloc(CacheMemoryContext,
+ sizeof(Oid) * ndicts);
+ memcpy(maplists[maxtokentype].dictIds, mapdicts,
+ sizeof(Oid) * ndicts);
+ /* and save the overall map */
+ entry->lenmap = maxtokentype + 1;
+ entry->map = (ListDictionary *)
+ MemoryContextAlloc(CacheMemoryContext,
+ sizeof(ListDictionary) * entry->lenmap);
+ memcpy(entry->map, maplists,
+ sizeof(ListDictionary) * entry->lenmap);
+ }
+
+ entry->isvalid = true;
+ }
+
+ lastUsedConfig = entry;
+
+ return entry;
+}
+
+
+/*---------------------------------------------------
+ * GUC variable "default_text_search_config"
+ *---------------------------------------------------
+ */
+
+Oid
+getTSCurrentConfig(bool emitError)
+{
+ /* if we have a cached value, return it */
+ if (OidIsValid(TSCurrentConfigCache))
+ return TSCurrentConfigCache;
+
+ /* fail if GUC hasn't been set up yet */
+ if (TSCurrentConfig == NULL || *TSCurrentConfig == '\0')
+ {
+ if (emitError)
+ elog(ERROR, "text search configuration isn't set");
+ else
+ return InvalidOid;
+ }
+
+ if (TSConfigCacheHash == NULL)
+ {
+ /* First time through: initialize the tsconfig inval callback */
+ init_ts_config_cache();
+ }
+
+ /* Look up the config */
+ TSCurrentConfigCache =
+ TSConfigGetCfgid(stringToQualifiedNameList(TSCurrentConfig),
+ !emitError);
+
+ return TSCurrentConfigCache;
+}
+
+const char *
+assignTSCurrentConfig(const char *newval, bool doit, GucSource source)
+{
+ /* do nothing during initial GUC setup */
+ if (newval == NULL)
+ {
+ if (doit)
+ TSCurrentConfigCache = InvalidOid;
+ return newval;
+ }
+
+ /*
+ * If we aren't inside a transaction, we cannot do database access so
+ * cannot verify the config name. Must accept it on faith.
+ */
+ if (IsTransactionState())
+ {
+ Oid cfgId;
+ HeapTuple tuple;
+ Form_pg_ts_config cfg;
+ char *buf;
+
+ cfgId = TSConfigGetCfgid(stringToQualifiedNameList(newval), true);
+
+ if (!OidIsValid(cfgId))
+ return NULL;
+
+ /*
+ * Modify the actually stored value to be fully qualified, to ensure
+ * later changes of search_path don't affect it.
+ */
+ tuple = SearchSysCache(TSCONFIGOID,
+ ObjectIdGetDatum(cfgId),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tuple))
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ cfgId);
+ cfg = (Form_pg_ts_config) GETSTRUCT(tuple);
+
+ buf = quote_qualified_identifier(get_namespace_name(cfg->cfgnamespace),
+ NameStr(cfg->cfgname));
+
+ ReleaseSysCache(tuple);
+
+ /* GUC wants it malloc'd not palloc'd */
+ newval = strdup(buf);
+ pfree(buf);
+
+ if (doit)
+ TSCurrentConfigCache = cfgId;
+ }
+ else
+ {
+ if (doit)
+ TSCurrentConfigCache = InvalidOid;
+ }
+
+ return newval;
+}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index a05b3be3937..e70768aa840 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.413 2007/08/19 01:41:25 adunstan Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.414 2007/08/21 01:11:19 tgl Exp $
*
*--------------------------------------------------------------------
*/
@@ -25,7 +25,6 @@
#include <syslog.h>
#endif
-
#include "access/gin.h"
#include "access/transam.h"
#include "access/twophase.h"
@@ -58,6 +57,7 @@
#include "storage/fd.h"
#include "storage/freespace.h"
#include "tcop/tcopprot.h"
+#include "tsearch/ts_cache.h"
#include "utils/builtins.h"
#include "utils/guc_tables.h"
#include "utils/memutils.h"
@@ -2240,8 +2240,9 @@ static struct config_string ConfigureNamesString[] =
{
{"log_destination", PGC_SIGHUP, LOGGING_WHERE,
gettext_noop("Sets the destination for server log output."),
- gettext_noop("Valid values are combinations of \"stderr\", \"syslog\", "
- " \"csvlog\" and \"eventlog\", depending on the platform."),
+ gettext_noop("Valid values are combinations of \"stderr\", "
+ "\"syslog\", \"csvlog\", and \"eventlog\", "
+ "depending on the platform."),
GUC_LIST_INPUT
},
&log_destination_string,
@@ -2434,6 +2435,15 @@ static struct config_string ConfigureNamesString[] =
"content", assign_xmloption, NULL
},
+ {
+ {"default_text_search_config", PGC_USERSET, CLIENT_CONN_LOCALE,
+ gettext_noop("Sets default text search configuration."),
+ NULL
+ },
+ &TSCurrentConfig,
+ "pg_catalog.simple", assignTSCurrentConfig, NULL
+ },
+
#ifdef USE_SSL
{
{"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 8720d18c55d..b22099c2fd7 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -448,6 +448,9 @@
#lc_numeric = 'C' # locale for number formatting
#lc_time = 'C' # locale for time formatting
+# default configuration for text search
+#default_text_search_config = 'pg_catalog.simple'
+
# - Other Defaults -
#explain_pretty_print = on
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 4560e77a636..15ac4b7cb2d 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
* Portions taken from FreeBSD.
*
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.139 2007/08/04 21:01:09 neilc Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.140 2007/08/21 01:11:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -88,6 +88,7 @@ static char *lc_monetary = "";
static char *lc_numeric = "";
static char *lc_time = "";
static char *lc_messages = "";
+static const char *default_text_search_config = "";
static char *username = "";
static bool pwprompt = false;
static char *pwfilename = NULL;
@@ -108,6 +109,7 @@ static char *hba_file;
static char *ident_file;
static char *conf_file;
static char *conversion_file;
+static char *dictionary_file;
static char *info_schema_file;
static char *features_file;
static char *system_views_file;
@@ -181,6 +183,7 @@ static void setup_depend(void);
static void setup_sysviews(void);
static void setup_description(void);
static void setup_conversion(void);
+static void setup_dictionary(void);
static void setup_privileges(void);
static void set_info_version(void);
static void setup_schema(void);
@@ -729,7 +732,7 @@ struct encoding_match
const char *system_enc_name;
};
-struct encoding_match encoding_match_list[] = {
+static const struct encoding_match encoding_match_list[] = {
{PG_EUC_JP, "EUC-JP"},
{PG_EUC_JP, "eucJP"},
{PG_EUC_JP, "IBM-eucJP"},
@@ -907,6 +910,94 @@ find_matching_encoding(const char *ctype)
}
#endif /* HAVE_LANGINFO_H && CODESET */
+
+/*
+ * Support for determining the best default text search configuration.
+ * We key this off LC_CTYPE, after stripping its encoding indicator if any.
+ */
+struct tsearch_config_match
+{
+ const char *tsconfname;
+ const char *langname;
+};
+
+static const struct tsearch_config_match tsearch_config_languages[] =
+{
+ {"danish", "da_DK"},
+ {"danish", "Danish_Danmark"},
+ {"dutch", "nl_NL"},
+ {"dutch", "Dutch_Netherlands"},
+ {"english", "C"},
+ {"english", "POSIX"},
+ {"english", "en_US"},
+ {"english", "English_America"},
+ {"english", "en_UK"},
+ {"english", "English_Britain"},
+ {"finnish", "fi_FI"},
+ {"finnish", "Finnish_Finland"},
+ {"french", "fr_FR"},
+ {"french", "French_France"},
+ {"german", "de_DE"},
+ {"german", "German_Germany"},
+ {"hungarian", "hu_HU"},
+ {"hungarian", "Hungarian_Hungary"},
+ {"italian", "it_IT"},
+ {"italian", "Italian_Italy"},
+ {"norwegian", "no_NO"},
+ {"norwegian", "Norwegian_Norway"},
+ {"portuguese", "pt_PT"},
+ {"portuguese", "Portuguese_Portugal"},
+ {"romanian", "ro_RO"},
+ {"russian", "ru_RU"},
+ {"russian", "Russian_Russia"},
+ {"spanish", "es_ES"},
+ {"spanish", "Spanish_Spain"},
+ {"swedish", "sv_SE"},
+ {"swedish", "Swedish_Sweden"},
+ {"turkish", "tr_TR"},
+ {"turkish", "Turkish_Turkey"},
+ {NULL, NULL} /* end marker */
+};
+
+/*
+ * Look for a text search configuration matching lc_ctype, and return its
+ * name; return NULL if no match.
+ */
+static const char *
+find_matching_ts_config(const char *lc_type)
+{
+ int i;
+ char *langname,
+ *ptr;
+
+ /*
+ * Convert lc_ctype to a language name by stripping ".utf8" or
+ * what-have-you
+ */
+ if (lc_type == NULL)
+ langname = xstrdup("");
+ else
+ {
+ ptr = langname = xstrdup(lc_type);
+ while (*ptr && *ptr != '.')
+ ptr++;
+ *ptr = '\0';
+ }
+
+ for (i = 0; tsearch_config_languages[i].tsconfname; i++)
+ {
+ if (pg_strcasecmp(tsearch_config_languages[i].langname, langname) == 0)
+ {
+ free(langname);
+ return tsearch_config_languages[i].tsconfname;
+ }
+ }
+
+ free(langname);
+ return NULL;
+}
+
+
/*
* get short version of VERSION
*/
@@ -1305,6 +1396,13 @@ setup_config(void)
}
conflines = replace_token(conflines, "#datestyle = 'iso, mdy'", repltok);
+ snprintf(repltok, sizeof(repltok),
+ "default_text_search_config = 'pg_catalog.%s'",
+ escape_quotes(default_text_search_config));
+ conflines = replace_token(conflines,
+ "#default_text_search_config = 'pg_catalog.simple'",
+ repltok);
+
snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
writefile(path, conflines);
@@ -1679,6 +1777,14 @@ setup_depend(void)
" FROM pg_namespace "
" WHERE nspname LIKE 'pg%';\n",
+ "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
+ " FROM pg_ts_parser;\n",
+ "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
+ " FROM pg_ts_dict;\n",
+ "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
+ " FROM pg_ts_template;\n",
+ "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
+ " FROM pg_ts_config;\n",
"INSERT INTO pg_shdepend SELECT 0, 0, 0, tableoid, oid, 'p' "
" FROM pg_authid;\n",
NULL
@@ -1826,6 +1932,43 @@ setup_conversion(void)
}
/*
+ * load extra dictionaries (Snowball stemmers)
+ */
+static void
+setup_dictionary(void)
+{
+ PG_CMD_DECL;
+ char **line;
+ char **conv_lines;
+
+ fputs(_("creating dictionaries ... "), stdout);
+ fflush(stdout);
+
+ /*
+ * We use -j here to avoid backslashing stuff
+ */
+ snprintf(cmd, sizeof(cmd),
+ "\"%s\" %s -j template1 >%s",
+ backend_exec, backend_options,
+ DEVNULL);
+
+ PG_CMD_OPEN;
+
+ conv_lines = readfile(dictionary_file);
+ for (line = conv_lines; *line != NULL; line++)
+ {
+ PG_CMD_PUTS(*line);
+ free(*line);
+ }
+
+ free(conv_lines);
+
+ PG_CMD_CLOSE;
+
+ check_ok();
+}
+
+/*
* Set up privileges
*
* We mark most system catalogs as world-readable. We don't currently have
@@ -2403,6 +2546,8 @@ usage(const char *progname)
" in the respective category (default taken from\n"
" environment)\n"));
printf(_(" --no-locale equivalent to --locale=C\n"));
+ printf(_(" -T, --text-search-config=CFG\n"));
+ printf(_(" set default text search configuration\n"));
printf(_(" -X, --xlogdir=XLOGDIR location for the transaction log directory\n"));
printf(_(" -A, --auth=METHOD default authentication method for local connections\n"));
printf(_(" -U, --username=NAME database superuser name\n"));
@@ -2438,6 +2583,7 @@ main(int argc, char *argv[])
{"lc-time", required_argument, NULL, 6},
{"lc-messages", required_argument, NULL, 7},
{"no-locale", no_argument, NULL, 8},
+ {"text-search-config", required_argument, NULL, 'T'},
{"auth", required_argument, NULL, 'A'},
{"pwprompt", no_argument, NULL, 'W'},
{"pwfile", required_argument, NULL, 9},
@@ -2498,7 +2644,7 @@ main(int argc, char *argv[])
/* process command-line options */
- while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sX:", long_options, &option_index)) != -1)
+ while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1)
{
switch (c)
{
@@ -2558,6 +2704,9 @@ main(int argc, char *argv[])
case 's':
show_setting = true;
break;
+ case 'T':
+ default_text_search_config = xstrdup(optarg);
+ break;
case 'X':
xlog_dir = xstrdup(optarg);
break;
@@ -2771,6 +2920,7 @@ main(int argc, char *argv[])
set_input(&ident_file, "pg_ident.conf.sample");
set_input(&conf_file, "postgresql.conf.sample");
set_input(&conversion_file, "conversion_create.sql");
+ set_input(&dictionary_file, "snowball_create.sql");
set_input(&info_schema_file, "information_schema.sql");
set_input(&features_file, "sql_features.txt");
set_input(&system_views_file, "system_views.sql");
@@ -2803,6 +2953,7 @@ main(int argc, char *argv[])
check_input(ident_file);
check_input(conf_file);
check_input(conversion_file);
+ check_input(dictionary_file);
check_input(info_schema_file);
check_input(features_file);
check_input(system_views_file);
@@ -2864,6 +3015,35 @@ main(int argc, char *argv[])
}
#endif /* HAVE_LANGINFO_H && CODESET */
+ if (strlen(default_text_search_config) == 0)
+ {
+ default_text_search_config = find_matching_ts_config(lc_ctype);
+ if (default_text_search_config == NULL)
+ {
+ printf(_("%s: could not find suitable text search configuration for locale \"%s\"\n"),
+ progname, lc_ctype);
+ default_text_search_config = "simple";
+ }
+ }
+ else
+ {
+ const char *checkmatch = find_matching_ts_config(lc_ctype);
+
+ if (checkmatch == NULL)
+ {
+ printf(_("%s: warning: suitable text search configuration for locale \"%s\" is unknown\n"),
+ progname, lc_ctype);
+ }
+ else if (strcmp(checkmatch, default_text_search_config) != 0)
+ {
+ printf(_("%s: warning: specified text search configuration \"%s\" may not match locale \"%s\"\n"),
+ progname, default_text_search_config, lc_ctype);
+ }
+ }
+
+ printf(_("The default text search configuration will be set to \"%s\".\n"),
+ default_text_search_config);
+
printf("\n");
umask(077);
@@ -3062,6 +3242,8 @@ main(int argc, char *argv[])
setup_conversion();
+ setup_dictionary();
+
setup_privileges();
setup_schema();
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 212c952d2c6..53d15ac970d 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.96 2007/01/23 17:54:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.97 2007/08/21 01:11:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -79,6 +79,10 @@ getSchemaData(int *numTablesPtr)
OpclassInfo *opcinfo;
OpfamilyInfo *opfinfo;
ConvInfo *convinfo;
+ TSParserInfo *prsinfo;
+ TSTemplateInfo *tmplinfo;
+ TSDictInfo *dictinfo;
+ TSConfigInfo *cfginfo;
int numNamespaces;
int numAggregates;
int numInherits;
@@ -88,6 +92,10 @@ getSchemaData(int *numTablesPtr)
int numOpclasses;
int numOpfamilies;
int numConversions;
+ int numTSParsers;
+ int numTSTemplates;
+ int numTSDicts;
+ int numTSConfigs;
if (g_verbose)
write_msg(NULL, "reading schemas\n");
@@ -120,6 +128,22 @@ getSchemaData(int *numTablesPtr)
opcinfo = getOpclasses(&numOpclasses);
if (g_verbose)
+ write_msg(NULL, "reading user-defined text search parsers\n");
+ prsinfo = getTSParsers(&numTSParsers);
+
+ if (g_verbose)
+ write_msg(NULL, "reading user-defined text search templates\n");
+ tmplinfo = getTSTemplates(&numTSTemplates);
+
+ if (g_verbose)
+ write_msg(NULL, "reading user-defined text search dictionaries\n");
+ dictinfo = getTSDictionaries(&numTSDicts);
+
+ if (g_verbose)
+ write_msg(NULL, "reading user-defined text search configurations\n");
+ cfginfo = getTSConfigurations(&numTSConfigs);
+
+ if (g_verbose)
write_msg(NULL, "reading user-defined operator families\n");
opfinfo = getOpfamilies(&numOpfamilies);
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index c0e192e859b..01439a18073 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.145 2007/08/06 01:38:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.146 2007/08/21 01:11:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2419,7 +2419,9 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
if (strcmp(type, "CONVERSION") == 0 ||
strcmp(type, "DOMAIN") == 0 ||
strcmp(type, "TABLE") == 0 ||
- strcmp(type, "TYPE") == 0)
+ strcmp(type, "TYPE") == 0 ||
+ strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
+ strcmp(type, "TEXT SEARCH CONFIGURATION") == 0)
{
appendPQExpBuffer(buf, "%s ", type);
if (te->namespace && te->namespace[0]) /* is null pre-7.3 */
@@ -2591,7 +2593,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isDat
strcmp(te->desc, "TABLE") == 0 ||
strcmp(te->desc, "TYPE") == 0 ||
strcmp(te->desc, "VIEW") == 0 ||
- strcmp(te->desc, "SEQUENCE") == 0)
+ strcmp(te->desc, "SEQUENCE") == 0 ||
+ strcmp(te->desc, "TEXT SEARCH DICTIONARY") == 0 ||
+ strcmp(te->desc, "TEXT SEARCH CONFIGURATION") == 0)
{
PQExpBuffer temp = createPQExpBuffer();
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index ee7b6bca790..4d4d7f7986e 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.469 2007/07/12 23:25:26 neilc Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.470 2007/08/21 01:11:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -158,6 +158,10 @@ static void dumpSequence(Archive *fout, TableInfo *tbinfo);
static void dumpIndex(Archive *fout, IndxInfo *indxinfo);
static void dumpConstraint(Archive *fout, ConstraintInfo *coninfo);
static void dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo);
+static void dumpTSParser(Archive *fout, TSParserInfo *prsinfo);
+static void dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo);
+static void dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo);
+static void dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo);
static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
const char *type, const char *name,
@@ -174,6 +178,7 @@ static char *format_function_arguments(FuncInfo *finfo, int nallargs,
static char *format_function_signature(FuncInfo *finfo, bool honor_quotes);
static const char *convertRegProcReference(const char *proc);
static const char *convertOperatorReference(const char *opr);
+static const char *convertTSFunction(Oid funcOid);
static Oid findLastBuiltinOid_V71(const char *);
static Oid findLastBuiltinOid_V70(void);
static void selectSourceSchema(const char *schemaName);
@@ -4678,6 +4683,327 @@ getTableAttrs(TableInfo *tblinfo, int numTables)
/*
+ * getTSParsers:
+ * read all text search parsers in the system catalogs and return them
+ * in the TSParserInfo* structure
+ *
+ * numTSParsers is set to the number of parsers read in
+ */
+TSParserInfo *
+getTSParsers(int *numTSParsers)
+{
+ PGresult *res;
+ int ntups;
+ int i;
+ PQExpBuffer query = createPQExpBuffer();
+ TSParserInfo *prsinfo;
+ int i_tableoid;
+ int i_oid;
+ int i_prsname;
+ int i_prsnamespace;
+ int i_prsstart;
+ int i_prstoken;
+ int i_prsend;
+ int i_prsheadline;
+ int i_prslextype;
+
+ /* Before 8.3, there is no built-in text search support */
+ if (g_fout->remoteVersion < 80300)
+ {
+ *numTSParsers = 0;
+ return NULL;
+ }
+
+ /*
+ * find all text search objects, including builtin ones; we filter out
+ * system-defined objects at dump-out time.
+ */
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema("pg_catalog");
+
+ appendPQExpBuffer(query, "SELECT tableoid, oid, prsname, prsnamespace, "
+ "prsstart::oid, prstoken::oid, "
+ "prsend::oid, prsheadline::oid, prslextype::oid "
+ "FROM pg_ts_parser");
+
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+
+ ntups = PQntuples(res);
+ *numTSParsers = ntups;
+
+ prsinfo = (TSParserInfo *) malloc(ntups * sizeof(TSParserInfo));
+
+ i_tableoid = PQfnumber(res, "tableoid");
+ i_oid = PQfnumber(res, "oid");
+ i_prsname = PQfnumber(res, "prsname");
+ i_prsnamespace = PQfnumber(res, "prsnamespace");
+ i_prsstart = PQfnumber(res, "prsstart");
+ i_prstoken = PQfnumber(res, "prstoken");
+ i_prsend = PQfnumber(res, "prsend");
+ i_prsheadline = PQfnumber(res, "prsheadline");
+ i_prslextype = PQfnumber(res, "prslextype");
+
+ for (i = 0; i < ntups; i++)
+ {
+ prsinfo[i].dobj.objType = DO_TSPARSER;
+ prsinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
+ prsinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
+ AssignDumpId(&prsinfo[i].dobj);
+ prsinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_prsname));
+ prsinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_prsnamespace)),
+ prsinfo[i].dobj.catId.oid);
+ prsinfo[i].prsstart = atooid(PQgetvalue(res, i, i_prsstart));
+ prsinfo[i].prstoken = atooid(PQgetvalue(res, i, i_prstoken));
+ prsinfo[i].prsend = atooid(PQgetvalue(res, i, i_prsend));
+ prsinfo[i].prsheadline = atooid(PQgetvalue(res, i, i_prsheadline));
+ prsinfo[i].prslextype = atooid(PQgetvalue(res, i, i_prslextype));
+
+ /* Decide whether we want to dump it */
+ selectDumpableObject(&(prsinfo[i].dobj));
+ }
+
+ PQclear(res);
+
+ destroyPQExpBuffer(query);
+
+ return prsinfo;
+}
+
+/*
+ * getTSDictionaries:
+ * read all text search dictionaries in the system catalogs and return them
+ * in the TSDictInfo* structure
+ *
+ * numTSDicts is set to the number of dictionaries read in
+ */
+TSDictInfo *
+getTSDictionaries(int *numTSDicts)
+{
+ PGresult *res;
+ int ntups;
+ int i;
+ PQExpBuffer query = createPQExpBuffer();
+ TSDictInfo *dictinfo;
+ int i_tableoid;
+ int i_oid;
+ int i_dictname;
+ int i_dictnamespace;
+ int i_rolname;
+ int i_dicttemplate;
+ int i_dictinitoption;
+
+ /* Before 8.3, there is no built-in text search support */
+ if (g_fout->remoteVersion < 80300)
+ {
+ *numTSDicts = 0;
+ return NULL;
+ }
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema("pg_catalog");
+
+ appendPQExpBuffer(query, "SELECT tableoid, oid, dictname, "
+ "dictnamespace, (%s dictowner) as rolname, "
+ "dicttemplate, dictinitoption "
+ "FROM pg_ts_dict",
+ username_subquery);
+
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+
+ ntups = PQntuples(res);
+ *numTSDicts = ntups;
+
+ dictinfo = (TSDictInfo *) malloc(ntups * sizeof(TSDictInfo));
+
+ i_tableoid = PQfnumber(res, "tableoid");
+ i_oid = PQfnumber(res, "oid");
+ i_dictname = PQfnumber(res, "dictname");
+ i_dictnamespace = PQfnumber(res, "dictnamespace");
+ i_rolname = PQfnumber(res, "rolname");
+ i_dictinitoption = PQfnumber(res, "dictinitoption");
+ i_dicttemplate = PQfnumber(res, "dicttemplate");
+
+ for (i = 0; i < ntups; i++)
+ {
+ dictinfo[i].dobj.objType = DO_TSDICT;
+ dictinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
+ dictinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
+ AssignDumpId(&dictinfo[i].dobj);
+ dictinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_dictname));
+ dictinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_dictnamespace)),
+ dictinfo[i].dobj.catId.oid);
+ dictinfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+ dictinfo[i].dicttemplate = atooid(PQgetvalue(res, i, i_dicttemplate));
+ if (PQgetisnull(res, i, i_dictinitoption))
+ dictinfo[i].dictinitoption = NULL;
+ else
+ dictinfo[i].dictinitoption = strdup(PQgetvalue(res, i, i_dictinitoption));
+
+ /* Decide whether we want to dump it */
+ selectDumpableObject(&(dictinfo[i].dobj));
+ }
+
+ PQclear(res);
+
+ destroyPQExpBuffer(query);
+
+ return dictinfo;
+}
+
+/*
+ * getTSTemplates:
+ * read all text search templates in the system catalogs and return them
+ * in the TSTemplateInfo* structure
+ *
+ * numTSTemplates is set to the number of templates read in
+ */
+TSTemplateInfo *
+getTSTemplates(int *numTSTemplates)
+{
+ PGresult *res;
+ int ntups;
+ int i;
+ PQExpBuffer query = createPQExpBuffer();
+ TSTemplateInfo *tmplinfo;
+ int i_tableoid;
+ int i_oid;
+ int i_tmplname;
+ int i_tmplnamespace;
+ int i_tmplinit;
+ int i_tmpllexize;
+
+ /* Before 8.3, there is no built-in text search support */
+ if (g_fout->remoteVersion < 80300)
+ {
+ *numTSTemplates = 0;
+ return NULL;
+ }
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema("pg_catalog");
+
+ appendPQExpBuffer(query, "SELECT tableoid, oid, tmplname, "
+ "tmplnamespace, tmplinit::oid, tmpllexize::oid "
+ "FROM pg_ts_template");
+
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+
+ ntups = PQntuples(res);
+ *numTSTemplates = ntups;
+
+ tmplinfo = (TSTemplateInfo *) malloc(ntups * sizeof(TSTemplateInfo));
+
+ i_tableoid = PQfnumber(res, "tableoid");
+ i_oid = PQfnumber(res, "oid");
+ i_tmplname = PQfnumber(res, "tmplname");
+ i_tmplnamespace = PQfnumber(res, "tmplnamespace");
+ i_tmplinit = PQfnumber(res, "tmplinit");
+ i_tmpllexize = PQfnumber(res, "tmpllexize");
+
+ for (i = 0; i < ntups; i++)
+ {
+ tmplinfo[i].dobj.objType = DO_TSTEMPLATE;
+ tmplinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
+ tmplinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
+ AssignDumpId(&tmplinfo[i].dobj);
+ tmplinfo[i].dobj.name = strdup(PQgetvalue(res, i, i_tmplname));
+ tmplinfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_tmplnamespace)),
+ tmplinfo[i].dobj.catId.oid);
+ tmplinfo[i].tmplinit = atooid(PQgetvalue(res, i, i_tmplinit));
+ tmplinfo[i].tmpllexize = atooid(PQgetvalue(res, i, i_tmpllexize));
+
+ /* Decide whether we want to dump it */
+ selectDumpableObject(&(tmplinfo[i].dobj));
+ }
+
+ PQclear(res);
+
+ destroyPQExpBuffer(query);
+
+ return tmplinfo;
+}
+
+/*
+ * getTSConfigurations:
+ * read all text search configurations in the system catalogs and return
+ * them in the TSConfigInfo* structure
+ *
+ * numTSConfigs is set to the number of configurations read in
+ */
+TSConfigInfo *
+getTSConfigurations(int *numTSConfigs)
+{
+ PGresult *res;
+ int ntups;
+ int i;
+ PQExpBuffer query = createPQExpBuffer();
+ TSConfigInfo *cfginfo;
+ int i_tableoid;
+ int i_oid;
+ int i_cfgname;
+ int i_cfgnamespace;
+ int i_rolname;
+ int i_cfgparser;
+
+ /* Before 8.3, there is no built-in text search support */
+ if (g_fout->remoteVersion < 80300)
+ {
+ *numTSConfigs = 0;
+ return NULL;
+ }
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema("pg_catalog");
+
+ appendPQExpBuffer(query, "SELECT tableoid, oid, cfgname, "
+ "cfgnamespace, (%s cfgowner) as rolname, cfgparser "
+ "FROM pg_ts_config",
+ username_subquery);
+
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+
+ ntups = PQntuples(res);
+ *numTSConfigs = ntups;
+
+ cfginfo = (TSConfigInfo *) malloc(ntups * sizeof(TSConfigInfo));
+
+ i_tableoid = PQfnumber(res, "tableoid");
+ i_oid = PQfnumber(res, "oid");
+ i_cfgname = PQfnumber(res, "cfgname");
+ i_cfgnamespace = PQfnumber(res, "cfgnamespace");
+ i_rolname = PQfnumber(res, "rolname");
+ i_cfgparser = PQfnumber(res, "cfgparser");
+
+ for (i = 0; i < ntups; i++)
+ {
+ cfginfo[i].dobj.objType = DO_TSCONFIG;
+ cfginfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_tableoid));
+ cfginfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_oid));
+ AssignDumpId(&cfginfo[i].dobj);
+ cfginfo[i].dobj.name = strdup(PQgetvalue(res, i, i_cfgname));
+ cfginfo[i].dobj.namespace = findNamespace(atooid(PQgetvalue(res, i, i_cfgnamespace)),
+ cfginfo[i].dobj.catId.oid);
+ cfginfo[i].rolname = strdup(PQgetvalue(res, i, i_rolname));
+ cfginfo[i].cfgparser = atooid(PQgetvalue(res, i, i_cfgparser));
+
+ /* Decide whether we want to dump it */
+ selectDumpableObject(&(cfginfo[i].dobj));
+ }
+
+ PQclear(res);
+
+ destroyPQExpBuffer(query);
+
+ return cfginfo;
+}
+
+
+/*
* dumpComment --
*
* This routine is used to dump any comments associated with the
@@ -5066,6 +5392,18 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
case DO_TABLE_TYPE:
/* table rowtypes are never dumped separately */
break;
+ case DO_TSPARSER:
+ dumpTSParser(fout, (TSParserInfo *) dobj);
+ break;
+ case DO_TSDICT:
+ dumpTSDictionary(fout, (TSDictInfo *) dobj);
+ break;
+ case DO_TSTEMPLATE:
+ dumpTSTemplate(fout, (TSTemplateInfo *) dobj);
+ break;
+ case DO_TSCONFIG:
+ dumpTSConfig(fout, (TSConfigInfo *) dobj);
+ break;
case DO_BLOBS:
ArchiveEntry(fout, dobj->catId, dobj->dumpId,
dobj->name, NULL, NULL, "",
@@ -6875,6 +7213,43 @@ convertOperatorReference(const char *opr)
}
/*
+ * Convert a function OID obtained from pg_ts_parser or pg_ts_template
+ *
+ * It is sufficient to use REGPROC rather than REGPROCEDURE, since the
+ * argument lists of these functions are predetermined. Note that the
+ * caller should ensure we are in the proper schema, because the results
+ * are search path dependent!
+ */
+static const char *
+convertTSFunction(Oid funcOid)
+{
+ char *result;
+ char query[128];
+ PGresult *res;
+ int ntups;
+
+ snprintf(query, sizeof(query),
+ "SELECT '%u'::pg_catalog.regproc", funcOid);
+ res = PQexec(g_conn, query);
+ check_sql_result(res, g_conn, query, PGRES_TUPLES_OK);
+
+ ntups = PQntuples(res);
+ if (ntups != 1)
+ {
+ write_msg(NULL, "Got %d rows instead of one from \"%s\"\n",
+ ntups, query);
+ exit_nicely();
+ }
+
+ result = strdup(PQgetvalue(res, 0, 0));
+
+ PQclear(res);
+
+ return result;
+}
+
+
+/*
* dumpOpclass
* write out a single operator class definition
*/
@@ -7795,6 +8170,351 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
destroyPQExpBuffer(details);
}
+/*
+ * dumpTSParser
+ * write out a single text search parser
+ */
+static void
+dumpTSParser(Archive *fout, TSParserInfo * prsinfo)
+{
+ PQExpBuffer q;
+ PQExpBuffer delq;
+
+ /* Skip if not to be dumped */
+ if (!prsinfo->dobj.dump || dataOnly)
+ return;
+
+ q = createPQExpBuffer();
+ delq = createPQExpBuffer();
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema(prsinfo->dobj.namespace->dobj.name);
+
+ appendPQExpBuffer(q, "CREATE TEXT SEARCH PARSER %s (\n",
+ fmtId(prsinfo->dobj.name));
+
+ appendPQExpBuffer(q, " START = %s,\n",
+ convertTSFunction(prsinfo->prsstart));
+ appendPQExpBuffer(q, " GETTOKEN = %s,\n",
+ convertTSFunction(prsinfo->prstoken));
+ appendPQExpBuffer(q, " END = %s,\n",
+ convertTSFunction(prsinfo->prsend));
+ if (prsinfo->prsheadline != InvalidOid)
+ appendPQExpBuffer(q, " HEADLINE = %s,\n",
+ convertTSFunction(prsinfo->prsheadline));
+ appendPQExpBuffer(q, " LEXTYPES = %s );\n",
+ convertTSFunction(prsinfo->prslextype));
+
+ /*
+ * DROP must be fully qualified in case same name appears in pg_catalog
+ */
+ appendPQExpBuffer(delq, "DROP TEXT SEARCH PARSER %s",
+ fmtId(prsinfo->dobj.namespace->dobj.name));
+ appendPQExpBuffer(delq, ".%s;\n",
+ fmtId(prsinfo->dobj.name));
+
+ ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId,
+ prsinfo->dobj.name,
+ prsinfo->dobj.namespace->dobj.name,
+ NULL,
+ "",
+ false, "TEXT SEARCH PARSER", q->data, delq->data, NULL,
+ prsinfo->dobj.dependencies, prsinfo->dobj.nDeps,
+ NULL, NULL);
+
+ /* Dump Parser Comments */
+ resetPQExpBuffer(q);
+ appendPQExpBuffer(q, "TEXT SEARCH PARSER %s",
+ fmtId(prsinfo->dobj.name));
+ dumpComment(fout, q->data,
+ NULL, "",
+ prsinfo->dobj.catId, 0, prsinfo->dobj.dumpId);
+
+ destroyPQExpBuffer(q);
+ destroyPQExpBuffer(delq);
+}
+
+/*
+ * dumpTSDictionary
+ * write out a single text search dictionary
+ */
+static void
+dumpTSDictionary(Archive *fout, TSDictInfo * dictinfo)
+{
+ PQExpBuffer q;
+ PQExpBuffer delq;
+ PQExpBuffer query;
+ PGresult *res;
+ int ntups;
+ char *nspname;
+ char *tmplname;
+
+ /* Skip if not to be dumped */
+ if (!dictinfo->dobj.dump || dataOnly)
+ return;
+
+ q = createPQExpBuffer();
+ delq = createPQExpBuffer();
+ query = createPQExpBuffer();
+
+ /* Fetch name and namespace of the dictionary's template */
+ selectSourceSchema("pg_catalog");
+ appendPQExpBuffer(query, "SELECT nspname, tmplname "
+ "FROM pg_ts_template p, pg_namespace n "
+ "WHERE p.oid = '%u' AND n.oid = tmplnamespace",
+ dictinfo->dicttemplate);
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+ ntups = PQntuples(res);
+ if (ntups != 1)
+ {
+ write_msg(NULL, "Got %d rows instead of one from \"%s\"\n",
+ ntups, query->data);
+ exit_nicely();
+ }
+ nspname = PQgetvalue(res, 0, 0);
+ tmplname = PQgetvalue(res, 0, 1);
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema(dictinfo->dobj.namespace->dobj.name);
+
+ appendPQExpBuffer(q, "CREATE TEXT SEARCH DICTIONARY %s (\n",
+ fmtId(dictinfo->dobj.name));
+
+ appendPQExpBuffer(q, " TEMPLATE = ");
+ if (strcmp(nspname, dictinfo->dobj.namespace->dobj.name) != 0)
+ appendPQExpBuffer(q, "%s.", fmtId(nspname));
+ appendPQExpBuffer(q, "%s", fmtId(tmplname));
+
+ PQclear(res);
+
+ if (dictinfo->dictinitoption)
+ {
+ appendPQExpBuffer(q, ",\n OPTION = ");
+ appendStringLiteralConn(q, dictinfo->dictinitoption, g_conn);
+ }
+
+ appendPQExpBuffer(q, " );\n");
+
+ /*
+ * DROP must be fully qualified in case same name appears in pg_catalog
+ */
+ appendPQExpBuffer(delq, "DROP TEXT SEARCH DICTIONARY %s",
+ fmtId(dictinfo->dobj.namespace->dobj.name));
+ appendPQExpBuffer(delq, ".%s;\n",
+ fmtId(dictinfo->dobj.name));
+
+ ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId,
+ dictinfo->dobj.name,
+ dictinfo->dobj.namespace->dobj.name,
+ NULL,
+ dictinfo->rolname,
+ false, "TEXT SEARCH DICTIONARY", q->data, delq->data, NULL,
+ dictinfo->dobj.dependencies, dictinfo->dobj.nDeps,
+ NULL, NULL);
+
+ /* Dump Dictionary Comments */
+ resetPQExpBuffer(q);
+ appendPQExpBuffer(q, "TEXT SEARCH DICTIONARY %s",
+ fmtId(dictinfo->dobj.name));
+ dumpComment(fout, q->data,
+ NULL, dictinfo->rolname,
+ dictinfo->dobj.catId, 0, dictinfo->dobj.dumpId);
+
+ destroyPQExpBuffer(q);
+ destroyPQExpBuffer(delq);
+ destroyPQExpBuffer(query);
+}
+
+/*
+ * dumpTSTemplate
+ * write out a single text search template
+ */
+static void
+dumpTSTemplate(Archive *fout, TSTemplateInfo * tmplinfo)
+{
+ PQExpBuffer q;
+ PQExpBuffer delq;
+
+ /* Skip if not to be dumped */
+ if (!tmplinfo->dobj.dump || dataOnly)
+ return;
+
+ q = createPQExpBuffer();
+ delq = createPQExpBuffer();
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema(tmplinfo->dobj.namespace->dobj.name);
+
+ appendPQExpBuffer(q, "CREATE TEXT SEARCH TEMPLATE %s (\n",
+ fmtId(tmplinfo->dobj.name));
+
+ if (tmplinfo->tmplinit != InvalidOid)
+ appendPQExpBuffer(q, " INIT = %s,\n",
+ convertTSFunction(tmplinfo->tmplinit));
+ appendPQExpBuffer(q, " LEXIZE = %s );\n",
+ convertTSFunction(tmplinfo->tmpllexize));
+
+ /*
+ * DROP must be fully qualified in case same name appears in pg_catalog
+ */
+ appendPQExpBuffer(delq, "DROP TEXT SEARCH TEMPLATE %s",
+ fmtId(tmplinfo->dobj.namespace->dobj.name));
+ appendPQExpBuffer(delq, ".%s;\n",
+ fmtId(tmplinfo->dobj.name));
+
+ ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId,
+ tmplinfo->dobj.name,
+ tmplinfo->dobj.namespace->dobj.name,
+ NULL,
+ "",
+ false, "TEXT SEARCH TEMPLATE", q->data, delq->data, NULL,
+ tmplinfo->dobj.dependencies, tmplinfo->dobj.nDeps,
+ NULL, NULL);
+
+ /* Dump Template Comments */
+ resetPQExpBuffer(q);
+ appendPQExpBuffer(q, "TEXT SEARCH TEMPLATE %s",
+ fmtId(tmplinfo->dobj.name));
+ dumpComment(fout, q->data,
+ NULL, "",
+ tmplinfo->dobj.catId, 0, tmplinfo->dobj.dumpId);
+
+ destroyPQExpBuffer(q);
+ destroyPQExpBuffer(delq);
+}
+
+/*
+ * dumpTSConfig
+ * write out a single text search configuration
+ */
+static void
+dumpTSConfig(Archive *fout, TSConfigInfo * cfginfo)
+{
+ PQExpBuffer q;
+ PQExpBuffer delq;
+ PQExpBuffer query;
+ PGresult *res;
+ char *nspname;
+ char *prsname;
+ int ntups,
+ i;
+ int i_tokenname;
+ int i_dictname;
+
+ /* Skip if not to be dumped */
+ if (!cfginfo->dobj.dump || dataOnly)
+ return;
+
+ q = createPQExpBuffer();
+ delq = createPQExpBuffer();
+ query = createPQExpBuffer();
+
+ /* Fetch name and namespace of the config's parser */
+ selectSourceSchema("pg_catalog");
+ appendPQExpBuffer(query, "SELECT nspname, prsname "
+ "FROM pg_ts_parser p, pg_namespace n "
+ "WHERE p.oid = '%u' AND n.oid = prsnamespace",
+ cfginfo->cfgparser);
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+ ntups = PQntuples(res);
+ if (ntups != 1)
+ {
+ write_msg(NULL, "Got %d rows instead of one from \"%s\"\n",
+ ntups, query->data);
+ exit_nicely();
+ }
+ nspname = PQgetvalue(res, 0, 0);
+ prsname = PQgetvalue(res, 0, 1);
+
+ /* Make sure we are in proper schema */
+ selectSourceSchema(cfginfo->dobj.namespace->dobj.name);
+
+ appendPQExpBuffer(q, "CREATE TEXT SEARCH CONFIGURATION %s (\n",
+ fmtId(cfginfo->dobj.name));
+
+ appendPQExpBuffer(q, " PARSER = ");
+ if (strcmp(nspname, cfginfo->dobj.namespace->dobj.name) != 0)
+ appendPQExpBuffer(q, "%s.", fmtId(nspname));
+ appendPQExpBuffer(q, "%s );\n", fmtId(prsname));
+
+ PQclear(res);
+
+ resetPQExpBuffer(query);
+ appendPQExpBuffer(query,
+ "SELECT \n"
+ " ( SELECT alias FROM pg_catalog.ts_token_type('%u'::pg_catalog.oid) AS t \n"
+ " WHERE t.tokid = m.maptokentype ) AS tokenname, \n"
+ " m.mapdict::pg_catalog.regdictionary AS dictname \n"
+ "FROM pg_catalog.pg_ts_config_map AS m \n"
+ "WHERE m.mapcfg = '%u' \n"
+ "ORDER BY m.mapcfg, m.maptokentype, m.mapseqno",
+ cfginfo->cfgparser, cfginfo->dobj.catId.oid);
+
+ res = PQexec(g_conn, query->data);
+ check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
+ ntups = PQntuples(res);
+
+ i_tokenname = PQfnumber(res, "tokenname");
+ i_dictname = PQfnumber(res, "dictname");
+
+ for (i = 0; i < ntups; i++)
+ {
+ char *tokenname = PQgetvalue(res, i, i_tokenname);
+ char *dictname = PQgetvalue(res, i, i_dictname);
+
+ if (i == 0 ||
+ strcmp(tokenname, PQgetvalue(res, i-1, i_tokenname)) != 0)
+ {
+ /* starting a new token type, so start a new command */
+ if (i > 0)
+ appendPQExpBuffer(q, ";\n");
+ appendPQExpBuffer(q, "\nALTER TEXT SEARCH CONFIGURATION %s\n",
+ fmtId(cfginfo->dobj.name));
+ /* tokenname needs quoting, dictname does NOT */
+ appendPQExpBuffer(q, " ADD MAPPING FOR %s WITH %s",
+ fmtId(tokenname), dictname);
+ }
+ else
+ appendPQExpBuffer(q, ", %s", dictname);
+ }
+
+ if (ntups > 0)
+ appendPQExpBuffer(q, ";\n");
+
+ PQclear(res);
+
+ /*
+ * DROP must be fully qualified in case same name appears in pg_catalog
+ */
+ appendPQExpBuffer(delq, "DROP TEXT SEARCH CONFIGURATION %s",
+ fmtId(cfginfo->dobj.namespace->dobj.name));
+ appendPQExpBuffer(delq, ".%s;\n",
+ fmtId(cfginfo->dobj.name));
+
+ ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId,
+ cfginfo->dobj.name,
+ cfginfo->dobj.namespace->dobj.name,
+ NULL,
+ cfginfo->rolname,
+ false, "TEXT SEARCH CONFIGURATION", q->data, delq->data, NULL,
+ cfginfo->dobj.dependencies, cfginfo->dobj.nDeps,
+ NULL, NULL);
+
+ /* Dump Configuration Comments */
+ resetPQExpBuffer(q);
+ appendPQExpBuffer(q, "TEXT SEARCH CONFIGURATION %s",
+ fmtId(cfginfo->dobj.name));
+ dumpComment(fout, q->data,
+ NULL, cfginfo->rolname,
+ cfginfo->dobj.catId, 0, cfginfo->dobj.dumpId);
+
+ destroyPQExpBuffer(q);
+ destroyPQExpBuffer(delq);
+ destroyPQExpBuffer(query);
+}
+
/*----------
* Write out grant/revoke information
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 9575cd5b19d..0383b0d296d 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.135 2007/05/11 17:57:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.136 2007/08/21 01:11:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -127,6 +127,10 @@ typedef enum
DO_CAST,
DO_TABLE_DATA,
DO_TABLE_TYPE,
+ DO_TSPARSER,
+ DO_TSDICT,
+ DO_TSTEMPLATE,
+ DO_TSCONFIG,
DO_BLOBS,
DO_BLOB_COMMENTS
} DumpableObjectType;
@@ -379,6 +383,37 @@ typedef struct _inhInfo
Oid inhparent; /* OID of its parent */
} InhInfo;
+typedef struct _prsInfo
+{
+ DumpableObject dobj;
+ Oid prsstart;
+ Oid prstoken;
+ Oid prsend;
+ Oid prsheadline;
+ Oid prslextype;
+} TSParserInfo;
+
+typedef struct _dictInfo
+{
+ DumpableObject dobj;
+ char *rolname;
+ Oid dicttemplate;
+ char *dictinitoption;
+} TSDictInfo;
+
+typedef struct _tmplInfo
+{
+ DumpableObject dobj;
+ Oid tmplinit;
+ Oid tmpllexize;
+} TSTemplateInfo;
+
+typedef struct _cfgInfo
+{
+ DumpableObject dobj;
+ char *rolname;
+ Oid cfgparser;
+} TSConfigInfo;
/* global decls */
extern bool force_quotes; /* double-quotes for identifiers flag */
@@ -458,5 +493,9 @@ extern void getTriggers(TableInfo tblinfo[], int numTables);
extern ProcLangInfo *getProcLangs(int *numProcLangs);
extern CastInfo *getCasts(int *numCasts);
extern void getTableAttrs(TableInfo *tbinfo, int numTables);
+extern TSParserInfo *getTSParsers(int *numTSParsers);
+extern TSDictInfo *getTSDictionaries(int *numTSDicts);
+extern TSTemplateInfo *getTSTemplates(int *numTSTemplates);
+extern TSConfigInfo *getTSConfigurations(int *numTSConfigs);
#endif /* PG_DUMP_H */
diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c
index a74857fb68e..d74a5facf8e 100644
--- a/src/bin/pg_dump/pg_dump_sort.c
+++ b/src/bin/pg_dump/pg_dump_sort.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump_sort.c,v 1.18 2007/03/18 16:50:44 neilc Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump_sort.c,v 1.19 2007/08/21 01:11:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -46,6 +46,10 @@ static const int oldObjectTypePriority[] =
2, /* DO_CAST */
9, /* DO_TABLE_DATA */
7, /* DO_TABLE_TYPE */
+ 3, /* DO_TSPARSER */
+ 4, /* DO_TSDICT */
+ 3, /* DO_TSTEMPLATE */
+ 5, /* DO_TSCONFIG */
10, /* DO_BLOBS */
11 /* DO_BLOB_COMMENTS */
};
@@ -76,6 +80,10 @@ static const int newObjectTypePriority[] =
8, /* DO_CAST */
13, /* DO_TABLE_DATA */
11, /* DO_TABLE_TYPE */
+ 5, /* DO_TSPARSER */
+ 6, /* DO_TSDICT */
+ 5, /* DO_TSTEMPLATE */
+ 7, /* DO_TSCONFIG */
14, /* DO_BLOBS */
15 /* DO_BLOB_COMMENTS */
};
@@ -1067,6 +1075,26 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
"TABLE TYPE %s (ID %d OID %u)",
obj->name, obj->dumpId, obj->catId.oid);
return;
+ case DO_TSPARSER:
+ snprintf(buf, bufsize,
+ "TEXT SEARCH PARSER %s (ID %d OID %u)",
+ obj->name, obj->dumpId, obj->catId.oid);
+ return;
+ case DO_TSDICT:
+ snprintf(buf, bufsize,
+ "TEXT SEARCH DICTIONARY %s (ID %d OID %u)",
+ obj->name, obj->dumpId, obj->catId.oid);
+ return;
+ case DO_TSTEMPLATE:
+ snprintf(buf, bufsize,
+ "TEXT SEARCH TEMPLATE %s (ID %d OID %u)",
+ obj->name, obj->dumpId, obj->catId.oid);
+ return;
+ case DO_TSCONFIG:
+ snprintf(buf, bufsize,
+ "TEXT SEARCH CONFIGURATION %s (ID %d OID %u)",
+ obj->name, obj->dumpId, obj->catId.oid);
+ return;
case DO_BLOBS:
snprintf(buf, bufsize,
"BLOBS (ID %d)",
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 936c56b2031..04e5cce6361 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.180 2007/07/08 19:07:38 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.181 2007/08/21 01:11:22 tgl Exp $
*/
#include "postgres_fe.h"
#include "command.h"
@@ -405,6 +405,27 @@ exec_command(const char *cmd,
case 'u':
success = describeRoles(pattern, show_verbose);
break;
+ case 'F': /* text search subsystem */
+ switch (cmd[2])
+ {
+ case '\0':
+ case '+':
+ success = listTSConfigs(pattern, show_verbose);
+ break;
+ case 'p':
+ success = listTSParsers(pattern, show_verbose);
+ break;
+ case 'd':
+ success = listTSDictionaries(pattern, show_verbose);
+ break;
+ case 't':
+ success = listTSTemplates(pattern, show_verbose);
+ break;
+ default:
+ status = PSQL_CMD_UNKNOWN;
+ break;
+ }
+ break;
default:
status = PSQL_CMD_UNKNOWN;
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 6dd156af4af..f258e16ce1a 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.157 2007/07/25 22:16:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.158 2007/08/21 01:11:22 tgl Exp $
*/
#include "postgres_fe.h"
#include "describe.h"
@@ -33,6 +33,14 @@ static bool describeOneTableDetails(const char *schemaname,
bool verbose);
static bool add_tablespace_footer(char relkind, Oid tablespace, char **footers,
int *count, PQExpBufferData buf, bool newline);
+static bool listTSParsersVerbose(const char *pattern);
+static bool describeOneTSParser(const char *oid, const char *nspname,
+ const char *prsname);
+static bool listTSConfigsVerbose(const char *pattern);
+static bool describeOneTSConfig(const char *oid, const char *nspname,
+ const char *cfgname,
+ const char *pnspname, const char *prsname);
+
/*----------------
* Handlers for various slash commands displaying some sort of list
@@ -325,7 +333,6 @@ describeTypes(const char *pattern, bool verbose)
}
-
/* \do
*/
bool
@@ -1930,3 +1937,512 @@ listSchemas(const char *pattern, bool verbose)
PQclear(res);
return true;
}
+
+
+/*
+ * \dFp
+ * list text search parsers
+ */
+bool
+listTSParsers(const char *pattern, bool verbose)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+
+ if (verbose)
+ return listTSParsersVerbose(pattern);
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT \n"
+ " n.nspname as \"%s\",\n"
+ " p.prsname as \"%s\",\n"
+ " pg_catalog.obj_description(p.oid, 'pg_ts_parser') as \"%s\"\n"
+ "FROM pg_catalog.pg_ts_parser p \n"
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.prsnamespace\n",
+ _("Schema"),
+ _("Name"),
+ _("Description")
+ );
+
+ processSQLNamePattern(pset.db, &buf, pattern, false, false,
+ "n.nspname", "p.prsname", NULL,
+ "pg_catalog.pg_ts_parser_is_visible(p.oid)");
+
+ appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ myopt.title = _("List of text search parsers");
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
+
+/*
+ * full description of parsers
+ */
+static bool
+listTSParsersVerbose(const char *pattern)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ int i;
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT p.oid, \n"
+ " n.nspname, \n"
+ " p.prsname \n"
+ "FROM pg_catalog.pg_ts_parser p\n"
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.prsnamespace\n"
+ );
+
+ processSQLNamePattern(pset.db, &buf, pattern, false, false,
+ "n.nspname", "p.prsname", NULL,
+ "pg_catalog.pg_ts_parser_is_visible(p.oid)");
+
+ appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ if (PQntuples(res) == 0)
+ {
+ if (!pset.quiet)
+ fprintf(stderr, _("Did not find any text search parser named \"%s\".\n"),
+ pattern);
+ PQclear(res);
+ return false;
+ }
+
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ const char *oid;
+ const char *nspname = NULL;
+ const char *prsname;
+
+ oid = PQgetvalue(res, i, 0);
+ if (!PQgetisnull(res, i, 1))
+ nspname = PQgetvalue(res, i, 1);
+ prsname = PQgetvalue(res, i, 2);
+
+ if (!describeOneTSParser(oid, nspname, prsname))
+ {
+ PQclear(res);
+ return false;
+ }
+
+ if (cancel_pressed)
+ {
+ PQclear(res);
+ return false;
+ }
+ }
+
+ PQclear(res);
+ return true;
+}
+
+static bool
+describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ char title[1024];
+ printQueryOpt myopt = pset.popt;
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT '%s' AS \"%s\", \n"
+ " p.prsstart::pg_catalog.regproc AS \"%s\", \n"
+ " pg_catalog.obj_description(p.prsstart, 'pg_proc') as \"%s\" \n"
+ " FROM pg_catalog.pg_ts_parser p \n"
+ " WHERE p.oid = '%s' \n"
+ "UNION ALL \n"
+ "SELECT '%s', \n"
+ " p.prstoken::pg_catalog.regproc, \n"
+ " pg_catalog.obj_description(p.prstoken, 'pg_proc') \n"
+ " FROM pg_catalog.pg_ts_parser p \n"
+ " WHERE p.oid = '%s' \n"
+ "UNION ALL \n"
+ "SELECT '%s', \n"
+ " p.prsend::pg_catalog.regproc, \n"
+ " pg_catalog.obj_description(p.prsend, 'pg_proc') \n"
+ " FROM pg_catalog.pg_ts_parser p \n"
+ " WHERE p.oid = '%s' \n"
+ "UNION ALL \n"
+ "SELECT '%s', \n"
+ " p.prsheadline::pg_catalog.regproc, \n"
+ " pg_catalog.obj_description(p.prsheadline, 'pg_proc') \n"
+ " FROM pg_catalog.pg_ts_parser p \n"
+ " WHERE p.oid = '%s' \n"
+ "UNION ALL \n"
+ "SELECT '%s', \n"
+ " p.prslextype::pg_catalog.regproc, \n"
+ " pg_catalog.obj_description(p.prslextype, 'pg_proc') \n"
+ " FROM pg_catalog.pg_ts_parser p \n"
+ " WHERE p.oid = '%s' \n",
+ _("Start parse"),
+ _("Method"), _("Function"), _("Description"),
+ oid,
+ _("Get next token"), oid,
+ _("End parse"), oid,
+ _("Get headline"), oid,
+ _("Get lexeme types"), oid
+ );
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ if (nspname)
+ sprintf(title, _("Text search parser \"%s.%s\""), nspname, prsname);
+ else
+ sprintf(title, _("Text search parser \"%s\""), prsname);
+ myopt.title = title;
+ myopt.footers = NULL;
+ myopt.default_footer = false;
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT t.alias as \"%s\", \n"
+ " t.description as \"%s\" \n"
+ "FROM pg_catalog.ts_token_type( '%s'::pg_catalog.oid ) as t \n"
+ "ORDER BY 1;",
+ _("Token name"),
+ _("Description"),
+ oid);
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ if (nspname)
+ sprintf(title, _("Token types for parser \"%s.%s\""), nspname, prsname);
+ else
+ sprintf(title, _("Token types for parser \"%s\""), prsname);
+ myopt.title = title;
+ myopt.footers = NULL;
+ myopt.default_footer = true;
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
+
+
+/*
+ * \dFd
+ * list text search dictionaries
+ */
+bool
+listTSDictionaries(const char *pattern, bool verbose)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT \n"
+ " n.nspname as \"%s\",\n"
+ " d.dictname as \"%s\",\n",
+ _("Schema"),
+ _("Name"));
+
+ if (verbose)
+ {
+ appendPQExpBuffer(&buf,
+ " ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM \n"
+ " pg_catalog.pg_ts_template t \n"
+ " LEFT JOIN pg_catalog.pg_namespace nt ON nt.oid = t.tmplnamespace \n"
+ " WHERE d.dicttemplate = t.oid ) AS \"%s\", \n"
+ " d.dictinitoption as \"%s\", \n",
+ _("Template"),
+ _("Init options"));
+ }
+
+ appendPQExpBuffer(&buf,
+ " pg_catalog.obj_description(d.oid, 'pg_ts_dict') as \"%s\"\n",
+ _("Description"));
+
+ appendPQExpBuffer(&buf, "FROM pg_catalog.pg_ts_dict d\n"
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.dictnamespace\n");
+
+ processSQLNamePattern(pset.db, &buf, pattern, false, false,
+ "n.nspname", "d.dictname", NULL,
+ "pg_catalog.pg_ts_dict_is_visible(d.oid)");
+
+ appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ myopt.title = _("List of text search dictionaries");
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
+
+
+/*
+ * \dFt
+ * list text search templates
+ */
+bool
+listTSTemplates(const char *pattern, bool verbose)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT \n"
+ " n.nspname AS \"%s\",\n"
+ " t.tmplname AS \"%s\",\n"
+ " t.tmplinit::pg_catalog.regproc AS \"%s\",\n"
+ " t.tmpllexize::pg_catalog.regproc AS \"%s\",\n"
+ " pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \"%s\"\n",
+ _("Schema"),
+ _("Name"),
+ _("Init"),
+ _("Lexize"),
+ _("Description"));
+
+ appendPQExpBuffer(&buf, "FROM pg_catalog.pg_ts_template t\n"
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.tmplnamespace\n");
+
+ processSQLNamePattern(pset.db, &buf, pattern, false, false,
+ "n.nspname", "t.tmplname", NULL,
+ "pg_catalog.pg_ts_template_is_visible(t.oid)");
+
+ appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ myopt.title = _("List of text search templates");
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
+
+
+/*
+ * \dF
+ * list text search configurations
+ */
+bool
+listTSConfigs(const char *pattern, bool verbose)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+
+ if (verbose)
+ return listTSConfigsVerbose(pattern);
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT \n"
+ " n.nspname as \"%s\",\n"
+ " c.cfgname as \"%s\",\n"
+ " pg_catalog.obj_description(c.oid, 'pg_ts_config') as \"%s\"\n"
+ "FROM pg_catalog.pg_ts_config c\n"
+ "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.cfgnamespace \n",
+ _("Schema"),
+ _("Name"),
+ _("Description")
+ );
+
+ processSQLNamePattern(pset.db, &buf, pattern, false, false,
+ "n.nspname", "c.cfgname", NULL,
+ "pg_catalog.pg_ts_config_is_visible(c.oid)");
+
+ appendPQExpBuffer(&buf, "ORDER BY 1, 2;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ myopt.nullPrint = NULL;
+ myopt.title = _("List of text search configurations");
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ PQclear(res);
+ return true;
+}
+
+static bool
+listTSConfigsVerbose(const char *pattern)
+{
+ PQExpBufferData buf;
+ PGresult *res;
+ int i;
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT c.oid, c.cfgname,\n"
+ " n.nspname, \n"
+ " p.prsname, \n"
+ " np.nspname as pnspname \n"
+ "FROM pg_catalog.pg_ts_config c \n"
+ " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.cfgnamespace, \n"
+ " pg_catalog.pg_ts_parser p \n"
+ " LEFT JOIN pg_catalog.pg_namespace np ON np.oid = p.prsnamespace \n"
+ "WHERE p.oid = c.cfgparser\n"
+ );
+
+ processSQLNamePattern(pset.db, &buf, pattern, true, false,
+ "n.nspname", "c.cfgname", NULL,
+ "pg_catalog.pg_ts_config_is_visible(c.oid)");
+
+ appendPQExpBuffer(&buf, "ORDER BY 3, 2;");
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ if (PQntuples(res) == 0)
+ {
+ if (!pset.quiet)
+ fprintf(stderr, _("Did not find any text search configuration named \"%s\".\n"),
+ pattern);
+ PQclear(res);
+ return false;
+ }
+
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ const char *oid;
+ const char *cfgname;
+ const char *nspname = NULL;
+ const char *prsname;
+ const char *pnspname = NULL;
+
+ oid = PQgetvalue(res, i, 0);
+ cfgname = PQgetvalue(res, i, 1);
+ if (!PQgetisnull(res, i, 2))
+ nspname = PQgetvalue(res, i, 2);
+ prsname = PQgetvalue(res, i, 3);
+ if (!PQgetisnull(res, i, 4))
+ pnspname = PQgetvalue(res, i, 4);
+
+ if (!describeOneTSConfig(oid, nspname, cfgname, pnspname, prsname))
+ {
+ PQclear(res);
+ return false;
+ }
+
+ if (cancel_pressed)
+ {
+ PQclear(res);
+ return false;
+ }
+ }
+
+ PQclear(res);
+ return true;
+}
+
+static bool
+describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
+ const char *pnspname, const char *prsname)
+{
+ PQExpBufferData buf,
+ title;
+ PGresult *res;
+ printQueryOpt myopt = pset.popt;
+
+ initPQExpBuffer(&buf);
+
+ printfPQExpBuffer(&buf,
+ "SELECT \n"
+ " ( SELECT t.alias FROM \n"
+ " pg_catalog.ts_token_type(c.cfgparser) AS t \n"
+ " WHERE t.tokid = m.maptokentype ) AS \"%s\", \n"
+ " pg_catalog.btrim( \n"
+ " ARRAY( SELECT mm.mapdict::pg_catalog.regdictionary \n"
+ " FROM pg_catalog.pg_ts_config_map AS mm \n"
+ " WHERE mm.mapcfg = m.mapcfg AND mm.maptokentype = m.maptokentype \n"
+ " ORDER BY mapcfg, maptokentype, mapseqno \n"
+ " ) :: pg_catalog.text , \n"
+ " '{}') AS \"%s\" \n"
+ "FROM pg_catalog.pg_ts_config AS c, pg_catalog.pg_ts_config_map AS m \n"
+ "WHERE c.oid = '%s' AND m.mapcfg = c.oid \n"
+ "GROUP BY m.mapcfg, m.maptokentype, c.cfgparser \n"
+ "ORDER BY 1",
+ _("Token"),
+ _("Dictionaries"),
+ oid);
+
+ res = PSQLexec(buf.data, false);
+ termPQExpBuffer(&buf);
+ if (!res)
+ return false;
+
+ initPQExpBuffer(&title);
+
+ if (nspname)
+ appendPQExpBuffer(&title, _("Text search configuration \"%s.%s\""), nspname, cfgname);
+ else
+ appendPQExpBuffer(&title, _("Text search configuration \"%s\""), cfgname);
+
+ if (pnspname)
+ appendPQExpBuffer(&title, _("\nParser: \"%s.%s\""), pnspname, prsname);
+ else
+ appendPQExpBuffer(&title, _("\nParser: \"%s\""), prsname);
+
+ myopt.nullPrint = NULL;
+ myopt.title = title.data;
+ myopt.footers = NULL;
+ myopt.default_footer = false;
+
+ printQuery(res, &myopt, pset.queryFout, pset.logfile);
+
+ termPQExpBuffer(&title);
+
+ PQclear(res);
+ return true;
+}
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 88d355f57b2..1ba3b54fc14 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.33 2007/01/05 22:19:49 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.34 2007/08/21 01:11:22 tgl Exp $
*/
#ifndef DESCRIBE_H
#define DESCRIBE_H
@@ -36,6 +36,18 @@ extern bool objectDescription(const char *pattern);
/* \d foo */
extern bool describeTableDetails(const char *pattern, bool verbose);
+/* \dF */
+extern bool listTSConfigs(const char *pattern, bool verbose);
+
+/* \dFp */
+extern bool listTSParsers(const char *pattern, bool verbose);
+
+/* \dFd */
+extern bool listTSDictionaries(const char *pattern, bool verbose);
+
+/* \dFt */
+extern bool listTSTemplates(const char *pattern, bool verbose);
+
/* \l */
extern bool listAllDbs(bool verbose);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 027b5cb0207..b220339a498 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.117 2007/02/23 18:20:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.118 2007/08/21 01:11:22 tgl Exp $
*/
#include "postgres_fe.h"
@@ -219,6 +219,10 @@ slashUsage(unsigned short int pager)
fprintf(output, _(" \\dd [PATTERN] show comment for object\n"));
fprintf(output, _(" \\dD [PATTERN] list domains\n"));
fprintf(output, _(" \\df [PATTERN] list functions (add \"+\" for more detail)\n"));
+ fprintf(output, _(" \\dF [PATTERN] list text search configurations (add \"+\" for more detail)\n"));
+ fprintf(output, _(" \\dFd [PATTERN] list text search dictionaries (add \"+\" for more detail)\n"));
+ fprintf(output, _(" \\dFt [PATTERN] list text search templates\n"));
+ fprintf(output, _(" \\dFp [PATTERN] list text search parsers (add \"+\" for more detail)\n"));
fprintf(output, _(" \\dg [PATTERN] list groups\n"));
fprintf(output, _(" \\dn [PATTERN] list schemas (add \"+\" for more detail)\n"));
fprintf(output, _(" \\do [NAME] list operators\n"));
diff --git a/src/include/access/gin.h b/src/include/access/gin.h
index b22fbd1a089..ff76d886dd2 100644
--- a/src/include/access/gin.h
+++ b/src/include/access/gin.h
@@ -2,8 +2,9 @@
* gin.h
* header file for postgres inverted index access method implementation.
*
- * Copyright (c) 2006, PostgreSQL Global Development Group
- * $PostgreSQL: pgsql/src/include/access/gin.h,v 1.12 2007/07/25 12:22:53 mha Exp $
+ * Copyright (c) 2006-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/access/gin.h,v 1.13 2007/08/21 01:11:22 tgl Exp $
*--------------------------------------------------------------------------
*/
@@ -430,6 +431,7 @@ extern Datum ginvacuumcleanup(PG_FUNCTION_ARGS);
/* ginarrayproc.c */
extern Datum ginarrayextract(PG_FUNCTION_ARGS);
+extern Datum ginqueryarrayextract(PG_FUNCTION_ARGS);
extern Datum ginarrayconsistent(PG_FUNCTION_ARGS);
/* ginbulk.c */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index e2bd4ec316d..a050ff1d3cc 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.415 2007/07/25 22:16:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.416 2007/08/21 01:11:22 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200707251
+#define CATALOG_VERSION_NO 200708201
#endif
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index 4196e5b4ad7..6a00f2c4fb9 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.29 2007/01/05 22:19:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/dependency.h,v 1.30 2007/08/21 01:11:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -137,6 +137,10 @@ typedef enum ObjectClass
OCLASS_REWRITE, /* pg_rewrite */
OCLASS_TRIGGER, /* pg_trigger */
OCLASS_SCHEMA, /* pg_namespace */
+ OCLASS_TSPARSER, /* pg_ts_parser */
+ OCLASS_TSDICT, /* pg_ts_dict */
+ OCLASS_TSTEMPLATE, /* pg_ts_template */
+ OCLASS_TSCONFIG, /* pg_ts_config */
OCLASS_ROLE, /* pg_authid */
OCLASS_DATABASE, /* pg_database */
OCLASS_TBLSPACE, /* pg_tablespace */
@@ -176,6 +180,10 @@ extern void add_exact_object_address(const ObjectAddress *object,
extern bool object_address_present(const ObjectAddress *object,
ObjectAddresses *addrs);
+extern void record_object_address_dependencies(const ObjectAddress *depender,
+ ObjectAddresses *referenced,
+ DependencyType behavior);
+
extern void free_object_addresses(ObjectAddresses *addrs);
/* in pg_depend.c */
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index 71970d48f74..4859778f935 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.99 2007/04/02 03:49:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.100 2007/08/21 01:11:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -224,6 +224,29 @@ DECLARE_UNIQUE_INDEX(pg_trigger_tgrelid_tgname_index, 2701, on pg_trigger using
DECLARE_UNIQUE_INDEX(pg_trigger_oid_index, 2702, on pg_trigger using btree(oid oid_ops));
#define TriggerOidIndexId 2702
+DECLARE_UNIQUE_INDEX(pg_ts_config_cfgname_index, 3608, on pg_ts_config using btree(cfgname name_ops, cfgnamespace oid_ops));
+#define TSConfigNameNspIndexId 3608
+DECLARE_UNIQUE_INDEX(pg_ts_config_oid_index, 3712, on pg_ts_config using btree(oid oid_ops));
+#define TSConfigOidIndexId 3712
+
+DECLARE_UNIQUE_INDEX(pg_ts_config_map_index, 3609, on pg_ts_config_map using btree(mapcfg oid_ops, maptokentype int4_ops, mapseqno int4_ops));
+#define TSConfigMapIndexId 3609
+
+DECLARE_UNIQUE_INDEX(pg_ts_dict_dictname_index, 3604, on pg_ts_dict using btree(dictname name_ops, dictnamespace oid_ops));
+#define TSDictionaryNameNspIndexId 3604
+DECLARE_UNIQUE_INDEX(pg_ts_dict_oid_index, 3605, on pg_ts_dict using btree(oid oid_ops));
+#define TSDictionaryOidIndexId 3605
+
+DECLARE_UNIQUE_INDEX(pg_ts_parser_prsname_index, 3606, on pg_ts_parser using btree(prsname name_ops, prsnamespace oid_ops));
+#define TSParserNameNspIndexId 3606
+DECLARE_UNIQUE_INDEX(pg_ts_parser_oid_index, 3607, on pg_ts_parser using btree(oid oid_ops));
+#define TSParserOidIndexId 3607
+
+DECLARE_UNIQUE_INDEX(pg_ts_template_tmplname_index, 3766, on pg_ts_template using btree(tmplname name_ops, tmplnamespace oid_ops));
+#define TSTemplateNameNspIndexId 3766
+DECLARE_UNIQUE_INDEX(pg_ts_template_oid_index, 3767, on pg_ts_template using btree(oid oid_ops));
+#define TSTemplateOidIndexId 3767
+
DECLARE_UNIQUE_INDEX(pg_type_oid_index, 2703, on pg_type using btree(oid oid_ops));
#define TypeOidIndexId 2703
DECLARE_UNIQUE_INDEX(pg_type_typname_nsp_index, 2704, on pg_type using btree(typname name_ops, typnamespace oid_ops));
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index f937a729060..a486df1c797 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.48 2007/07/25 22:16:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/namespace.h,v 1.49 2007/08/21 01:11:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,7 +30,7 @@ typedef struct _FuncCandidateList
Oid oid; /* the function or operator's OID */
int nargs; /* number of arg types returned */
Oid args[1]; /* arg types --- VARIABLE LENGTH ARRAY */
-} *FuncCandidateList; /* VARIABLE LENGTH STRUCT */
+} *FuncCandidateList; /* VARIABLE LENGTH STRUCT */
/*
* Structure for xxxOverrideSearchPath functions
@@ -67,6 +67,18 @@ extern bool OpfamilyIsVisible(Oid opfid);
extern Oid ConversionGetConid(const char *conname);
extern bool ConversionIsVisible(Oid conid);
+extern Oid TSParserGetPrsid(List *names, bool failOK);
+extern bool TSParserIsVisible(Oid prsId);
+
+extern Oid TSDictionaryGetDictid(List *names, bool failOK);
+extern bool TSDictionaryIsVisible(Oid dictId);
+
+extern Oid TSTemplateGetTmplid(List *names, bool failOK);
+extern bool TSTemplateIsVisible(Oid tmplId);
+
+extern Oid TSConfigGetCfgid(List *names, bool failOK);
+extern bool TSConfigIsVisible(Oid cfgid);
+
extern void DeconstructQualifiedName(List *names,
char **nspname_p,
char **objname_p);
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index 0ee798b356e..a459e3b0d49 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_aggregate.h,v 1.62 2007/04/02 03:49:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_aggregate.h,v 1.63 2007/08/21 01:11:25 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -226,6 +226,9 @@ DATA(insert ( 2243 bitor - 0 1560 _null_ ));
/* xml */
DATA(insert ( 2901 xmlconcat2 - 0 142 _null_ ));
+/* text search */
+DATA(insert ( 3688 ts_rewrite_accum ts_rewrite_finish 0 3615 _null_ ));
+
/*
* prototypes for functions in pg_aggregate.c
*/
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 26b2ffe4ede..ac0a2ed8689 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -29,7 +29,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.81 2007/05/08 18:56:47 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.82 2007/08/21 01:11:25 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -652,4 +652,39 @@ DATA(insert ( 3522 3500 3500 5 f 3519 403 ));
*/
DATA(insert ( 3523 3500 3500 1 f 3516 405 ));
+/*
+ * btree tsvector_ops
+ */
+DATA(insert ( 3626 3614 3614 1 f 3627 403 ));
+DATA(insert ( 3626 3614 3614 2 f 3628 403 ));
+DATA(insert ( 3626 3614 3614 3 f 3629 403 ));
+DATA(insert ( 3626 3614 3614 4 f 3631 403 ));
+DATA(insert ( 3626 3614 3614 5 f 3632 403 ));
+
+/*
+ * GiST tsvector_ops
+ */
+DATA(insert ( 3655 3614 3615 1 t 3636 783 ));
+
+/*
+ * GIN tsvector_ops
+ */
+DATA(insert ( 3659 3614 3615 1 f 3636 2742 ));
+DATA(insert ( 3659 3614 3615 2 t 3660 2742 ));
+
+/*
+ * btree tsquery_ops
+ */
+DATA(insert ( 3683 3615 3615 1 f 3674 403 ));
+DATA(insert ( 3683 3615 3615 2 f 3675 403 ));
+DATA(insert ( 3683 3615 3615 3 f 3676 403 ));
+DATA(insert ( 3683 3615 3615 4 f 3678 403 ));
+DATA(insert ( 3683 3615 3615 5 f 3679 403 ));
+
+/*
+ * GiST tsquery_ops
+ */
+DATA(insert ( 3702 3615 3615 7 t 3693 783 ));
+DATA(insert ( 3702 3615 3615 8 t 3694 783 ));
+
#endif /* PG_AMOP_H */
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index c31a09f2243..a89ed470606 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -22,7 +22,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.66 2007/07/06 04:15:59 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.67 2007/08/21 01:11:25 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -189,119 +189,140 @@ DATA(insert ( 2595 718 718 4 2580 ));
DATA(insert ( 2595 718 718 5 2581 ));
DATA(insert ( 2595 718 718 6 2582 ));
DATA(insert ( 2595 718 718 7 2584 ));
+DATA(insert ( 3655 3614 3614 1 3654 ));
+DATA(insert ( 3655 3614 3614 2 3651 ));
+DATA(insert ( 3655 3614 3614 3 3648 ));
+DATA(insert ( 3655 3614 3614 4 3649 ));
+DATA(insert ( 3655 3614 3614 5 3653 ));
+DATA(insert ( 3655 3614 3614 6 3650 ));
+DATA(insert ( 3655 3614 3614 7 3652 ));
+DATA(insert ( 3702 3615 3615 1 3701 ));
+DATA(insert ( 3702 3615 3615 2 3698 ));
+DATA(insert ( 3702 3615 3615 3 3695 ));
+DATA(insert ( 3702 3615 3615 4 3696 ));
+DATA(insert ( 3702 3615 3615 5 3700 ));
+DATA(insert ( 3702 3615 3615 6 3697 ));
+DATA(insert ( 3702 3615 3615 7 3699 ));
+
/* gin */
DATA(insert ( 2745 1007 1007 1 351 ));
DATA(insert ( 2745 1007 1007 2 2743 ));
-DATA(insert ( 2745 1007 1007 3 2743 ));
+DATA(insert ( 2745 1007 1007 3 2774 ));
DATA(insert ( 2745 1007 1007 4 2744 ));
DATA(insert ( 2745 1009 1009 1 360 ));
DATA(insert ( 2745 1009 1009 2 2743 ));
-DATA(insert ( 2745 1009 1009 3 2743 ));
+DATA(insert ( 2745 1009 1009 3 2774 ));
DATA(insert ( 2745 1009 1009 4 2744 ));
DATA(insert ( 2745 1023 1023 1 357 ));
DATA(insert ( 2745 1023 1023 2 2743 ));
-DATA(insert ( 2745 1023 1023 3 2743 ));
+DATA(insert ( 2745 1023 1023 3 2774 ));
DATA(insert ( 2745 1023 1023 4 2744 ));
DATA(insert ( 2745 1561 1561 1 1596 ));
DATA(insert ( 2745 1561 1561 2 2743 ));
-DATA(insert ( 2745 1561 1561 3 2743 ));
+DATA(insert ( 2745 1561 1561 3 2774 ));
DATA(insert ( 2745 1561 1561 4 2744 ));
DATA(insert ( 2745 1000 1000 1 1693 ));
DATA(insert ( 2745 1000 1000 2 2743 ));
-DATA(insert ( 2745 1000 1000 3 2743 ));
+DATA(insert ( 2745 1000 1000 3 2774 ));
DATA(insert ( 2745 1000 1000 4 2744 ));
DATA(insert ( 2745 1014 1014 1 1078 ));
DATA(insert ( 2745 1014 1014 2 2743 ));
-DATA(insert ( 2745 1014 1014 3 2743 ));
+DATA(insert ( 2745 1014 1014 3 2774 ));
DATA(insert ( 2745 1014 1014 4 2744 ));
DATA(insert ( 2745 1001 1001 1 1954 ));
DATA(insert ( 2745 1001 1001 2 2743 ));
-DATA(insert ( 2745 1001 1001 3 2743 ));
+DATA(insert ( 2745 1001 1001 3 2774 ));
DATA(insert ( 2745 1001 1001 4 2744 ));
DATA(insert ( 2745 1002 1002 1 358 ));
DATA(insert ( 2745 1002 1002 2 2743 ));
-DATA(insert ( 2745 1002 1002 3 2743 ));
+DATA(insert ( 2745 1002 1002 3 2774 ));
DATA(insert ( 2745 1002 1002 4 2744 ));
DATA(insert ( 2745 1182 1182 1 1092 ));
DATA(insert ( 2745 1182 1182 2 2743 ));
-DATA(insert ( 2745 1182 1182 3 2743 ));
+DATA(insert ( 2745 1182 1182 3 2774 ));
DATA(insert ( 2745 1182 1182 4 2744 ));
DATA(insert ( 2745 1021 1021 1 354 ));
DATA(insert ( 2745 1021 1021 2 2743 ));
-DATA(insert ( 2745 1021 1021 3 2743 ));
+DATA(insert ( 2745 1021 1021 3 2774 ));
DATA(insert ( 2745 1021 1021 4 2744 ));
DATA(insert ( 2745 1022 1022 1 355 ));
DATA(insert ( 2745 1022 1022 2 2743 ));
-DATA(insert ( 2745 1022 1022 3 2743 ));
+DATA(insert ( 2745 1022 1022 3 2774 ));
DATA(insert ( 2745 1022 1022 4 2744 ));
DATA(insert ( 2745 1041 1041 1 926 ));
DATA(insert ( 2745 1041 1041 2 2743 ));
-DATA(insert ( 2745 1041 1041 3 2743 ));
+DATA(insert ( 2745 1041 1041 3 2774 ));
DATA(insert ( 2745 1041 1041 4 2744 ));
DATA(insert ( 2745 1005 1005 1 350 ));
DATA(insert ( 2745 1005 1005 2 2743 ));
-DATA(insert ( 2745 1005 1005 3 2743 ));
+DATA(insert ( 2745 1005 1005 3 2774 ));
DATA(insert ( 2745 1005 1005 4 2744 ));
DATA(insert ( 2745 1016 1016 1 842 ));
DATA(insert ( 2745 1016 1016 2 2743 ));
-DATA(insert ( 2745 1016 1016 3 2743 ));
+DATA(insert ( 2745 1016 1016 3 2774 ));
DATA(insert ( 2745 1016 1016 4 2744 ));
DATA(insert ( 2745 1187 1187 1 1315 ));
DATA(insert ( 2745 1187 1187 2 2743 ));
-DATA(insert ( 2745 1187 1187 3 2743 ));
+DATA(insert ( 2745 1187 1187 3 2774 ));
DATA(insert ( 2745 1187 1187 4 2744 ));
DATA(insert ( 2745 1040 1040 1 836 ));
DATA(insert ( 2745 1040 1040 2 2743 ));
-DATA(insert ( 2745 1040 1040 3 2743 ));
+DATA(insert ( 2745 1040 1040 3 2774 ));
DATA(insert ( 2745 1040 1040 4 2744 ));
DATA(insert ( 2745 1003 1003 1 359 ));
DATA(insert ( 2745 1003 1003 2 2743 ));
-DATA(insert ( 2745 1003 1003 3 2743 ));
+DATA(insert ( 2745 1003 1003 3 2774 ));
DATA(insert ( 2745 1003 1003 4 2744 ));
DATA(insert ( 2745 1231 1231 1 1769 ));
DATA(insert ( 2745 1231 1231 2 2743 ));
-DATA(insert ( 2745 1231 1231 3 2743 ));
+DATA(insert ( 2745 1231 1231 3 2774 ));
DATA(insert ( 2745 1231 1231 4 2744 ));
DATA(insert ( 2745 1028 1028 1 356 ));
DATA(insert ( 2745 1028 1028 2 2743 ));
-DATA(insert ( 2745 1028 1028 3 2743 ));
+DATA(insert ( 2745 1028 1028 3 2774 ));
DATA(insert ( 2745 1028 1028 4 2744 ));
DATA(insert ( 2745 1013 1013 1 404 ));
DATA(insert ( 2745 1013 1013 2 2743 ));
-DATA(insert ( 2745 1013 1013 3 2743 ));
+DATA(insert ( 2745 1013 1013 3 2774 ));
DATA(insert ( 2745 1013 1013 4 2744 ));
DATA(insert ( 2745 1183 1183 1 1107 ));
DATA(insert ( 2745 1183 1183 2 2743 ));
-DATA(insert ( 2745 1183 1183 3 2743 ));
+DATA(insert ( 2745 1183 1183 3 2774 ));
DATA(insert ( 2745 1183 1183 4 2744 ));
DATA(insert ( 2745 1185 1185 1 1314 ));
DATA(insert ( 2745 1185 1185 2 2743 ));
-DATA(insert ( 2745 1185 1185 3 2743 ));
+DATA(insert ( 2745 1185 1185 3 2774 ));
DATA(insert ( 2745 1185 1185 4 2744 ));
DATA(insert ( 2745 1270 1270 1 1358 ));
DATA(insert ( 2745 1270 1270 2 2743 ));
-DATA(insert ( 2745 1270 1270 3 2743 ));
+DATA(insert ( 2745 1270 1270 3 2774 ));
DATA(insert ( 2745 1270 1270 4 2744 ));
DATA(insert ( 2745 1563 1563 1 1672 ));
DATA(insert ( 2745 1563 1563 2 2743 ));
-DATA(insert ( 2745 1563 1563 3 2743 ));
+DATA(insert ( 2745 1563 1563 3 2774 ));
DATA(insert ( 2745 1563 1563 4 2744 ));
DATA(insert ( 2745 1115 1115 1 2045 ));
DATA(insert ( 2745 1115 1115 2 2743 ));
-DATA(insert ( 2745 1115 1115 3 2743 ));
+DATA(insert ( 2745 1115 1115 3 2774 ));
DATA(insert ( 2745 1115 1115 4 2744 ));
DATA(insert ( 2745 791 791 1 377 ));
DATA(insert ( 2745 791 791 2 2743 ));
-DATA(insert ( 2745 791 791 3 2743 ));
+DATA(insert ( 2745 791 791 3 2774 ));
DATA(insert ( 2745 791 791 4 2744 ));
DATA(insert ( 2745 1024 1024 1 380 ));
DATA(insert ( 2745 1024 1024 2 2743 ));
-DATA(insert ( 2745 1024 1024 3 2743 ));
+DATA(insert ( 2745 1024 1024 3 2774 ));
DATA(insert ( 2745 1024 1024 4 2744 ));
DATA(insert ( 2745 1025 1025 1 381 ));
DATA(insert ( 2745 1025 1025 2 2743 ));
-DATA(insert ( 2745 1025 1025 3 2743 ));
+DATA(insert ( 2745 1025 1025 3 2774 ));
DATA(insert ( 2745 1025 1025 4 2744 ));
+DATA(insert ( 3659 3614 3614 1 360 ));
+DATA(insert ( 3659 3614 3614 2 3656 ));
+DATA(insert ( 3659 3614 3614 3 3657 ));
+DATA(insert ( 3659 3614 3614 4 3658 ));
+DATA(insert ( 3626 3614 3614 1 3622 ));
+DATA(insert ( 3683 3615 3615 1 3668 ));
#endif /* PG_AMPROC_H */
diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index 82016774e80..2fe1cf03835 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -10,7 +10,7 @@
*
* Copyright (c) 2002-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.34 2007/06/05 21:31:07 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_cast.h,v 1.35 2007/08/21 01:11:25 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -169,6 +169,20 @@ DATA(insert ( 21 2206 313 i ));
DATA(insert ( 23 2206 0 i ));
DATA(insert ( 2206 20 1288 a ));
DATA(insert ( 2206 23 0 a ));
+DATA(insert ( 26 3734 0 i ));
+DATA(insert ( 3734 26 0 i ));
+DATA(insert ( 20 3734 1287 i ));
+DATA(insert ( 21 3734 313 i ));
+DATA(insert ( 23 3734 0 i ));
+DATA(insert ( 3734 20 1288 a ));
+DATA(insert ( 3734 23 0 a ));
+DATA(insert ( 26 3769 0 i ));
+DATA(insert ( 3769 26 0 i ));
+DATA(insert ( 20 3769 1287 i ));
+DATA(insert ( 21 3769 313 i ));
+DATA(insert ( 23 3769 0 i ));
+DATA(insert ( 3769 20 1288 a ));
+DATA(insert ( 3769 23 0 a ));
DATA(insert ( 25 2205 1079 i ));
DATA(insert ( 1043 2205 1079 i ));
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index 28fed113014..8674fe027cd 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -28,7 +28,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.76 2007/05/08 18:56:47 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.77 2007/08/21 01:11:25 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -205,5 +205,10 @@ DATA(insert ( 403 uuid_ops PGNSP PGUID 2968 2950 t 0 ));
DATA(insert ( 405 uuid_ops PGNSP PGUID 2969 2950 t 0 ));
DATA(insert ( 403 enum_ops PGNSP PGUID 3522 3500 t 0 ));
DATA(insert ( 405 enum_ops PGNSP PGUID 3523 3500 t 0 ));
+DATA(insert ( 403 tsvector_ops PGNSP PGUID 3626 3614 t 0 ));
+DATA(insert ( 783 tsvector_ops PGNSP PGUID 3655 3614 t 3642 ));
+DATA(insert ( 2742 tsvector_ops PGNSP PGUID 3659 3614 t 25 ));
+DATA(insert ( 403 tsquery_ops PGNSP PGUID 3683 3615 t 0 ));
+DATA(insert ( 783 tsquery_ops PGNSP PGUID 3702 3615 t 20 ));
#endif /* PG_OPCLASS_H */
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index e3b2910eb22..4b6f2575574 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.153 2007/06/06 23:00:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.154 2007/08/21 01:11:25 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -915,6 +915,34 @@ DATA(insert OID = 3519 ( ">" PGNSP PGUID b f f 3500 3500 16 3518 3520 enum_g
DATA(insert OID = 3520 ( "<=" PGNSP PGUID b f f 3500 3500 16 3521 3519 enum_le scalarltsel scalarltjoinsel ));
DATA(insert OID = 3521 ( ">=" PGNSP PGUID b f f 3500 3500 16 3520 3518 enum_ge scalargtsel scalargtjoinsel ));
+/*
+ * tsearch operations
+ */
+DATA(insert OID = 3627 ( "<" PGNSP PGUID b f f 3614 3614 16 3632 3631 tsvector_lt scalarltsel scalarltjoinsel ));
+DATA(insert OID = 3628 ( "<=" PGNSP PGUID b f f 3614 3614 16 3631 3632 tsvector_le scalarltsel scalarltjoinsel ));
+DATA(insert OID = 3629 ( "=" PGNSP PGUID b t f 3614 3614 16 3629 3630 tsvector_eq eqsel eqjoinsel ));
+DATA(insert OID = 3630 ( "<>" PGNSP PGUID b f f 3614 3614 16 3630 3629 tsvector_ne neqsel neqjoinsel ));
+DATA(insert OID = 3631 ( ">=" PGNSP PGUID b f f 3614 3614 16 3628 3627 tsvector_ge scalargtsel scalargtjoinsel ));
+DATA(insert OID = 3632 ( ">" PGNSP PGUID b f f 3614 3614 16 3627 3628 tsvector_gt scalargtsel scalargtjoinsel ));
+DATA(insert OID = 3633 ( "||" PGNSP PGUID b f f 3614 3614 3614 0 0 tsvector_concat - - ));
+DATA(insert OID = 3636 ( "@@" PGNSP PGUID b f f 3614 3615 16 3637 0 ts_match_vq contsel contjoinsel ));
+DATA(insert OID = 3637 ( "@@" PGNSP PGUID b f f 3615 3614 16 3636 0 ts_match_qv contsel contjoinsel ));
+DATA(insert OID = 3660 ( "@@@" PGNSP PGUID b f f 3614 3615 16 3661 0 ts_match_vq contsel contjoinsel ));
+DATA(insert OID = 3661 ( "@@@" PGNSP PGUID b f f 3615 3614 16 3660 0 ts_match_qv contsel contjoinsel ));
+DATA(insert OID = 3674 ( "<" PGNSP PGUID b f f 3615 3615 16 3679 3678 tsquery_lt scalarltsel scalarltjoinsel ));
+DATA(insert OID = 3675 ( "<=" PGNSP PGUID b f f 3615 3615 16 3678 3679 tsquery_le scalarltsel scalarltjoinsel ));
+DATA(insert OID = 3676 ( "=" PGNSP PGUID b t f 3615 3615 16 3676 3677 tsquery_eq eqsel eqjoinsel ));
+DATA(insert OID = 3677 ( "<>" PGNSP PGUID b f f 3615 3615 16 3677 3676 tsquery_ne neqsel neqjoinsel ));
+DATA(insert OID = 3678 ( ">=" PGNSP PGUID b f f 3615 3615 16 3675 3674 tsquery_ge scalargtsel scalargtjoinsel ));
+DATA(insert OID = 3679 ( ">" PGNSP PGUID b f f 3615 3615 16 3674 3675 tsquery_gt scalargtsel scalargtjoinsel ));
+DATA(insert OID = 3680 ( "&&" PGNSP PGUID b f f 3615 3615 3615 0 0 tsquery_and - - ));
+DATA(insert OID = 3681 ( "||" PGNSP PGUID b f f 3615 3615 3615 0 0 tsquery_or - - ));
+DATA(insert OID = 3682 ( "!!" PGNSP PGUID l f f 0 3615 3615 0 0 tsquery_not - - ));
+DATA(insert OID = 3693 ( "@>" PGNSP PGUID b f f 3615 3615 16 3694 0 tsq_mcontains contsel contjoinsel ));
+DATA(insert OID = 3694 ( "<@" PGNSP PGUID b f f 3615 3615 16 3693 0 tsq_mcontained contsel contjoinsel ));
+DATA(insert OID = 3762 ( "@@" PGNSP PGUID b f f 25 25 16 0 0 ts_match_tt contsel contjoinsel ));
+DATA(insert OID = 3763 ( "@@" PGNSP PGUID b f f 25 3615 16 0 0 ts_match_tq contsel contjoinsel ));
+
/*
* function prototypes
diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h
index a39e28c632d..702ec8d6e3e 100644
--- a/src/include/catalog/pg_opfamily.h
+++ b/src/include/catalog/pg_opfamily.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_opfamily.h,v 1.5 2007/05/08 18:56:47 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_opfamily.h,v 1.6 2007/08/21 01:11:25 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -27,7 +27,7 @@
*/
/* ----------------
- * pg_opfamily definition. cpp turns this into
+ * pg_opfamily definition. cpp turns this into
* typedef struct FormData_pg_opfamily
* ----------------
*/
@@ -139,6 +139,10 @@ DATA(insert OID = 2968 ( 403 uuid_ops PGNSP PGUID ));
DATA(insert OID = 2969 ( 405 uuid_ops PGNSP PGUID ));
DATA(insert OID = 3522 ( 403 enum_ops PGNSP PGUID ));
DATA(insert OID = 3523 ( 405 enum_ops PGNSP PGUID ));
-
+DATA(insert OID = 3626 ( 403 tsvector_ops PGNSP PGUID ));
+DATA(insert OID = 3655 ( 783 tsvector_ops PGNSP PGUID ));
+DATA(insert OID = 3659 ( 2742 tsvector_ops PGNSP PGUID ));
+DATA(insert OID = 3683 ( 403 tsquery_ops PGNSP PGUID ));
+DATA(insert OID = 3702 ( 783 tsquery_ops PGNSP PGUID ));
#endif /* PG_OPFAMILY_H */
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 024be90487b..1a624c6dbe0 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.462 2007/07/06 04:15:59 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.463 2007/08/21 01:11:25 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
@@ -3124,6 +3124,15 @@ DATA(insert OID = 2083 ( pg_opclass_is_visible PGNSP PGUID 12 1 0 f f t f s 1
DESCR("is opclass visible in search path?");
DATA(insert OID = 2093 ( pg_conversion_is_visible PGNSP PGUID 12 1 0 f f t f s 1 16 "26" _null_ _null_ _null_ pg_conversion_is_visible - _null_ ));
DESCR("is conversion visible in search path?");
+DATA(insert OID = 3756 ( pg_ts_parser_is_visible PGNSP PGUID 12 1 0 f f t f s 1 16 "26" _null_ _null_ _null_ pg_ts_parser_is_visible - _null_ ));
+DESCR("is text search parser visible in search path?");
+DATA(insert OID = 3757 ( pg_ts_dict_is_visible PGNSP PGUID 12 1 0 f f t f s 1 16 "26" _null_ _null_ _null_ pg_ts_dict_is_visible - _null_ ));
+DESCR("is text search dictionary visible in search path?");
+DATA(insert OID = 3768 ( pg_ts_template_is_visible PGNSP PGUID 12 1 0 f f t f s 1 16 "26" _null_ _null_ _null_ pg_ts_template_is_visible - _null_ ));
+DESCR("is text search template visible in search path?");
+DATA(insert OID = 3758 ( pg_ts_config_is_visible PGNSP PGUID 12 1 0 f f t f s 1 16 "26" _null_ _null_ _null_ pg_ts_config_is_visible - _null_ ));
+DESCR("is text search configuration visible in search path?");
+
DATA(insert OID = 2854 ( pg_my_temp_schema PGNSP PGUID 12 1 0 f f t f s 0 26 "" _null_ _null_ _null_ pg_my_temp_schema - _null_ ));
DESCR("get OID of current session's temp schema, if any");
DATA(insert OID = 2855 ( pg_is_other_temp_schema PGNSP PGUID 12 1 0 f f t f s 1 16 "26" _null_ _null_ _null_ pg_is_other_temp_schema - _null_ ));
@@ -3969,6 +3978,8 @@ DESCR("gin(internal)");
/* GIN array support */
DATA(insert OID = 2743 ( ginarrayextract PGNSP PGUID 12 1 0 f f t f i 2 2281 "2277 2281" _null_ _null_ _null_ ginarrayextract - _null_ ));
DESCR("GIN array support");
+DATA(insert OID = 2774 ( ginqueryarrayextract PGNSP PGUID 12 1 0 f f t f i 3 2281 "2277 2281 21" _null_ _null_ _null_ ginqueryarrayextract - _null_ ));
+DESCR("GIN array support");
DATA(insert OID = 2744 ( ginarrayconsistent PGNSP PGUID 12 1 0 f f t f i 3 16 "2281 21 2281" _null_ _null_ _null_ ginarrayconsistent - _null_ ));
DESCR("GIN array support");
@@ -4128,6 +4139,257 @@ DATA(insert OID = 3529 ( enum_last PGNSP PGUID 12 1 0 f f f f s 1 3500 "3500"
DATA(insert OID = 3530 ( enum_range PGNSP PGUID 12 1 0 f f f f s 2 2277 "3500 3500" _null_ _null_ _null_ enum_range_bounds - _null_ ));
DATA(insert OID = 3531 ( enum_range PGNSP PGUID 12 1 0 f f f f s 1 2277 "3500" _null_ _null_ _null_ enum_range_all - _null_ ));
+/* text search stuff */
+DATA(insert OID = 3610 ( tsvectorin PGNSP PGUID 12 1 0 f f t f i 1 3614 "2275" _null_ _null_ _null_ tsvectorin - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3639 ( tsvectorrecv PGNSP PGUID 12 1 0 f f t f i 1 3614 "2281" _null_ _null_ _null_ tsvectorrecv - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3611 ( tsvectorout PGNSP PGUID 12 1 0 f f t f i 1 2275 "3614" _null_ _null_ _null_ tsvectorout - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3638 ( tsvectorsend PGNSP PGUID 12 1 0 f f t f i 1 17 "3614" _null_ _null_ _null_ tsvectorsend - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3612 ( tsqueryin PGNSP PGUID 12 1 0 f f t f i 1 3615 "2275" _null_ _null_ _null_ tsqueryin - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3641 ( tsqueryrecv PGNSP PGUID 12 1 0 f f t f i 1 3615 "2281" _null_ _null_ _null_ tsqueryrecv - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3613 ( tsqueryout PGNSP PGUID 12 1 0 f f t f i 1 2275 "3615" _null_ _null_ _null_ tsqueryout - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3640 ( tsquerysend PGNSP PGUID 12 1 0 f f t f i 1 17 "3615" _null_ _null_ _null_ tsquerysend - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3646 ( gtsvectorin PGNSP PGUID 12 1 0 f f t f i 1 3642 "2275" _null_ _null_ _null_ gtsvectorin - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3647 ( gtsvectorout PGNSP PGUID 12 1 0 f f t f i 1 2275 "3642" _null_ _null_ _null_ gtsvectorout - _null_ ));
+DESCR("I/O");
+
+DATA(insert OID = 3616 ( tsvector_lt PGNSP PGUID 12 1 0 f f t f i 2 16 "3614 3614" _null_ _null_ _null_ tsvector_lt - _null_ ));
+DESCR("less-than");
+DATA(insert OID = 3617 ( tsvector_le PGNSP PGUID 12 1 0 f f t f i 2 16 "3614 3614" _null_ _null_ _null_ tsvector_le - _null_ ));
+DESCR("less-than-or-equal");
+DATA(insert OID = 3618 ( tsvector_eq PGNSP PGUID 12 1 0 f f t f i 2 16 "3614 3614" _null_ _null_ _null_ tsvector_eq - _null_ ));
+DESCR("equal");
+DATA(insert OID = 3619 ( tsvector_ne PGNSP PGUID 12 1 0 f f t f i 2 16 "3614 3614" _null_ _null_ _null_ tsvector_ne - _null_ ));
+DESCR("not equal");
+DATA(insert OID = 3620 ( tsvector_ge PGNSP PGUID 12 1 0 f f t f i 2 16 "3614 3614" _null_ _null_ _null_ tsvector_ge - _null_ ));
+DESCR("greater-than-or-equal");
+DATA(insert OID = 3621 ( tsvector_gt PGNSP PGUID 12 1 0 f f t f i 2 16 "3614 3614" _null_ _null_ _null_ tsvector_gt - _null_ ));
+DESCR("greater-than");
+DATA(insert OID = 3622 ( tsvector_cmp PGNSP PGUID 12 1 0 f f t f i 2 23 "3614 3614" _null_ _null_ _null_ tsvector_cmp - _null_ ));
+DESCR("btree less-equal-greater");
+
+DATA(insert OID = 3711 ( length PGNSP PGUID 12 1 0 f f t f i 1 23 "3614" _null_ _null_ _null_ tsvector_length - _null_ ));
+DESCR("number of lexemes");
+DATA(insert OID = 3623 ( strip PGNSP PGUID 12 1 0 f f t f i 1 3614 "3614" _null_ _null_ _null_ tsvector_strip - _null_ ));
+DESCR("strip position information");
+DATA(insert OID = 3624 ( setweight PGNSP PGUID 12 1 0 f f t f i 2 3614 "3614 18" _null_ _null_ _null_ tsvector_setweight - _null_ ));
+DESCR("set weight of lexeme's entries");
+DATA(insert OID = 3625 ( tsvector_concat PGNSP PGUID 12 1 0 f f t f i 2 3614 "3614 3614" _null_ _null_ _null_ tsvector_concat - _null_ ));
+DESCR("concatenate");
+
+DATA(insert OID = 3634 ( ts_match_vq PGNSP PGUID 12 1 0 f f t f i 2 16 "3614 3615" _null_ _null_ _null_ ts_match_vq - _null_ ));
+DESCR("match tsvector to tsquery");
+DATA(insert OID = 3635 ( ts_match_qv PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3614" _null_ _null_ _null_ ts_match_qv - _null_ ));
+DESCR("match tsquery to tsvector");
+DATA(insert OID = 3760 ( ts_match_tt PGNSP PGUID 12 3 0 f f t f s 2 16 "25 25" _null_ _null_ _null_ ts_match_tt - _null_ ));
+DESCR("text search match");
+DATA(insert OID = 3761 ( ts_match_tq PGNSP PGUID 12 2 0 f f t f s 2 16 "25 3615" _null_ _null_ _null_ ts_match_tq - _null_ ));
+DESCR("match text to tsquery");
+
+DATA(insert OID = 3648 ( gtsvector_compress PGNSP PGUID 12 1 0 f f t f i 1 2281 "2281" _null_ _null_ _null_ gtsvector_compress - _null_ ));
+DESCR("GiST tsvector support");
+DATA(insert OID = 3649 ( gtsvector_decompress PGNSP PGUID 12 1 0 f f t f i 1 2281 "2281" _null_ _null_ _null_ gtsvector_decompress - _null_ ));
+DESCR("GiST tsvector support");
+DATA(insert OID = 3650 ( gtsvector_picksplit PGNSP PGUID 12 1 0 f f t f i 2 2281 "2281 2281" _null_ _null_ _null_ gtsvector_picksplit - _null_ ));
+DESCR("GiST tsvector support");
+DATA(insert OID = 3651 ( gtsvector_union PGNSP PGUID 12 1 0 f f t f i 2 2281 "2281 2281" _null_ _null_ _null_ gtsvector_union - _null_ ));
+DESCR("GiST tsvector support");
+DATA(insert OID = 3652 ( gtsvector_same PGNSP PGUID 12 1 0 f f t f i 3 2281 "3642 3642 2281" _null_ _null_ _null_ gtsvector_same - _null_ ));
+DESCR("GiST tsvector support");
+DATA(insert OID = 3653 ( gtsvector_penalty PGNSP PGUID 12 1 0 f f t f i 3 2281 "2281 2281 2281" _null_ _null_ _null_ gtsvector_penalty - _null_ ));
+DESCR("GiST tsvector support");
+DATA(insert OID = 3654 ( gtsvector_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "3642 2281 23" _null_ _null_ _null_ gtsvector_consistent - _null_ ));
+DESCR("GiST tsvector support");
+
+DATA(insert OID = 3656 ( gin_extract_tsvector PGNSP PGUID 12 1 0 f f t f i 2 2281 "3614 2281" _null_ _null_ _null_ gin_extract_tsvector - _null_ ));
+DESCR("GIN tsvector support");
+DATA(insert OID = 3657 ( gin_extract_query PGNSP PGUID 12 1 0 f f t f i 3 2281 "2281 2281 21" _null_ _null_ _null_ gin_extract_query - _null_ ));
+DESCR("GIN tsvector support");
+DATA(insert OID = 3658 ( gin_ts_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "2281 21 2281" _null_ _null_ _null_ gin_ts_consistent - _null_ ));
+DESCR("GIN tsvector support");
+
+DATA(insert OID = 3662 ( tsquery_lt PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsquery_lt - _null_ ));
+DESCR("less-than");
+DATA(insert OID = 3663 ( tsquery_le PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsquery_le - _null_ ));
+DESCR("less-than-or-equal");
+DATA(insert OID = 3664 ( tsquery_eq PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsquery_eq - _null_ ));
+DESCR("equal");
+DATA(insert OID = 3665 ( tsquery_ne PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsquery_ne - _null_ ));
+DESCR("not equal");
+DATA(insert OID = 3666 ( tsquery_ge PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsquery_ge - _null_ ));
+DESCR("greater-than-or-equal");
+DATA(insert OID = 3667 ( tsquery_gt PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsquery_gt - _null_ ));
+DESCR("greater-than");
+DATA(insert OID = 3668 ( tsquery_cmp PGNSP PGUID 12 1 0 f f t f i 2 23 "3615 3615" _null_ _null_ _null_ tsquery_cmp - _null_ ));
+DESCR("btree less-equal-greater");
+
+DATA(insert OID = 3669 ( tsquery_and PGNSP PGUID 12 1 0 f f t f i 2 3615 "3615 3615" _null_ _null_ _null_ tsquery_and - _null_ ));
+DESCR("AND-concatenate");
+DATA(insert OID = 3670 ( tsquery_or PGNSP PGUID 12 1 0 f f t f i 2 3615 "3615 3615" _null_ _null_ _null_ tsquery_or - _null_ ));
+DESCR("OR-concatenate");
+DATA(insert OID = 3671 ( tsquery_not PGNSP PGUID 12 1 0 f f t f i 1 3615 "3615" _null_ _null_ _null_ tsquery_not - _null_ ));
+DESCR("NOT-tsquery");
+
+DATA(insert OID = 3691 ( tsq_mcontains PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsq_mcontains - _null_ ));
+DESCR("contains");
+DATA(insert OID = 3692 ( tsq_mcontained PGNSP PGUID 12 1 0 f f t f i 2 16 "3615 3615" _null_ _null_ _null_ tsq_mcontained - _null_ ));
+DESCR("contained");
+
+DATA(insert OID = 3672 ( numnode PGNSP PGUID 12 1 0 f f t f i 1 23 "3615" _null_ _null_ _null_ tsquery_numnode - _null_ ));
+DESCR("number of nodes");
+DATA(insert OID = 3673 ( querytree PGNSP PGUID 12 1 0 f f t f i 1 25 "3615" _null_ _null_ _null_ tsquerytree - _null_ ));
+DESCR("show real useful query for GiST index");
+
+DATA(insert OID = 3684 ( ts_rewrite PGNSP PGUID 12 1 0 f f t f i 3 3615 "3615 3615 3615" _null_ _null_ _null_ tsquery_rewrite_query - _null_ ));
+DESCR("rewrite tsquery");
+DATA(insert OID = 3685 ( ts_rewrite PGNSP PGUID 12 1 1000 f f t t v 2 3615 "3615 25" _null_ _null_ _null_ tsquery_rewrite - _null_ ));
+DESCR("rewrite tsquery");
+DATA(insert OID = 3686 ( ts_rewrite_accum PGNSP PGUID 12 1 0 f f f f i 2 3615 "3615 3645" _null_ _null_ _null_ ts_rewrite_accum - _null_ ));
+DESCR("rewrite tsquery accumulator");
+DATA(insert OID = 3687 ( ts_rewrite_finish PGNSP PGUID 12 1 0 f f t f i 1 3615 "3615" _null_ _null_ _null_ ts_rewrite_finish - _null_ ));
+DESCR("rewrite tsquery finish");
+DATA(insert OID = 3688 ( ts_rewrite PGNSP PGUID 12 1 0 t f f f i 1 3615 "3645" _null_ _null_ _null_ aggregate_dummy - _null_ ));
+DESCR("rewrite tsquery");
+
+DATA(insert OID = 3695 ( gtsquery_compress PGNSP PGUID 12 1 0 f f t f i 1 2281 "2281" _null_ _null_ _null_ gtsquery_compress - _null_ ));
+DESCR("GiST tsquery support");
+DATA(insert OID = 3696 ( gtsquery_decompress PGNSP PGUID 12 1 0 f f t f i 1 2281 "2281" _null_ _null_ _null_ gtsquery_decompress - _null_ ));
+DESCR("GiST tsquery support");
+DATA(insert OID = 3697 ( gtsquery_picksplit PGNSP PGUID 12 1 0 f f t f i 2 2281 "2281 2281" _null_ _null_ _null_ gtsquery_picksplit - _null_ ));
+DESCR("GiST tsquery support");
+DATA(insert OID = 3698 ( gtsquery_union PGNSP PGUID 12 1 0 f f t f i 2 2281 "2281 2281" _null_ _null_ _null_ gtsquery_union - _null_ ));
+DESCR("GiST tsquery support");
+DATA(insert OID = 3699 ( gtsquery_same PGNSP PGUID 12 1 0 f f t f i 3 2281 "20 20 2281" _null_ _null_ _null_ gtsquery_same - _null_ ));
+DESCR("GiST tsquery support");
+DATA(insert OID = 3700 ( gtsquery_penalty PGNSP PGUID 12 1 0 f f t f i 3 2281 "2281 2281 2281" _null_ _null_ _null_ gtsquery_penalty - _null_ ));
+DESCR("GiST tsquery support");
+DATA(insert OID = 3701 ( gtsquery_consistent PGNSP PGUID 12 1 0 f f t f i 3 16 "20 2281 23" _null_ _null_ _null_ gtsquery_consistent - _null_ ));
+DESCR("GiST tsquery support");
+
+DATA(insert OID = 3689 ( ts_stat PGNSP PGUID 12 10 10000 f f t t v 1 2249 "25" "{25,25,23,23}" "{i,o,o,o}" "{query,word,ndoc,nentry}" ts_stat1 - _null_ ));
+DESCR("statistics of tsvector column");
+DATA(insert OID = 3690 ( ts_stat PGNSP PGUID 12 10 10000 f f t t v 2 2249 "25 25" "{25,25,25,23,23}" "{i,i,o,o,o}" "{query,weights,word,ndoc,nentry}" ts_stat2 - _null_ ));
+DESCR("statistics of tsvector column");
+
+DATA(insert OID = 3703 ( ts_rank PGNSP PGUID 12 1 0 f f t f i 4 700 "1021 3614 3615 23" _null_ _null_ _null_ ts_rank_wttf - _null_ ));
+DESCR("relevance");
+DATA(insert OID = 3704 ( ts_rank PGNSP PGUID 12 1 0 f f t f i 3 700 "1021 3614 3615" _null_ _null_ _null_ ts_rank_wtt - _null_ ));
+DESCR("relevance");
+DATA(insert OID = 3705 ( ts_rank PGNSP PGUID 12 1 0 f f t f i 3 700 "3614 3615 23" _null_ _null_ _null_ ts_rank_ttf - _null_ ));
+DESCR("relevance");
+DATA(insert OID = 3706 ( ts_rank PGNSP PGUID 12 1 0 f f t f i 2 700 "3614 3615" _null_ _null_ _null_ ts_rank_tt - _null_ ));
+DESCR("relevance");
+DATA(insert OID = 3707 ( ts_rank_cd PGNSP PGUID 12 1 0 f f t f i 4 700 "1021 3614 3615 23" _null_ _null_ _null_ ts_rankcd_wttf - _null_ ));
+DESCR("relevance");
+DATA(insert OID = 3708 ( ts_rank_cd PGNSP PGUID 12 1 0 f f t f i 3 700 "1021 3614 3615" _null_ _null_ _null_ ts_rankcd_wtt - _null_ ));
+DESCR("relevance");
+DATA(insert OID = 3709 ( ts_rank_cd PGNSP PGUID 12 1 0 f f t f i 3 700 "3614 3615 23" _null_ _null_ _null_ ts_rankcd_ttf - _null_ ));
+DESCR("relevance");
+DATA(insert OID = 3710 ( ts_rank_cd PGNSP PGUID 12 1 0 f f t f i 2 700 "3614 3615" _null_ _null_ _null_ ts_rankcd_tt - _null_ ));
+DESCR("relevance");
+
+DATA(insert OID = 3713 ( ts_token_type PGNSP PGUID 12 1 16 f f t t i 1 2249 "26" "{26,23,25,25}" "{i,o,o,o}" "{parser_oid,tokid,alias,description}" ts_token_type_byid - _null_ ));
+DESCR("get parser's token types");
+DATA(insert OID = 3714 ( ts_token_type PGNSP PGUID 12 1 16 f f t t s 1 2249 "25" "{25,23,25,25}" "{i,o,o,o}" "{parser_name,tokid,alias,description}" ts_token_type_byname - _null_ ));
+DESCR("get parser's token types");
+DATA(insert OID = 3715 ( ts_parse PGNSP PGUID 12 1 1000 f f t t i 2 2249 "26 25" "{26,25,23,25}" "{i,i,o,o}" "{parser_oid,txt,tokid,token}" ts_parse_byid - _null_ ));
+DESCR("parse text to tokens");
+DATA(insert OID = 3716 ( ts_parse PGNSP PGUID 12 1 1000 f f t t s 2 2249 "25 25" "{25,25,23,25}" "{i,i,o,o}" "{parser_name,txt,tokid,token}" ts_parse_byname - _null_ ));
+DESCR("parse text to tokens");
+
+DATA(insert OID = 3717 ( prsd_start PGNSP PGUID 12 1 0 f f t f i 2 2281 "2281 23" _null_ _null_ _null_ prsd_start - _null_ ));
+DESCR("");
+DATA(insert OID = 3718 ( prsd_nexttoken PGNSP PGUID 12 1 0 f f t f i 3 2281 "2281 2281 2281" _null_ _null_ _null_ prsd_nexttoken - _null_ ));
+DESCR("");
+DATA(insert OID = 3719 ( prsd_end PGNSP PGUID 12 1 0 f f t f i 1 2278 "2281" _null_ _null_ _null_ prsd_end - _null_ ));
+DESCR("");
+DATA(insert OID = 3720 ( prsd_headline PGNSP PGUID 12 1 0 f f t f i 3 2281 "2281 25 3615" _null_ _null_ _null_ prsd_headline - _null_ ));
+DESCR("");
+DATA(insert OID = 3721 ( prsd_lextype PGNSP PGUID 12 1 0 f f t f i 1 2281 "2281" _null_ _null_ _null_ prsd_lextype - _null_ ));
+DESCR("");
+
+DATA(insert OID = 3723 ( ts_lexize PGNSP PGUID 12 1 0 f f t f i 2 1009 "26 25" _null_ _null_ _null_ ts_lexize_byid - _null_ ));
+DESCR("normalize one word by dictionary");
+DATA(insert OID = 3724 ( ts_lexize PGNSP PGUID 12 1 0 f f t f s 2 1009 "25 25" _null_ _null_ _null_ ts_lexize_byname - _null_ ));
+DESCR("normalize one word by dictionary");
+
+DATA(insert OID = 3725 ( dsimple_init PGNSP PGUID 12 1 0 f f f f i 1 2281 "2281" _null_ _null_ _null_ dsimple_init - _null_ ));
+DESCR("");
+DATA(insert OID = 3726 ( dsimple_lexize PGNSP PGUID 12 1 0 f f t f i 4 2281 "2281 2281 2281 2281" _null_ _null_ _null_ dsimple_lexize - _null_ ));
+DESCR("");
+
+DATA(insert OID = 3728 ( dsynonym_init PGNSP PGUID 12 1 0 f f f f i 1 2281 "2281" _null_ _null_ _null_ dsynonym_init - _null_ ));
+DESCR("");
+DATA(insert OID = 3729 ( dsynonym_lexize PGNSP PGUID 12 1 0 f f t f i 4 2281 "2281 2281 2281 2281" _null_ _null_ _null_ dsynonym_lexize - _null_ ));
+DESCR("");
+
+DATA(insert OID = 3731 ( dispell_init PGNSP PGUID 12 1 0 f f f f i 1 2281 "2281" _null_ _null_ _null_ dispell_init - _null_ ));
+DESCR("");
+DATA(insert OID = 3732 ( dispell_lexize PGNSP PGUID 12 1 0 f f t f i 4 2281 "2281 2281 2281 2281" _null_ _null_ _null_ dispell_lexize - _null_ ));
+DESCR("");
+
+DATA(insert OID = 3740 ( thesaurus_init PGNSP PGUID 12 1 0 f f f f i 1 2281 "2281" _null_ _null_ _null_ thesaurus_init - _null_ ));
+DESCR("");
+DATA(insert OID = 3741 ( thesaurus_lexize PGNSP PGUID 12 1 0 f f t f i 4 2281 "2281 2281 2281 2281" _null_ _null_ _null_ thesaurus_lexize - _null_ ));
+DESCR("");
+
+DATA(insert OID = 3743 ( ts_headline PGNSP PGUID 12 1 0 f f t f i 4 25 "3734 25 3615 25" _null_ _null_ _null_ ts_headline_byid_opt - _null_ ));
+DESCR("generate headline");
+DATA(insert OID = 3744 ( ts_headline PGNSP PGUID 12 1 0 f f t f i 3 25 "3734 25 3615" _null_ _null_ _null_ ts_headline_byid - _null_ ));
+DESCR("generate headline");
+DATA(insert OID = 3754 ( ts_headline PGNSP PGUID 12 1 0 f f t f s 3 25 "25 3615 25" _null_ _null_ _null_ ts_headline_opt - _null_ ));
+DESCR("generate headline");
+DATA(insert OID = 3755 ( ts_headline PGNSP PGUID 12 1 0 f f t f s 2 25 "25 3615" _null_ _null_ _null_ ts_headline - _null_ ));
+DESCR("generate headline");
+
+DATA(insert OID = 3745 ( to_tsvector PGNSP PGUID 12 1 0 f f t f i 2 3614 "3734 25" _null_ _null_ _null_ to_tsvector_byid - _null_ ));
+DESCR("transform to tsvector");
+DATA(insert OID = 3746 ( to_tsquery PGNSP PGUID 12 1 0 f f t f i 2 3615 "3734 25" _null_ _null_ _null_ to_tsquery_byid - _null_ ));
+DESCR("make tsquery");
+DATA(insert OID = 3747 ( plainto_tsquery PGNSP PGUID 12 1 0 f f t f i 2 3615 "3734 25" _null_ _null_ _null_ plainto_tsquery_byid - _null_ ));
+DESCR("transform to tsquery");
+DATA(insert OID = 3749 ( to_tsvector PGNSP PGUID 12 1 0 f f t f s 1 3614 "25" _null_ _null_ _null_ to_tsvector - _null_ ));
+DESCR("transform to tsvector");
+DATA(insert OID = 3750 ( to_tsquery PGNSP PGUID 12 1 0 f f t f s 1 3615 "25" _null_ _null_ _null_ to_tsquery - _null_ ));
+DESCR("make tsquery");
+DATA(insert OID = 3751 ( plainto_tsquery PGNSP PGUID 12 1 0 f f t f s 1 3615 "25" _null_ _null_ _null_ plainto_tsquery - _null_ ));
+DESCR("transform to tsquery");
+
+DATA(insert OID = 3752 ( tsvector_update_trigger PGNSP PGUID 12 1 0 f f f f v 0 2279 "" _null_ _null_ _null_ tsvector_update_trigger_byid - _null_ ));
+DESCR("trigger for automatic update of tsvector column");
+DATA(insert OID = 3753 ( tsvector_update_trigger_column PGNSP PGUID 12 1 0 f f f f v 0 2279 "" _null_ _null_ _null_ tsvector_update_trigger_bycolumn - _null_ ));
+DESCR("trigger for automatic update of tsvector column");
+
+DATA(insert OID = 3759 ( get_current_ts_config PGNSP PGUID 12 1 0 f f t f s 0 3734 "" _null_ _null_ _null_ get_current_ts_config - _null_ ));
+DESCR("get current tsearch configuration");
+
+DATA(insert OID = 3736 ( regconfigin PGNSP PGUID 12 1 0 f f t f s 1 3734 "2275" _null_ _null_ _null_ regconfigin - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3737 ( regconfigout PGNSP PGUID 12 1 0 f f t f s 1 2275 "3734" _null_ _null_ _null_ regconfigout - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3738 ( regconfigrecv PGNSP PGUID 12 1 0 f f t f i 1 3734 "2281" _null_ _null_ _null_ regconfigrecv - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3739 ( regconfigsend PGNSP PGUID 12 1 0 f f t f i 1 17 "3734" _null_ _null_ _null_ regconfigsend - _null_ ));
+DESCR("I/O");
+
+DATA(insert OID = 3771 ( regdictionaryin PGNSP PGUID 12 1 0 f f t f s 1 3769 "2275" _null_ _null_ _null_ regdictionaryin - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3772 ( regdictionaryout PGNSP PGUID 12 1 0 f f t f s 1 2275 "3769" _null_ _null_ _null_ regdictionaryout - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3773 ( regdictionaryrecv PGNSP PGUID 12 1 0 f f t f i 1 3769 "2281" _null_ _null_ _null_ regdictionaryrecv - _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3774 ( regdictionarysend PGNSP PGUID 12 1 0 f f t f i 1 17 "3769" _null_ _null_ _null_ regdictionarysend - _null_ ));
+DESCR("I/O");
+
+
/*
* Symbolic values for provolatile column: these indicate whether the result
* of a function is dependent *only* on the values of its explicit arguments,
diff --git a/src/include/catalog/pg_ts_config.h b/src/include/catalog/pg_ts_config.h
new file mode 100644
index 00000000000..7d56cb39187
--- /dev/null
+++ b/src/include/catalog/pg_ts_config.h
@@ -0,0 +1,65 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_ts_config.h
+ * definition of configuration of tsearch
+ *
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/catalog/pg_ts_config.h,v 1.1 2007/08/21 01:11:27 tgl Exp $
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ * XXX do NOT break up DATA() statements into multiple lines!
+ * the scripts are not as smart as you might think...
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_TS_CONFIG_H
+#define PG_TS_CONFIG_H
+
+/* ----------------
+ * postgres.h contains the system type definitions and the
+ * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
+ * ----------------
+ */
+
+/* ----------------
+ * pg_ts_config definition. cpp turns this into
+ * typedef struct FormData_pg_ts_config
+ * ----------------
+ */
+#define TSConfigRelationId 3602
+
+CATALOG(pg_ts_config,3602)
+{
+ NameData cfgname; /* name of configuration */
+ Oid cfgnamespace; /* name space */
+ Oid cfgowner; /* owner */
+ Oid cfgparser; /* OID of parser (in pg_ts_parser) */
+} FormData_pg_ts_config;
+
+typedef FormData_pg_ts_config *Form_pg_ts_config;
+
+/* ----------------
+ * compiler constants for pg_ts_config
+ * ----------------
+ */
+#define Natts_pg_ts_config 4
+#define Anum_pg_ts_config_cfgname 1
+#define Anum_pg_ts_config_cfgnamespace 2
+#define Anum_pg_ts_config_cfgowner 3
+#define Anum_pg_ts_config_cfgparser 4
+
+/* ----------------
+ * initial contents of pg_ts_config
+ * ----------------
+ */
+DATA(insert OID = 3748 ( "simple" PGNSP PGUID 3722 ));
+DESCR("simple configuration");
+
+#endif /* PG_TS_CONFIG_H */
diff --git a/src/include/catalog/pg_ts_config_map.h b/src/include/catalog/pg_ts_config_map.h
new file mode 100644
index 00000000000..0db8025110a
--- /dev/null
+++ b/src/include/catalog/pg_ts_config_map.h
@@ -0,0 +1,83 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_ts_config_map.h
+ * definition of token mappings for configurations of tsearch
+ *
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/catalog/pg_ts_config_map.h,v 1.1 2007/08/21 01:11:27 tgl Exp $
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ * XXX do NOT break up DATA() statements into multiple lines!
+ * the scripts are not as smart as you might think...
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_TS_CONFIG_MAP_H
+#define PG_TS_CONFIG_MAP_H
+
+/* ----------------
+ * postgres.h contains the system type definitions and the
+ * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
+ * ----------------
+ */
+
+/* ----------------
+ * pg_ts_config_map definition. cpp turns this into
+ * typedef struct FormData_pg_ts_config_map
+ * ----------------
+ */
+#define TSConfigMapRelationId 3603
+
+CATALOG(pg_ts_config_map,3603) BKI_WITHOUT_OIDS
+{
+ Oid mapcfg; /* OID of configuration owning this entry */
+ int4 maptokentype; /* token type from parser */
+ int4 mapseqno; /* order in which to consult dictionaries */
+ Oid mapdict; /* dictionary to consult */
+} FormData_pg_ts_config_map;
+
+typedef FormData_pg_ts_config_map *Form_pg_ts_config_map;
+
+/* ----------------
+ * compiler constants for pg_ts_config_map
+ * ----------------
+ */
+#define Natts_pg_ts_config_map 4
+#define Anum_pg_ts_config_map_mapcfg 1
+#define Anum_pg_ts_config_map_maptokentype 2
+#define Anum_pg_ts_config_map_mapseqno 3
+#define Anum_pg_ts_config_map_mapdict 4
+
+/* ----------------
+ * initial contents of pg_ts_config_map
+ * ----------------
+ */
+
+DATA(insert ( 3748 1 1 3765 ));
+DATA(insert ( 3748 2 1 3765 ));
+DATA(insert ( 3748 3 1 3765 ));
+DATA(insert ( 3748 4 1 3765 ));
+DATA(insert ( 3748 5 1 3765 ));
+DATA(insert ( 3748 6 1 3765 ));
+DATA(insert ( 3748 7 1 3765 ));
+DATA(insert ( 3748 8 1 3765 ));
+DATA(insert ( 3748 9 1 3765 ));
+DATA(insert ( 3748 10 1 3765 ));
+DATA(insert ( 3748 11 1 3765 ));
+DATA(insert ( 3748 15 1 3765 ));
+DATA(insert ( 3748 16 1 3765 ));
+DATA(insert ( 3748 17 1 3765 ));
+DATA(insert ( 3748 18 1 3765 ));
+DATA(insert ( 3748 19 1 3765 ));
+DATA(insert ( 3748 20 1 3765 ));
+DATA(insert ( 3748 21 1 3765 ));
+DATA(insert ( 3748 22 1 3765 ));
+
+#endif /* PG_TS_CONFIG_MAP_H */
diff --git a/src/include/catalog/pg_ts_dict.h b/src/include/catalog/pg_ts_dict.h
new file mode 100644
index 00000000000..7c5f07363ee
--- /dev/null
+++ b/src/include/catalog/pg_ts_dict.h
@@ -0,0 +1,68 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_ts_dict.h
+ * definition of dictionaries for tsearch
+ *
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/catalog/pg_ts_dict.h,v 1.1 2007/08/21 01:11:27 tgl Exp $
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ * XXX do NOT break up DATA() statements into multiple lines!
+ * the scripts are not as smart as you might think...
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_TS_DICT_H
+#define PG_TS_DICT_H
+
+/* ----------------
+ * postgres.h contains the system type definitions and the
+ * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
+ * ----------------
+ */
+
+/* ----------------
+ * pg_ts_dict definition. cpp turns this into
+ * typedef struct FormData_pg_ts_dict
+ * ----------------
+ */
+#define TSDictionaryRelationId 3600
+
+CATALOG(pg_ts_dict,3600)
+{
+ NameData dictname; /* dictionary name */
+ Oid dictnamespace; /* name space */
+ Oid dictowner; /* owner */
+ Oid dicttemplate; /* dictionary's template */
+ text dictinitoption; /* options passed to dict_init() */
+} FormData_pg_ts_dict;
+
+typedef FormData_pg_ts_dict *Form_pg_ts_dict;
+
+/* ----------------
+ * compiler constants for pg_ts_dict
+ * ----------------
+ */
+#define Natts_pg_ts_dict 5
+#define Anum_pg_ts_dict_dictname 1
+#define Anum_pg_ts_dict_dictnamespace 2
+#define Anum_pg_ts_dict_dictowner 3
+#define Anum_pg_ts_dict_dicttemplate 4
+#define Anum_pg_ts_dict_dictinitoption 5
+
+/* ----------------
+ * initial contents of pg_ts_dict
+ * ----------------
+ */
+
+DATA(insert OID = 3765 ( "simple" PGNSP PGUID 3727 _null_));
+DESCR("simple dictionary: just lower case and check for stopword");
+
+#endif /* PG_TS_DICT_H */
diff --git a/src/include/catalog/pg_ts_parser.h b/src/include/catalog/pg_ts_parser.h
new file mode 100644
index 00000000000..fb7aff5b37c
--- /dev/null
+++ b/src/include/catalog/pg_ts_parser.h
@@ -0,0 +1,72 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_ts_parser.h
+ * definition of parsers for tsearch
+ *
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/catalog/pg_ts_parser.h,v 1.1 2007/08/21 01:11:27 tgl Exp $
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ * XXX do NOT break up DATA() statements into multiple lines!
+ * the scripts are not as smart as you might think...
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_TS_PARSER_H
+#define PG_TS_PARSER_H
+
+/* ----------------
+ * postgres.h contains the system type definitions and the
+ * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
+ * ----------------
+ */
+
+/* ----------------
+ * pg_ts_parser definition. cpp turns this into
+ * typedef struct FormData_pg_ts_parser
+ * ----------------
+ */
+#define TSParserRelationId 3601
+
+CATALOG(pg_ts_parser,3601)
+{
+ NameData prsname; /* parser's name */
+ Oid prsnamespace; /* name space */
+ regproc prsstart; /* init parsing session */
+ regproc prstoken; /* return next token */
+ regproc prsend; /* finalize parsing session */
+ regproc prsheadline; /* return data for headline creation */
+ regproc prslextype; /* return descriptions of lexeme's types */
+} FormData_pg_ts_parser;
+
+typedef FormData_pg_ts_parser *Form_pg_ts_parser;
+
+/* ----------------
+ * compiler constants for pg_ts_parser
+ * ----------------
+ */
+#define Natts_pg_ts_parser 7
+#define Anum_pg_ts_parser_prsname 1
+#define Anum_pg_ts_parser_prsnamespace 2
+#define Anum_pg_ts_parser_prsstart 3
+#define Anum_pg_ts_parser_prstoken 4
+#define Anum_pg_ts_parser_prsend 5
+#define Anum_pg_ts_parser_prsheadline 6
+#define Anum_pg_ts_parser_prslextype 7
+
+/* ----------------
+ * initial contents of pg_ts_parser
+ * ----------------
+ */
+
+DATA(insert OID = 3722 ( "default" PGNSP prsd_start prsd_nexttoken prsd_end prsd_headline prsd_lextype ));
+DESCR("default word parser");
+
+#endif /* PG_TS_PARSER_H */
diff --git a/src/include/catalog/pg_ts_template.h b/src/include/catalog/pg_ts_template.h
new file mode 100644
index 00000000000..9a5c3ef7b71
--- /dev/null
+++ b/src/include/catalog/pg_ts_template.h
@@ -0,0 +1,72 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_ts_template.h
+ * definition of dictionary templates for tsearch
+ *
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/catalog/pg_ts_template.h,v 1.1 2007/08/21 01:11:27 tgl Exp $
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ * XXX do NOT break up DATA() statements into multiple lines!
+ * the scripts are not as smart as you might think...
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_TS_TEMPLATE_H
+#define PG_TS_TEMPLATE_H
+
+/* ----------------
+ * postgres.h contains the system type definitions and the
+ * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file
+ * can be read by both genbki.sh and the C compiler.
+ * ----------------
+ */
+
+/* ----------------
+ * pg_ts_template definition. cpp turns this into
+ * typedef struct FormData_pg_ts_template
+ * ----------------
+ */
+#define TSTemplateRelationId 3764
+
+CATALOG(pg_ts_template,3764)
+{
+ NameData tmplname; /* template name */
+ Oid tmplnamespace; /* name space */
+ regproc tmplinit; /* initialization method of dict (may be 0) */
+ regproc tmpllexize; /* base method of dictionary */
+} FormData_pg_ts_template;
+
+typedef FormData_pg_ts_template *Form_pg_ts_template;
+
+/* ----------------
+ * compiler constants for pg_ts_template
+ * ----------------
+ */
+#define Natts_pg_ts_template 4
+#define Anum_pg_ts_template_tmplname 1
+#define Anum_pg_ts_template_tmplnamespace 2
+#define Anum_pg_ts_template_tmplinit 3
+#define Anum_pg_ts_template_tmpllexize 4
+
+/* ----------------
+ * initial contents of pg_ts_template
+ * ----------------
+ */
+
+DATA(insert OID = 3727 ( "simple" PGNSP dsimple_init dsimple_lexize ));
+DESCR("simple dictionary: just lower case and check for stopword");
+DATA(insert OID = 3730 ( "synonym" PGNSP dsynonym_init dsynonym_lexize ));
+DESCR("synonym dictionary: replace word by its synonym");
+DATA(insert OID = 3733 ( "ispell" PGNSP dispell_init dispell_lexize ));
+DESCR("Ispell dictionary");
+DATA(insert OID = 3742 ( "thesaurus" PGNSP thesaurus_init thesaurus_lexize ));
+DESCR("thesaurus dictionary: phrase by phrase substitution");
+
+#endif /* PG_TS_TEMPLATE_H */
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 01db6c616fc..6c6715c75a2 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.186 2007/06/15 20:56:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.187 2007/08/21 01:11:27 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -549,6 +549,29 @@ DATA(insert OID = 2950 ( uuid PGNSP PGUID 16 f b t \054 0 0 2951 uuid_in uuid_
DESCR("UUID datatype");
DATA(insert OID = 2951 ( _uuid PGNSP PGUID -1 f b t \054 0 2950 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+/* text search */
+DATA(insert OID = 3614 ( tsvector PGNSP PGUID -1 f b t \054 0 0 3643 tsvectorin tsvectorout tsvectorrecv tsvectorsend - - - i x f 0 -1 0 _null_ _null_ ));
+DESCR("text representation for text search");
+#define TSVECTOROID 3614
+DATA(insert OID = 3642 ( gtsvector PGNSP PGUID -1 f b t \054 0 0 3644 gtsvectorin gtsvectorout - - - - - i p f 0 -1 0 _null_ _null_ ));
+DESCR("GiST index internal text representation for text search");
+#define GTSVECTOROID 3642
+DATA(insert OID = 3615 ( tsquery PGNSP PGUID -1 f b t \054 0 0 3645 tsqueryin tsqueryout tsqueryrecv tsquerysend - - - i p f 0 -1 0 _null_ _null_ ));
+DESCR("query representation for text search");
+#define TSQUERYOID 3615
+DATA(insert OID = 3734 ( regconfig PGNSP PGUID 4 t b t \054 0 0 3735 regconfigin regconfigout regconfigrecv regconfigsend - - - i p f 0 -1 0 _null_ _null_ ));
+DESCR("registered text search configuration");
+#define REGCONFIGOID 3734
+DATA(insert OID = 3769 ( regdictionary PGNSP PGUID 4 t b t \054 0 0 3770 regdictionaryin regdictionaryout regdictionaryrecv regdictionarysend - - - i p f 0 -1 0 _null_ _null_ ));
+DESCR("registered text search dictionary");
+#define REGDICTIONARYOID 3769
+
+DATA(insert OID = 3643 ( _tsvector PGNSP PGUID -1 f b t \054 0 3614 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3644 ( _gtsvector PGNSP PGUID -1 f b t \054 0 3642 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3645 ( _tsquery PGNSP PGUID -1 f b t \054 0 3615 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3735 ( _regconfig PGNSP PGUID -1 f b t \054 0 3734 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+DATA(insert OID = 3770 ( _regdictionary PGNSP PGUID -1 f b t \054 0 3769 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+
/*
* pseudo-types
*
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index cf74692208b..514507d26f0 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.82 2007/07/17 05:02:02 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.83 2007/08/21 01:11:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -92,6 +92,35 @@ extern void RenameOpFamily(List *name, const char *access_method, const char *ne
extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId);
extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId);
+/* commands/tsearchcmds.c */
+extern void DefineTSParser(List *names, List *parameters);
+extern void RenameTSParser(List *oldname, const char *newname);
+extern void RemoveTSParser(List *names, DropBehavior behavior,
+ bool missing_ok);
+extern void RemoveTSParserById(Oid prsId);
+
+extern void DefineTSDictionary(List *names, List *parameters);
+extern void RenameTSDictionary(List *oldname, const char *newname);
+extern void RemoveTSDictionary(List *names, DropBehavior behavior,
+ bool missing_ok);
+extern void RemoveTSDictionaryById(Oid dictId);
+extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt);
+extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId);
+
+extern void DefineTSTemplate(List *names, List *parameters);
+extern void RenameTSTemplate(List *oldname, const char *newname);
+extern void RemoveTSTemplate(List *names, DropBehavior behavior,
+ bool missing_ok);
+extern void RemoveTSTemplateById(Oid tmplId);
+
+extern void DefineTSConfiguration(List *names, List *parameters);
+extern void RenameTSConfiguration(List *oldname, const char *newname);
+extern void RemoveTSConfiguration(List *names, DropBehavior behavior,
+ bool missing_ok);
+extern void RemoveTSConfigurationById(Oid cfgId);
+extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt);
+extern void AlterTSConfigurationOwner(List *name, Oid newOwnerId);
+
/* support routines in commands/define.c */
extern char *case_translate_language_name(const char *input);
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 92bd19e999e..7f6a08f450f 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.202 2007/07/25 12:22:53 mha Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.203 2007/08/21 01:11:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -312,6 +312,8 @@ typedef enum NodeTag
T_ReassignOwnedStmt,
T_CompositeTypeStmt,
T_CreateEnumStmt,
+ T_AlterTSDictionaryStmt,
+ T_AlterTSConfigurationStmt,
/*
* TAGS FOR PARSE TREE NODES (parsenodes.h)
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index a108759b760..7ba810dbb1a 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.350 2007/07/17 05:02:02 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.351 2007/08/21 01:11:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -836,6 +836,10 @@ typedef enum ObjectType
OBJECT_TABLE,
OBJECT_TABLESPACE,
OBJECT_TRIGGER,
+ OBJECT_TSCONFIGURATION,
+ OBJECT_TSDICTIONARY,
+ OBJECT_TSPARSER,
+ OBJECT_TSTEMPLATE,
OBJECT_TYPE,
OBJECT_VIEW
} ObjectType;
@@ -2033,4 +2037,35 @@ typedef struct ReassignOwnedStmt
char *newrole;
} ReassignOwnedStmt;
+/*
+ * TS Dictionary stmts: DefineStmt, RenameStmt and DropStmt are default
+ */
+typedef struct AlterTSDictionaryStmt
+{
+ NodeTag type;
+ List *dictname; /* qualified name (list of Value strings) */
+ List *options; /* List of DefElem nodes */
+} AlterTSDictionaryStmt;
+
+/*
+ * TS Configuration stmts: DefineStmt, RenameStmt and DropStmt are default
+ */
+typedef struct AlterTSConfigurationStmt
+{
+ NodeTag type;
+ List *cfgname; /* qualified name (list of Value strings) */
+ List *options; /* List of DefElem nodes */
+
+ /*
+ * These fields are used for ADD/ALTER/DROP MAPPING variants.
+ * dicts will be non-NIL if ADD/ALTER MAPPING was specified.
+ * If dicts is NIL, but tokentype isn't, DROP MAPPING was specified.
+ */
+ List *tokentype; /* list of Value strings */
+ List *dicts; /* list of list of Value strings */
+ bool override; /* if true - remove old variant */
+ bool replace; /* if true - replace dictionary by another */
+ bool missing_ok; /* for DROP - skip error if missing? */
+} AlterTSConfigurationStmt;
+
#endif /* PARSENODES_H */
diff --git a/src/include/snowball/header.h b/src/include/snowball/header.h
new file mode 100644
index 00000000000..38b7da73c51
--- /dev/null
+++ b/src/include/snowball/header.h
@@ -0,0 +1,62 @@
+/*-------------------------------------------------------------------------
+ *
+ * header.h
+ * Replacement header file for Snowball stemmer modules
+ *
+ * The Snowball stemmer modules do #include "header.h", and think they
+ * are including snowball/libstemmer/header.h. We adjust the CPPFLAGS
+ * so that this file is found instead, and thereby we can modify the
+ * headers they see. The main point here is to ensure that pg_config.h
+ * is included before any system headers such as <stdio.h>; without that,
+ * we have portability issues on some platforms due to variation in
+ * largefile options across different modules in the backend.
+ *
+ * NOTE: this file should not be included into any non-snowball sources!
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/snowball/header.h,v 1.1 2007/08/21 01:11:28 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef SNOWBALL_HEADR_H
+#define SNOWBALL_HEADR_H
+
+#include "postgres.h"
+
+/* Some platforms define MAXINT and/or MININT, causing conflicts */
+#ifdef MAXINT
+#undef MAXINT
+#endif
+#ifdef MININT
+#undef MININT
+#endif
+
+/* Now we can include the original Snowball header.h */
+#include "snowball/libstemmer/header.h"
+
+/*
+ * Redefine standard memory allocation interface to pgsql's one.
+ * This allows us to control where the Snowball code allocates stuff.
+ */
+#ifdef malloc
+#undef malloc
+#endif
+#define malloc(a) palloc(a)
+
+#ifdef calloc
+#undef calloc
+#endif
+#define calloc(a,b) palloc0((a) * (b))
+
+#ifdef realloc
+#undef realloc
+#endif
+#define realloc(a,b) repalloc(a,b)
+
+#ifdef free
+#undef free
+#endif
+#define free(a) pfree(a)
+
+#endif /* SNOWBALL_HEADR_H */
diff --git a/src/include/snowball/libstemmer/api.h b/src/include/snowball/libstemmer/api.h
new file mode 100644
index 00000000000..8b997f0c298
--- /dev/null
+++ b/src/include/snowball/libstemmer/api.h
@@ -0,0 +1,26 @@
+
+typedef unsigned char symbol;
+
+/* Or replace 'char' above with 'short' for 16 bit characters.
+
+ More precisely, replace 'char' with whatever type guarantees the
+ character width you need. Note however that sizeof(symbol) should divide
+ HEAD, defined in header.h as 2*sizeof(int), without remainder, otherwise
+ there is an alignment problem. In the unlikely event of a problem here,
+ consult Martin Porter.
+
+*/
+
+struct SN_env {
+ symbol * p;
+ int c; int l; int lb; int bra; int ket;
+ symbol * * S;
+ int * I;
+ unsigned char * B;
+};
+
+extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size);
+extern void SN_close_env(struct SN_env * z, int S_size);
+
+extern int SN_set_current(struct SN_env * z, int size, const symbol * s);
+
diff --git a/src/include/snowball/libstemmer/header.h b/src/include/snowball/libstemmer/header.h
new file mode 100644
index 00000000000..4d3078f50f4
--- /dev/null
+++ b/src/include/snowball/libstemmer/header.h
@@ -0,0 +1,58 @@
+
+#include <limits.h>
+
+#include "api.h"
+
+#define MAXINT INT_MAX
+#define MININT INT_MIN
+
+#define HEAD 2*sizeof(int)
+
+#define SIZE(p) ((int *)(p))[-1]
+#define SET_SIZE(p, n) ((int *)(p))[-1] = n
+#define CAPACITY(p) ((int *)(p))[-2]
+
+struct among
+{ int s_size; /* number of chars in string */
+ const symbol * s; /* search string */
+ int substring_i;/* index to longest matching substring */
+ int result; /* result of the lookup */
+ int (* function)(struct SN_env *);
+};
+
+extern symbol * create_s(void);
+extern void lose_s(symbol * p);
+
+extern int skip_utf8(const symbol * p, int c, int lb, int l, int n);
+
+extern int in_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat);
+extern int in_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat);
+extern int out_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat);
+extern int out_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat);
+
+extern int in_grouping(struct SN_env * z, const unsigned char * s, int min, int max, int repeat);
+extern int in_grouping_b(struct SN_env * z, const unsigned char * s, int min, int max, int repeat);
+extern int out_grouping(struct SN_env * z, const unsigned char * s, int min, int max, int repeat);
+extern int out_grouping_b(struct SN_env * z, const unsigned char * s, int min, int max, int repeat);
+
+extern int eq_s(struct SN_env * z, int s_size, const symbol * s);
+extern int eq_s_b(struct SN_env * z, int s_size, const symbol * s);
+extern int eq_v(struct SN_env * z, const symbol * p);
+extern int eq_v_b(struct SN_env * z, const symbol * p);
+
+extern int find_among(struct SN_env * z, const struct among * v, int v_size);
+extern int find_among_b(struct SN_env * z, const struct among * v, int v_size);
+
+extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const symbol * s, int * adjustment);
+extern int slice_from_s(struct SN_env * z, int s_size, const symbol * s);
+extern int slice_from_v(struct SN_env * z, const symbol * p);
+extern int slice_del(struct SN_env * z);
+
+extern int insert_s(struct SN_env * z, int bra, int ket, int s_size, const symbol * s);
+extern int insert_v(struct SN_env * z, int bra, int ket, const symbol * p);
+
+extern symbol * slice_to(struct SN_env * z, symbol * p);
+extern symbol * assign_to(struct SN_env * z, symbol * p);
+
+extern void debug(struct SN_env * z, int number, int line_count);
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_danish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_danish.h
new file mode 100644
index 00000000000..49c5559cdfc
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_danish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * danish_ISO_8859_1_create_env(void);
+extern void danish_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int danish_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_dutch.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_dutch.h
new file mode 100644
index 00000000000..e67d11152cd
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_dutch.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * dutch_ISO_8859_1_create_env(void);
+extern void dutch_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int dutch_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_english.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_english.h
new file mode 100644
index 00000000000..e685dcf7ef0
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_english.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * english_ISO_8859_1_create_env(void);
+extern void english_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int english_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_finnish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_finnish.h
new file mode 100644
index 00000000000..c67b67b944f
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_finnish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * finnish_ISO_8859_1_create_env(void);
+extern void finnish_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int finnish_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_french.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_french.h
new file mode 100644
index 00000000000..21244d61621
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_french.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * french_ISO_8859_1_create_env(void);
+extern void french_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int french_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_german.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_german.h
new file mode 100644
index 00000000000..85253892278
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_german.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * german_ISO_8859_1_create_env(void);
+extern void german_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int german_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_hungarian.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_hungarian.h
new file mode 100644
index 00000000000..c3177e5019c
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_hungarian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * hungarian_ISO_8859_1_create_env(void);
+extern void hungarian_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int hungarian_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_italian.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_italian.h
new file mode 100644
index 00000000000..dccbfd5e971
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_italian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * italian_ISO_8859_1_create_env(void);
+extern void italian_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int italian_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_norwegian.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_norwegian.h
new file mode 100644
index 00000000000..e09e34e52f3
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_norwegian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * norwegian_ISO_8859_1_create_env(void);
+extern void norwegian_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int norwegian_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_porter.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_porter.h
new file mode 100644
index 00000000000..5c8fd01db17
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_porter.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * porter_ISO_8859_1_create_env(void);
+extern void porter_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int porter_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_portuguese.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_portuguese.h
new file mode 100644
index 00000000000..0279bc94da6
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_portuguese.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * portuguese_ISO_8859_1_create_env(void);
+extern void portuguese_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int portuguese_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_spanish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_spanish.h
new file mode 100644
index 00000000000..83f1498403f
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_spanish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * spanish_ISO_8859_1_create_env(void);
+extern void spanish_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int spanish_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_swedish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_swedish.h
new file mode 100644
index 00000000000..4184e5ca39e
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_swedish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * swedish_ISO_8859_1_create_env(void);
+extern void swedish_ISO_8859_1_close_env(struct SN_env * z);
+
+extern int swedish_ISO_8859_1_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_2_romanian.h b/src/include/snowball/libstemmer/stem_ISO_8859_2_romanian.h
new file mode 100644
index 00000000000..931f269ceb2
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_ISO_8859_2_romanian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * romanian_ISO_8859_2_create_env(void);
+extern void romanian_ISO_8859_2_close_env(struct SN_env * z);
+
+extern int romanian_ISO_8859_2_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_KOI8_R_russian.h b/src/include/snowball/libstemmer/stem_KOI8_R_russian.h
new file mode 100644
index 00000000000..de2179d29f0
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_KOI8_R_russian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * russian_KOI8_R_create_env(void);
+extern void russian_KOI8_R_close_env(struct SN_env * z);
+
+extern int russian_KOI8_R_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_danish.h b/src/include/snowball/libstemmer/stem_UTF_8_danish.h
new file mode 100644
index 00000000000..ed744d454f0
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_danish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * danish_UTF_8_create_env(void);
+extern void danish_UTF_8_close_env(struct SN_env * z);
+
+extern int danish_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_dutch.h b/src/include/snowball/libstemmer/stem_UTF_8_dutch.h
new file mode 100644
index 00000000000..a99646452b0
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_dutch.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * dutch_UTF_8_create_env(void);
+extern void dutch_UTF_8_close_env(struct SN_env * z);
+
+extern int dutch_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_english.h b/src/include/snowball/libstemmer/stem_UTF_8_english.h
new file mode 100644
index 00000000000..619a8bc72ae
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_english.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * english_UTF_8_create_env(void);
+extern void english_UTF_8_close_env(struct SN_env * z);
+
+extern int english_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_finnish.h b/src/include/snowball/libstemmer/stem_UTF_8_finnish.h
new file mode 100644
index 00000000000..d2f2fd96383
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_finnish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * finnish_UTF_8_create_env(void);
+extern void finnish_UTF_8_close_env(struct SN_env * z);
+
+extern int finnish_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_french.h b/src/include/snowball/libstemmer/stem_UTF_8_french.h
new file mode 100644
index 00000000000..08e341846df
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_french.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * french_UTF_8_create_env(void);
+extern void french_UTF_8_close_env(struct SN_env * z);
+
+extern int french_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_german.h b/src/include/snowball/libstemmer/stem_UTF_8_german.h
new file mode 100644
index 00000000000..5bd84d431f0
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_german.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * german_UTF_8_create_env(void);
+extern void german_UTF_8_close_env(struct SN_env * z);
+
+extern int german_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_hungarian.h b/src/include/snowball/libstemmer/stem_UTF_8_hungarian.h
new file mode 100644
index 00000000000..d81bd23469a
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_hungarian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * hungarian_UTF_8_create_env(void);
+extern void hungarian_UTF_8_close_env(struct SN_env * z);
+
+extern int hungarian_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_italian.h b/src/include/snowball/libstemmer/stem_UTF_8_italian.h
new file mode 100644
index 00000000000..3bee080d52c
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_italian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * italian_UTF_8_create_env(void);
+extern void italian_UTF_8_close_env(struct SN_env * z);
+
+extern int italian_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_norwegian.h b/src/include/snowball/libstemmer/stem_UTF_8_norwegian.h
new file mode 100644
index 00000000000..c75444bcd95
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_norwegian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * norwegian_UTF_8_create_env(void);
+extern void norwegian_UTF_8_close_env(struct SN_env * z);
+
+extern int norwegian_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_porter.h b/src/include/snowball/libstemmer/stem_UTF_8_porter.h
new file mode 100644
index 00000000000..82d469ac459
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_porter.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * porter_UTF_8_create_env(void);
+extern void porter_UTF_8_close_env(struct SN_env * z);
+
+extern int porter_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_portuguese.h b/src/include/snowball/libstemmer/stem_UTF_8_portuguese.h
new file mode 100644
index 00000000000..9fe7f9aa811
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_portuguese.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * portuguese_UTF_8_create_env(void);
+extern void portuguese_UTF_8_close_env(struct SN_env * z);
+
+extern int portuguese_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_romanian.h b/src/include/snowball/libstemmer/stem_UTF_8_romanian.h
new file mode 100644
index 00000000000..d01e8132e20
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_romanian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * romanian_UTF_8_create_env(void);
+extern void romanian_UTF_8_close_env(struct SN_env * z);
+
+extern int romanian_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_russian.h b/src/include/snowball/libstemmer/stem_UTF_8_russian.h
new file mode 100644
index 00000000000..4ef774ddccb
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_russian.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * russian_UTF_8_create_env(void);
+extern void russian_UTF_8_close_env(struct SN_env * z);
+
+extern int russian_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_spanish.h b/src/include/snowball/libstemmer/stem_UTF_8_spanish.h
new file mode 100644
index 00000000000..10572ecc370
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_spanish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * spanish_UTF_8_create_env(void);
+extern void spanish_UTF_8_close_env(struct SN_env * z);
+
+extern int spanish_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_swedish.h b/src/include/snowball/libstemmer/stem_UTF_8_swedish.h
new file mode 100644
index 00000000000..1444ebb49a6
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_swedish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * swedish_UTF_8_create_env(void);
+extern void swedish_UTF_8_close_env(struct SN_env * z);
+
+extern int swedish_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/snowball/libstemmer/stem_UTF_8_turkish.h b/src/include/snowball/libstemmer/stem_UTF_8_turkish.h
new file mode 100644
index 00000000000..8173a174867
--- /dev/null
+++ b/src/include/snowball/libstemmer/stem_UTF_8_turkish.h
@@ -0,0 +1,16 @@
+
+/* This file was generated automatically by the Snowball to ANSI C compiler */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern struct SN_env * turkish_UTF_8_create_env(void);
+extern void turkish_UTF_8_close_env(struct SN_env * z);
+
+extern int turkish_UTF_8_stem(struct SN_env * z);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/include/tsearch/dicts/regis.h b/src/include/tsearch/dicts/regis.h
new file mode 100644
index 00000000000..d187875168c
--- /dev/null
+++ b/src/include/tsearch/dicts/regis.h
@@ -0,0 +1,49 @@
+/*-------------------------------------------------------------------------
+ *
+ * regis.h
+ *
+ * Declarations for for fast regex subset, used by ISpell
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/tsearch/dicts/regis.h,v 1.1 2007/08/21 01:11:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef __REGIS_H__
+#define __REGIS_H__
+
+typedef struct RegisNode
+{
+ uint32
+ type:2,
+ len:16,
+ unused:14;
+ struct RegisNode *next;
+ unsigned char data[1];
+} RegisNode;
+
+#define RNHDRSZ (offsetof(RegisNode,data))
+
+#define RSF_ONEOF 1
+#define RSF_NONEOF 2
+
+typedef struct Regis
+{
+ RegisNode *node;
+ uint32
+ issuffix:1,
+ nchar:16,
+ unused:15;
+} Regis;
+
+bool RS_isRegis(const char *str);
+
+void RS_compile(Regis * r, bool issuffix, char *str);
+void RS_free(Regis * r);
+
+/*returns true if matches */
+bool RS_execute(Regis * r, char *str);
+
+#endif
diff --git a/src/include/tsearch/dicts/spell.h b/src/include/tsearch/dicts/spell.h
new file mode 100644
index 00000000000..6c15a672f33
--- /dev/null
+++ b/src/include/tsearch/dicts/spell.h
@@ -0,0 +1,153 @@
+/*-------------------------------------------------------------------------
+ *
+ * spell.h
+ *
+ * Declarations for ISpell dictionary
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/tsearch/dicts/spell.h,v 1.1 2007/08/21 01:11:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef __SPELL_H__
+#define __SPELL_H__
+
+#include "regex/regex.h"
+#include "tsearch/dicts/regis.h"
+#include "tsearch/ts_public.h"
+
+struct SPNode;
+
+typedef struct
+{
+ uint32
+ val:8,
+ isword:1,
+ compoundflag:4,
+ affix:19;
+ struct SPNode *node;
+} SPNodeData;
+
+/*
+ * Names of FF_ are correlated with Hunspell options in affix file
+ * http://sourceforge.net/docman/display_doc.php?docid=29374&group_id=143754
+ */
+#define FF_COMPOUNDONLY 0x01
+#define FF_COMPOUNDBEGIN 0x02
+#define FF_COMPOUNDMIDDLE 0x04
+#define FF_COMPOUNDLAST 0x08
+#define FF_COMPOUNDFLAG ( FF_COMPOUNDBEGIN | FF_COMPOUNDMIDDLE | FF_COMPOUNDLAST )
+#define FF_DICTFLAGMASK 0x0f
+
+typedef struct SPNode
+{
+ uint32 length;
+ SPNodeData data[1];
+} SPNode;
+
+#define SPNHRDSZ (sizeof(uint32))
+
+
+typedef struct spell_struct
+{
+ union
+ {
+ char flag[16];
+ struct
+ {
+ int affix;
+ int len;
+ } d;
+ } p;
+ char word[1];
+} SPELL;
+
+#define SPELLHDRSZ (offsetof(SPELL, word))
+
+typedef struct aff_struct
+{
+ uint32
+ flag:8,
+ type:1,
+ flagflags:7,
+ issimple:1,
+ isregis:1,
+ replen:14;
+ char *find;
+ char *repl;
+ union
+ {
+ regex_t regex;
+ Regis regis;
+ } reg;
+} AFFIX;
+
+/*
+ * affixes use deictinary flags too
+ */
+#define FF_COMPOUNDPERMITFLAG 0x10
+#define FF_COMPOUNDFORBIDFLAG 0x20
+#define FF_CROSSPRODUCT 0x40
+#define FF_SUFFIX 1
+#define FF_PREFIX 0
+
+struct AffixNode;
+
+typedef struct
+{
+ uint32
+ val:8,
+ naff:24;
+ AFFIX **aff;
+ struct AffixNode *node;
+} AffixNodeData;
+
+typedef struct AffixNode
+{
+ uint32 isvoid:1,
+ length:31;
+ AffixNodeData data[1];
+} AffixNode;
+
+#define ANHRDSZ (sizeof(uint32))
+
+typedef struct
+{
+ char *affix;
+ int len;
+ bool issuffix;
+} CMPDAffix;
+
+typedef struct
+{
+ int maffixes;
+ int naffixes;
+ AFFIX *Affix;
+
+ int nspell;
+ int mspell;
+ SPELL **Spell;
+
+ AffixNode *Suffix;
+ AffixNode *Prefix;
+
+ SPNode *Dictionary;
+ char **AffixData;
+ int lenAffixData;
+ int nAffixData;
+
+ CMPDAffix *CompoundAffix;
+
+ unsigned char flagval[256];
+ bool usecompound;
+} IspellDict;
+
+extern TSLexeme *NINormalizeWord(IspellDict * Conf, char *word);
+extern void NIImportAffixes(IspellDict * Conf, const char *filename);
+extern void NIImportDictionary(IspellDict * Conf, const char *filename);
+extern void NISortDictionary(IspellDict * Conf);
+extern void NISortAffixes(IspellDict * Conf);
+
+#endif
diff --git a/src/include/tsearch/ts_cache.h b/src/include/tsearch/ts_cache.h
new file mode 100644
index 00000000000..ac309f8c324
--- /dev/null
+++ b/src/include/tsearch/ts_cache.h
@@ -0,0 +1,98 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_cache.h
+ * Tsearch related object caches.
+ *
+ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/tsearch/ts_cache.h,v 1.1 2007/08/21 01:11:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef TS_CACHE_H
+#define TS_CACHE_H
+
+#include "fmgr.h"
+#include "utils/guc.h"
+
+
+/*
+ * All TS*CacheEntry structs must share this common header
+ * (see InvalidateTSCacheCallBack)
+ */
+typedef struct TSAnyCacheEntry
+{
+ Oid objId;
+ bool isvalid;
+} TSAnyCacheEntry;
+
+
+typedef struct TSParserCacheEntry
+{
+ /* prsId is the hash lookup key and MUST BE FIRST */
+ Oid prsId; /* OID of the parser */
+ bool isvalid;
+
+ Oid startOid;
+ Oid tokenOid;
+ Oid endOid;
+ Oid headlineOid;
+ Oid lextypeOid;
+
+ /*
+ * Pre-set-up fmgr call of most needed parser's methods
+ */
+ FmgrInfo prsstart;
+ FmgrInfo prstoken;
+ FmgrInfo prsend;
+ FmgrInfo prsheadline;
+} TSParserCacheEntry;
+
+typedef struct TSDictionaryCacheEntry
+{
+ /* dictId is the hash lookup key and MUST BE FIRST */
+ Oid dictId;
+ bool isvalid;
+
+ /* most frequent fmgr call */
+ Oid lexizeOid;
+ FmgrInfo lexize;
+
+ MemoryContext dictCtx; /* memory context to store private data */
+ void *dictData;
+} TSDictionaryCacheEntry;
+
+typedef struct
+{
+ int len;
+ Oid *dictIds;
+} ListDictionary;
+
+typedef struct
+{
+ /* cfgId is the hash lookup key and MUST BE FIRST */
+ Oid cfgId;
+ bool isvalid;
+
+ Oid prsId;
+
+ int lenmap;
+ ListDictionary *map;
+} TSConfigCacheEntry;
+
+
+/*
+ * GUC variable for current configuration
+ */
+extern char *TSCurrentConfig;
+
+
+extern TSParserCacheEntry *lookup_ts_parser_cache(Oid prsId);
+extern TSDictionaryCacheEntry *lookup_ts_dictionary_cache(Oid dictId);
+extern TSConfigCacheEntry *lookup_ts_config_cache(Oid cfgId);
+
+extern Oid getTSCurrentConfig(bool emitError);
+extern const char *assignTSCurrentConfig(const char *newval, bool doit, GucSource source);
+
+#endif /* TS_CACHE_H */
diff --git a/src/include/tsearch/ts_locale.h b/src/include/tsearch/ts_locale.h
new file mode 100644
index 00000000000..8a197666473
--- /dev/null
+++ b/src/include/tsearch/ts_locale.h
@@ -0,0 +1,88 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_locale.h
+ * helper utilities for tsearch
+ *
+ * Copyright (c) 1998-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/tsearch/ts_locale.h,v 1.1 2007/08/21 01:11:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef __TSLOCALE_H__
+#define __TSLOCALE_H__
+
+#include <ctype.h>
+#include <limits.h>
+
+#include "utils/pg_locale.h"
+#include "mb/pg_wchar.h"
+
+/*
+ * towlower() and friends should be in <wctype.h>, but some pre-C99 systems
+ * declare them in <wchar.h>.
+ */
+#ifdef HAVE_WCHAR_H
+#include <wchar.h>
+#endif
+#ifdef HAVE_WCTYPE_H
+#include <wctype.h>
+#endif
+
+#if defined(HAVE_WCSTOMBS) && defined(HAVE_TOWLOWER)
+#define TS_USE_WIDE
+#endif
+
+#define TOUCHAR(x) (*((unsigned char*)(x)))
+
+#ifdef TS_USE_WIDE
+
+size_t char2wchar(wchar_t *to, const char *from, size_t len);
+
+#ifdef WIN32
+
+size_t wchar2char(char *to, const wchar_t *from, size_t len);
+#else /* WIN32 */
+
+/* correct wcstombs */
+#define wchar2char wcstombs
+
+#endif /* WIN32 */
+
+#define t_isdigit(x) ( pg_mblen(x)==1 && isdigit( TOUCHAR(x) ) )
+#define t_isspace(x) ( pg_mblen(x)==1 && isspace( TOUCHAR(x) ) )
+extern int _t_isalpha(const char *ptr);
+
+#define t_isalpha(x) ( (pg_mblen(x)==1) ? isalpha( TOUCHAR(x) ) : _t_isalpha(x) )
+extern int _t_isprint(const char *ptr);
+
+#define t_isprint(x) ( (pg_mblen(x)==1) ? isprint( TOUCHAR(x) ) : _t_isprint(x) )
+/*
+ * t_iseq() should be called only for ASCII symbols
+ */
+#define t_iseq(x,c) ( (pg_mblen(x)==1) ? ( TOUCHAR(x) == ((unsigned char)(c)) ) : false )
+
+#define COPYCHAR(d,s) do { \
+ int lll = pg_mblen( s ); \
+ \
+ while( lll-- ) \
+ TOUCHAR((d)+lll) = TOUCHAR((s)+lll); \
+} while(0)
+
+#else /* not def TS_USE_WIDE */
+
+#define t_isdigit(x) isdigit( TOUCHAR(x) )
+#define t_isspace(x) isspace( TOUCHAR(x) )
+#define t_isalpha(x) isalpha( TOUCHAR(x) )
+#define t_isprint(x) isprint( TOUCHAR(x) )
+#define t_iseq(x,c) ( TOUCHAR(x) == ((unsigned char)(c)) )
+
+#define COPYCHAR(d,s) TOUCHAR(d) = TOUCHAR(s)
+#endif
+
+char *lowerstr(char *str);
+char *lowerstr_with_len(char *str, int len);
+char *recode_and_lowerstr(char *str);
+
+#endif /* __TSLOCALE_H__ */
diff --git a/src/include/tsearch/ts_public.h b/src/include/tsearch/ts_public.h
new file mode 100644
index 00000000000..8e8fa5cc6ff
--- /dev/null
+++ b/src/include/tsearch/ts_public.h
@@ -0,0 +1,128 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_public.h
+ * Public interface to various tsearch modules, such as
+ * parsers and dictionaries.
+ *
+ * Copyright (c) 1998-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/tsearch/ts_public.h,v 1.1 2007/08/21 01:11:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _PG_TS_PUBLIC_H_
+#define _PG_TS_PUBLIC_H_
+
+#include "tsearch/ts_type.h"
+
+/*
+ * Parser's framework
+ */
+
+/*
+ * returning type for prslextype method of parser
+ */
+typedef struct
+{
+ int lexid;
+ char *alias;
+ char *descr;
+} LexDescr;
+
+/*
+ * Interface to headline generator
+ */
+typedef struct
+{
+ uint32 selected:1,
+ in:1,
+ replace:1,
+ repeated:1,
+ unused:4,
+ type:8,
+ len:16;
+ char *word;
+ QueryItem *item;
+} HeadlineWordEntry;
+
+typedef struct
+{
+ HeadlineWordEntry *words;
+ int4 lenwords;
+ int4 curwords;
+ char *startsel;
+ char *stopsel;
+ int2 startsellen;
+ int2 stopsellen;
+} HeadlineParsedText;
+
+/*
+ * Common useful things for tsearch subsystem
+ */
+
+/* simple parser of cfg string looking like "key=val, key='val'" */
+typedef struct
+{
+ char *key;
+ char *value;
+} Map;
+
+extern void parse_keyvalpairs(text *in, Map ** m);
+
+extern char *get_tsearch_config_filename(const char *basename,
+ const char *extension);
+
+extern char *pnstrdup(const char *in, int len);
+
+/*
+ * Often useful stopword list management
+ */
+typedef struct
+{
+ int len;
+ char **stop;
+ char *(*wordop) (char *);
+} StopList;
+
+extern void sortstoplist(StopList * s);
+extern void readstoplist(char *in, StopList * s);
+extern bool searchstoplist(StopList * s, char *key);
+
+/*
+ * Interface with dictionaries
+ */
+
+/* return struct for any lexize function */
+typedef struct
+{
+ /*
+ * number of variant of split word , for example Word 'fotballklubber'
+ * (norwegian) has two varian to split: ( fotball, klubb ) and ( fot,
+ * ball, klubb ). So, dictionary should return: nvariant lexeme 1 fotball
+ * 1 klubb 2 fot 2 ball 2 klubb
+ */
+ uint16 nvariant;
+
+ uint16 flags;
+
+ /* C-string */
+ char *lexeme;
+} TSLexeme;
+
+#define TSL_ADDPOS 0x01
+
+/*
+ * Struct for supporting complex dictionaries like
+ * thesaurus, pointer to is an 4-th argument for
+ * dictlexize method
+ */
+typedef struct
+{
+ bool isend; /* in: marks for lexize_info about text end is
+ * reached */
+ bool getnext; /* out: dict wants next lexeme */
+ void *private; /* internal dict state between calls with
+ * getnext == true */
+} DictSubState;
+
+#endif /* _PG_TS_PUBLIC_H_ */
diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h
new file mode 100644
index 00000000000..ec22f96f59f
--- /dev/null
+++ b/src/include/tsearch/ts_type.h
@@ -0,0 +1,240 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_type.h
+ * Definitions for the tsvector and tsquery types
+ *
+ * Copyright (c) 1998-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/tsearch/ts_type.h,v 1.1 2007/08/21 01:11:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _PG_TSTYPE_H_
+#define _PG_TSTYPE_H_
+
+#include "fmgr.h"
+
+/*
+ * TSVector type.
+ * Note, tsvectorsend/recv believe that sizeof(WordEntry) == 4
+ */
+
+typedef struct
+{
+ uint32
+ haspos:1,
+ len:11, /* MAX 2Kb */
+ pos:20; /* MAX 1Mb */
+} WordEntry;
+
+#define MAXSTRLEN ( 1<<11 )
+#define MAXSTRPOS ( 1<<20 )
+
+/*
+ * Equivalent to
+ * typedef struct {
+ * uint16
+ * weight:2,
+ * pos:14;
+ * }
+ */
+
+typedef uint16 WordEntryPos;
+
+#define WEP_GETWEIGHT(x) ( (x) >> 14 )
+#define WEP_GETPOS(x) ( (x) & 0x3fff )
+
+#define WEP_SETWEIGHT(x,v) ( (x) = ( (v) << 14 ) | ( (x) & 0x3fff ) )
+#define WEP_SETPOS(x,v) ( (x) = ( (x) & 0xc000 ) | ( (v) & 0x3fff ) )
+
+#define MAXENTRYPOS (1<<14)
+#define MAXNUMPOS (256)
+#define LIMITPOS(x) ( ( (x) >= MAXENTRYPOS ) ? (MAXENTRYPOS-1) : (x) )
+
+/*
+ * Structure of tsvector datatype:
+ * 1) standard varlena header
+ * 2) int4 size - number of lexemes or WordEntry array, which is the same
+ * 3) Array of WordEntry - sorted array, comparison based on word's length
+ * and strncmp(). WordEntry->pos points number of
+ * bytes from end of WordEntry array to start of
+ * corresponding lexeme.
+ * 4) Lexeme's storage:
+ * SHORTALIGNED(lexeme) and position information if it exists
+ * Position information: first int2 - is a number of positions and it
+ * follows array of WordEntryPos
+ */
+
+typedef struct
+{
+ int32 vl_len_; /* varlena header (do not touch directly!) */
+ int4 size;
+ char data[1];
+} TSVectorData;
+
+typedef TSVectorData *TSVector;
+
+#define DATAHDRSIZE (VARHDRSZ + sizeof(int4))
+#define CALCDATASIZE(x, lenstr) ( (x) * sizeof(WordEntry) + DATAHDRSIZE + (lenstr) )
+#define ARRPTR(x) ( (WordEntry*) ( (char*)(x) + DATAHDRSIZE ) )
+#define STRPTR(x) ( (char*)(x) + DATAHDRSIZE + ( sizeof(WordEntry) * ((TSVector)(x))->size ) )
+#define STRSIZE(x) ( ((TSVector)(x))->len - DATAHDRSIZE - ( sizeof(WordEntry) * ((TSVector)(x))->size ) )
+#define _POSDATAPTR(x,e) (STRPTR(x)+((WordEntry*)(e))->pos+SHORTALIGN(((WordEntry*)(e))->len))
+#define POSDATALEN(x,e) ( ( ((WordEntry*)(e))->haspos ) ? (*(uint16*)_POSDATAPTR(x,e)) : 0 )
+#define POSDATAPTR(x,e) ( (WordEntryPos*)( _POSDATAPTR(x,e)+sizeof(uint16) ) )
+
+/*
+ * fmgr interface macros
+ */
+
+#define DatumGetTSVector(X) ((TSVector) PG_DETOAST_DATUM(X))
+#define DatumGetTSVectorCopy(X) ((TSVector) PG_DETOAST_DATUM_COPY(X))
+#define TSVectorGetDatum(X) PointerGetDatum(X)
+#define PG_GETARG_TSVECTOR(n) DatumGetTSVector(PG_GETARG_DATUM(n))
+#define PG_GETARG_TSVECTOR_COPY(n) DatumGetTSVectorCopy(PG_GETARG_DATUM(n))
+#define PG_RETURN_TSVECTOR(x) return TSVectorGetDatum(x)
+
+/*
+ * I/O
+ */
+extern Datum tsvectorin(PG_FUNCTION_ARGS);
+extern Datum tsvectorout(PG_FUNCTION_ARGS);
+extern Datum tsvectorsend(PG_FUNCTION_ARGS);
+extern Datum tsvectorrecv(PG_FUNCTION_ARGS);
+
+/*
+ * operations with tsvector
+ */
+extern Datum tsvector_lt(PG_FUNCTION_ARGS);
+extern Datum tsvector_le(PG_FUNCTION_ARGS);
+extern Datum tsvector_eq(PG_FUNCTION_ARGS);
+extern Datum tsvector_ne(PG_FUNCTION_ARGS);
+extern Datum tsvector_ge(PG_FUNCTION_ARGS);
+extern Datum tsvector_gt(PG_FUNCTION_ARGS);
+extern Datum tsvector_cmp(PG_FUNCTION_ARGS);
+
+extern Datum tsvector_length(PG_FUNCTION_ARGS);
+extern Datum tsvector_strip(PG_FUNCTION_ARGS);
+extern Datum tsvector_setweight(PG_FUNCTION_ARGS);
+extern Datum tsvector_concat(PG_FUNCTION_ARGS);
+extern Datum tsvector_update_trigger_byid(PG_FUNCTION_ARGS);
+extern Datum tsvector_update_trigger_bycolumn(PG_FUNCTION_ARGS);
+
+extern Datum ts_match_vq(PG_FUNCTION_ARGS);
+extern Datum ts_match_qv(PG_FUNCTION_ARGS);
+extern Datum ts_match_tt(PG_FUNCTION_ARGS);
+extern Datum ts_match_tq(PG_FUNCTION_ARGS);
+
+extern Datum ts_stat1(PG_FUNCTION_ARGS);
+extern Datum ts_stat2(PG_FUNCTION_ARGS);
+
+extern Datum ts_rank_tt(PG_FUNCTION_ARGS);
+extern Datum ts_rank_wtt(PG_FUNCTION_ARGS);
+extern Datum ts_rank_ttf(PG_FUNCTION_ARGS);
+extern Datum ts_rank_wttf(PG_FUNCTION_ARGS);
+extern Datum ts_rankcd_tt(PG_FUNCTION_ARGS);
+extern Datum ts_rankcd_wtt(PG_FUNCTION_ARGS);
+extern Datum ts_rankcd_ttf(PG_FUNCTION_ARGS);
+extern Datum ts_rankcd_wttf(PG_FUNCTION_ARGS);
+
+
+/*
+ * TSQuery
+ */
+
+/*
+ * QueryItem is one node in tsquery - operator or operand.
+ */
+
+typedef struct QueryItem
+{
+ int8 type; /* operand or kind of operator */
+ int8 weight; /* weights of operand to search */
+ int2 left; /* pointer to left operand Right operand is
+ * item + 1, left operand is placed
+ * item+item->left */
+ int4 val; /* crc32 value of operand's value */
+ /* pointer to text value of operand, must correlate with WordEntry */
+ uint32
+ istrue:1, /* use for ranking in Cover */
+ length:11,
+ distance:20;
+} QueryItem;
+
+/*
+ * It's impossible to use offsetof(QueryItem, istrue)
+ */
+#define HDRSIZEQI ( sizeof(int8) + sizeof(int8) + sizeof(int2) + sizeof(int4) )
+
+/*
+ * Storage:
+ * (len)(size)(array of ITEM)(array of operand in text form)
+ * operands are always finished by '\0'
+ */
+
+typedef struct
+{
+ int32 vl_len_; /* varlena header (do not touch directly!) */
+ int4 size; /* number of QueryItems */
+ char data[1];
+} TSQueryData;
+
+typedef TSQueryData *TSQuery;
+
+#define HDRSIZETQ ( VARHDRSZ + sizeof(int4) )
+#define COMPUTESIZE(size,lenofoperand) ( HDRSIZETQ + (size) * sizeof(QueryItem) + (lenofoperand) )
+#define GETQUERY(x) ((QueryItem*)( (char*)(x)+HDRSIZETQ ))
+#define GETOPERAND(x) ( (char*)GETQUERY(x) + ((TSQuery)(x))->size * sizeof(QueryItem) )
+#define OPERANDSSIZE(x) ( (x)->len - HDRSIZETQ - (x)->size * sizeof(QueryItem) )
+
+#define ISOPERATOR(x) ( pg_mblen(x)==1 && ( *(x)=='!' || *(x)=='&' || *(x)=='|' || *(x)=='(' || *(x)==')' ) )
+
+
+/*
+ * fmgr interface macros
+ * Note, TSQuery type marked as plain storage, so it can't be toasted
+ * but PG_DETOAST_DATUM_COPY is used for simplicity
+ */
+
+#define DatumGetTSQuery(X) ((TSQuery) DatumGetPointer(X))
+#define DatumGetTSQueryCopy(X) ((TSQuery) PG_DETOAST_DATUM_COPY(X))
+#define TSQueryGetDatum(X) PointerGetDatum(X)
+#define PG_GETARG_TSQUERY(n) DatumGetTSQuery(PG_GETARG_DATUM(n))
+#define PG_GETARG_TSQUERY_COPY(n) DatumGetTSQueryCopy(PG_GETARG_DATUM(n))
+#define PG_RETURN_TSQUERY(x) return TSQueryGetDatum(x)
+
+/*
+ * I/O
+ */
+extern Datum tsqueryin(PG_FUNCTION_ARGS);
+extern Datum tsqueryout(PG_FUNCTION_ARGS);
+extern Datum tsquerysend(PG_FUNCTION_ARGS);
+extern Datum tsqueryrecv(PG_FUNCTION_ARGS);
+
+/*
+ * operations with tsquery
+ */
+extern Datum tsquery_lt(PG_FUNCTION_ARGS);
+extern Datum tsquery_le(PG_FUNCTION_ARGS);
+extern Datum tsquery_eq(PG_FUNCTION_ARGS);
+extern Datum tsquery_ne(PG_FUNCTION_ARGS);
+extern Datum tsquery_ge(PG_FUNCTION_ARGS);
+extern Datum tsquery_gt(PG_FUNCTION_ARGS);
+extern Datum tsquery_cmp(PG_FUNCTION_ARGS);
+
+extern Datum tsquerytree(PG_FUNCTION_ARGS);
+extern Datum tsquery_numnode(PG_FUNCTION_ARGS);
+
+extern Datum tsquery_and(PG_FUNCTION_ARGS);
+extern Datum tsquery_or(PG_FUNCTION_ARGS);
+extern Datum tsquery_not(PG_FUNCTION_ARGS);
+
+extern Datum tsquery_rewrite(PG_FUNCTION_ARGS);
+extern Datum tsquery_rewrite_query(PG_FUNCTION_ARGS);
+extern Datum ts_rewrite_accum(PG_FUNCTION_ARGS);
+extern Datum ts_rewrite_finish(PG_FUNCTION_ARGS);
+
+extern Datum tsq_mcontains(PG_FUNCTION_ARGS);
+extern Datum tsq_mcontained(PG_FUNCTION_ARGS);
+
+#endif /* _PG_TSTYPE_H_ */
diff --git a/src/include/tsearch/ts_utils.h b/src/include/tsearch/ts_utils.h
new file mode 100644
index 00000000000..f84db4c6e41
--- /dev/null
+++ b/src/include/tsearch/ts_utils.h
@@ -0,0 +1,315 @@
+/*-------------------------------------------------------------------------
+ *
+ * ts_utils.h
+ * helper utilities for tsearch
+ *
+ * Copyright (c) 1998-2007, PostgreSQL Global Development Group
+ *
+ * $PostgreSQL: pgsql/src/include/tsearch/ts_utils.h,v 1.1 2007/08/21 01:11:29 tgl Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef _PG_TS_UTILS_H_
+#define _PG_TS_UTILS_H_
+
+#include "tsearch/ts_type.h"
+
+/*
+ * Common parse definitions for tsvector and tsquery
+ */
+
+typedef struct
+{
+ WordEntry entry; /* should be first ! */
+ WordEntryPos *pos;
+} WordEntryIN;
+
+typedef struct
+{
+ char *prsbuf;
+ char *word;
+ char *curpos;
+ int4 len;
+ int4 state;
+ int4 alen;
+ WordEntryPos *pos;
+ bool oprisdelim;
+} TSVectorParseState;
+
+extern bool gettoken_tsvector(TSVectorParseState *state);
+
+struct ParseQueryNode;
+typedef struct
+{
+ char *buffer; /* entire string we are scanning */
+ char *buf; /* current scan point */
+ int4 state;
+ int4 count;
+
+ /* reverse polish notation in list (for temprorary usage) */
+ struct ParseQueryNode *str;
+
+ /* number in str */
+ int4 num;
+
+ /* text-form operand */
+ int4 lenop;
+ int4 sumlen;
+ char *op;
+ char *curop;
+
+ /* state for value's parser */
+ TSVectorParseState valstate;
+ /* tscfg */
+ Oid cfg_id;
+} TSQueryParserState;
+
+extern TSQuery parse_tsquery(char *buf,
+ void (*pushval) (TSQueryParserState *, int, char *, int, int2),
+ Oid cfg_id, bool isplain);
+extern void pushval_asis(TSQueryParserState * state,
+ int type, char *strval, int lenval, int2 weight);
+extern void pushquery(TSQueryParserState * state, int4 type, int4 val,
+ int4 distance, int4 lenval, int2 weight);
+
+/*
+ * parse plain text and lexize words
+ */
+typedef struct
+{
+ uint16 len;
+ uint16 nvariant;
+ union
+ {
+ uint16 pos;
+ uint16 *apos;
+ } pos;
+ char *word;
+ uint32 alen;
+} ParsedWord;
+
+typedef struct
+{
+ ParsedWord *words;
+ int4 lenwords;
+ int4 curwords;
+ int4 pos;
+} ParsedText;
+
+extern void parsetext(Oid cfgId, ParsedText * prs, char *buf, int4 buflen);
+
+/*
+ * headline framework, flow in common to generate:
+ * 1 parse text with hlparsetext
+ * 2 parser-specific function to find part
+ * 3 generatHeadline to generate result text
+ */
+
+typedef struct
+{
+ uint32 selected:1,
+ in:1,
+ replace:1,
+ repeated:1,
+ unused:4,
+ type:8,
+ len:16;
+ char *word;
+ QueryItem *item;
+} HeadlineWord;
+
+typedef struct
+{
+ HeadlineWord *words;
+ int4 lenwords;
+ int4 curwords;
+ char *startsel;
+ char *stopsel;
+ int2 startsellen;
+ int2 stopsellen;
+} HeadlineText;
+
+extern void hlparsetext(Oid cfgId, HeadlineText * prs, TSQuery query,
+ char *buf, int4 buflen);
+extern text *generatHeadline(HeadlineText * prs);
+
+/*
+ * token/node types for parsing
+ */
+#define END 0
+#define ERR 1
+#define VAL 2
+#define OPR 3
+#define OPEN 4
+#define CLOSE 5
+#define VALSTOP 6 /* for stop words */
+
+/*
+ * Common check function for tsvector @@ tsquery
+ */
+
+extern bool TS_execute(QueryItem * curitem, void *checkval, bool calcnot,
+ bool (*chkcond) (void *checkval, QueryItem * val));
+
+/*
+ * Useful conversion macros
+ */
+#define TextPGetCString(t) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(t)))
+#define CStringGetTextP(c) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(c)))
+
+/*
+ * to_ts* - text transformation to tsvector, tsquery
+ */
+extern TSVector make_tsvector(ParsedText *prs);
+
+extern Datum to_tsvector_byid(PG_FUNCTION_ARGS);
+extern Datum to_tsvector(PG_FUNCTION_ARGS);
+extern Datum to_tsquery_byid(PG_FUNCTION_ARGS);
+extern Datum to_tsquery(PG_FUNCTION_ARGS);
+extern Datum plainto_tsquery_byid(PG_FUNCTION_ARGS);
+extern Datum plainto_tsquery(PG_FUNCTION_ARGS);
+
+/*
+ * GiST support function
+ */
+
+extern Datum gtsvector_compress(PG_FUNCTION_ARGS);
+extern Datum gtsvector_decompress(PG_FUNCTION_ARGS);
+extern Datum gtsvector_consistent(PG_FUNCTION_ARGS);
+extern Datum gtsvector_union(PG_FUNCTION_ARGS);
+extern Datum gtsvector_same(PG_FUNCTION_ARGS);
+extern Datum gtsvector_penalty(PG_FUNCTION_ARGS);
+extern Datum gtsvector_picksplit(PG_FUNCTION_ARGS);
+
+/*
+ * IO functions for pseudotype gtsvector
+ * used internally in tsvector GiST opclass
+ */
+extern Datum gtsvectorin(PG_FUNCTION_ARGS);
+extern Datum gtsvectorout(PG_FUNCTION_ARGS);
+
+/*
+ * GIN support function
+ */
+
+extern Datum gin_extract_tsvector(PG_FUNCTION_ARGS);
+extern Datum gin_extract_query(PG_FUNCTION_ARGS);
+extern Datum gin_ts_consistent(PG_FUNCTION_ARGS);
+
+/*
+ * Possible strategy numbers for indexes
+ * TSearchStrategyNumber - (tsvector|text) @@ tsquery
+ * TSearchWithClassStrategyNumber - tsvector @@@ tsquery
+ */
+#define TSearchStrategyNumber 1
+#define TSearchWithClassStrategyNumber 2
+
+/*
+ * TSQuery Utilities
+ */
+extern QueryItem *clean_NOT(QueryItem * ptr, int4 *len);
+extern QueryItem *clean_fakeval(QueryItem * ptr, int4 *len);
+
+typedef struct QTNode
+{
+ QueryItem *valnode;
+ uint32 flags;
+ int4 nchild;
+ char *word;
+ uint32 sign;
+ struct QTNode **child;
+} QTNode;
+
+#define QTN_NEEDFREE 0x01
+#define QTN_NOCHANGE 0x02
+#define QTN_WORDFREE 0x04
+
+typedef uint64 TSQuerySign;
+
+#define TSQS_SIGLEN (sizeof(TSQuerySign)*BITS_PER_BYTE)
+
+
+extern QTNode *QT2QTN(QueryItem * in, char *operand);
+extern TSQuery QTN2QT(QTNode *in);
+extern void QTNFree(QTNode * in);
+extern void QTNSort(QTNode * in);
+extern void QTNTernary(QTNode * in);
+extern void QTNBinary(QTNode * in);
+extern int QTNodeCompare(QTNode * an, QTNode * bn);
+extern QTNode *QTNCopy(QTNode *in);
+extern bool QTNEq(QTNode * a, QTNode * b);
+extern TSQuerySign makeTSQuerySign(TSQuery a);
+
+/*
+ * TSQuery GiST support
+ */
+extern Datum gtsquery_compress(PG_FUNCTION_ARGS);
+extern Datum gtsquery_decompress(PG_FUNCTION_ARGS);
+extern Datum gtsquery_consistent(PG_FUNCTION_ARGS);
+extern Datum gtsquery_union(PG_FUNCTION_ARGS);
+extern Datum gtsquery_same(PG_FUNCTION_ARGS);
+extern Datum gtsquery_penalty(PG_FUNCTION_ARGS);
+extern Datum gtsquery_picksplit(PG_FUNCTION_ARGS);
+
+/*
+ * Parser interface to SQL
+ */
+extern Datum ts_token_type_byid(PG_FUNCTION_ARGS);
+extern Datum ts_token_type_byname(PG_FUNCTION_ARGS);
+extern Datum ts_parse_byid(PG_FUNCTION_ARGS);
+extern Datum ts_parse_byname(PG_FUNCTION_ARGS);
+
+/*
+ * Default word parser
+ */
+
+extern Datum prsd_start(PG_FUNCTION_ARGS);
+extern Datum prsd_nexttoken(PG_FUNCTION_ARGS);
+extern Datum prsd_end(PG_FUNCTION_ARGS);
+extern Datum prsd_headline(PG_FUNCTION_ARGS);
+extern Datum prsd_lextype(PG_FUNCTION_ARGS);
+
+/*
+ * Dictionary interface to SQL
+ */
+extern Datum ts_lexize_byid(PG_FUNCTION_ARGS);
+extern Datum ts_lexize_byname(PG_FUNCTION_ARGS);
+
+/*
+ * Simple built-in dictionary
+ */
+extern Datum dsimple_init(PG_FUNCTION_ARGS);
+extern Datum dsimple_lexize(PG_FUNCTION_ARGS);
+
+/*
+ * Synonym built-in dictionary
+ */
+extern Datum dsynonym_init(PG_FUNCTION_ARGS);
+extern Datum dsynonym_lexize(PG_FUNCTION_ARGS);
+
+/*
+ * ISpell dictionary
+ */
+extern Datum dispell_init(PG_FUNCTION_ARGS);
+extern Datum dispell_lexize(PG_FUNCTION_ARGS);
+
+/*
+ * Thesaurus
+ */
+extern Datum thesaurus_init(PG_FUNCTION_ARGS);
+extern Datum thesaurus_lexize(PG_FUNCTION_ARGS);
+
+/*
+ * headline
+ */
+extern Datum ts_headline_byid_opt(PG_FUNCTION_ARGS);
+extern Datum ts_headline_byid(PG_FUNCTION_ARGS);
+extern Datum ts_headline(PG_FUNCTION_ARGS);
+extern Datum ts_headline_opt(PG_FUNCTION_ARGS);
+
+/*
+ * current cfg
+ */
+extern Datum get_current_ts_config(PG_FUNCTION_ARGS);
+
+#endif /* _PG_TS_UTILS_H_ */
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index 5eb054e1466..92d153ea5a4 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.101 2007/03/26 16:58:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.102 2007/08/21 01:11:29 tgl Exp $
*
* NOTES
* An ACL array is simply an array of AclItems, representing the union
@@ -181,6 +181,8 @@ typedef enum AclObjectKind
ACL_KIND_OPFAMILY, /* pg_opfamily */
ACL_KIND_CONVERSION, /* pg_conversion */
ACL_KIND_TABLESPACE, /* pg_tablespace */
+ ACL_KIND_TSDICTIONARY, /* pg_ts_dict */
+ ACL_KIND_TSCONFIGURATION, /* pg_ts_config */
MAX_ACL_KIND /* MUST BE LAST */
} AclObjectKind;
@@ -281,5 +283,7 @@ extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
extern bool pg_opfamily_ownercheck(Oid opf_oid, Oid roleid);
extern bool pg_database_ownercheck(Oid db_oid, Oid roleid);
extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
+extern bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid);
+extern bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid);
#endif /* ACL_H */
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index de677902d47..ee0532f63b7 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.299 2007/07/25 12:22:54 mha Exp $
+ * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.300 2007/08/21 01:11:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -523,6 +523,14 @@ extern Datum regtypein(PG_FUNCTION_ARGS);
extern Datum regtypeout(PG_FUNCTION_ARGS);
extern Datum regtyperecv(PG_FUNCTION_ARGS);
extern Datum regtypesend(PG_FUNCTION_ARGS);
+extern Datum regconfigin(PG_FUNCTION_ARGS);
+extern Datum regconfigout(PG_FUNCTION_ARGS);
+extern Datum regconfigrecv(PG_FUNCTION_ARGS);
+extern Datum regconfigsend(PG_FUNCTION_ARGS);
+extern Datum regdictionaryin(PG_FUNCTION_ARGS);
+extern Datum regdictionaryout(PG_FUNCTION_ARGS);
+extern Datum regdictionaryrecv(PG_FUNCTION_ARGS);
+extern Datum regdictionarysend(PG_FUNCTION_ARGS);
extern Datum text_regclass(PG_FUNCTION_ARGS);
extern List *stringToQualifiedNameList(const char *string);
extern char *format_procedure(Oid procedure_oid);
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 12cd9a72f22..b34e8803216 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.69 2007/04/02 03:49:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.70 2007/08/21 01:11:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -65,8 +65,17 @@
#define RELOID 34
#define RULERELNAME 35
#define STATRELATT 36
-#define TYPENAMENSP 37
-#define TYPEOID 38
+#define TSCONFIGMAP 37
+#define TSCONFIGNAMENSP 38
+#define TSCONFIGOID 39
+#define TSDICTNAMENSP 40
+#define TSDICTOID 41
+#define TSPARSERNAMENSP 42
+#define TSPARSEROID 43
+#define TSTEMPLATENAMENSP 44
+#define TSTEMPLATEOID 45
+#define TYPENAMENSP 46
+#define TYPEOID 47
extern void InitCatalogCache(void);
extern void InitCatalogCachePhase2(void);
diff --git a/src/makefiles/Makefile.hpux b/src/makefiles/Makefile.hpux
index 1316fa1d68d..f91dfae391c 100644
--- a/src/makefiles/Makefile.hpux
+++ b/src/makefiles/Makefile.hpux
@@ -38,9 +38,9 @@ else
DLSUFFIX = .sl
endif
ifeq ($(GCC), yes)
- CFLAGS_SL = -fpic
+ CFLAGS_SL = -fPIC
else
- CFLAGS_SL = +z
+ CFLAGS_SL = +Z
endif
# Rule for building shared libs (currently used only for regression test
diff --git a/src/test/regress/data/tsearch.data b/src/test/regress/data/tsearch.data
new file mode 100644
index 00000000000..29a26f2428c
--- /dev/null
+++ b/src/test/regress/data/tsearch.data
@@ -0,0 +1,508 @@
+\n
+\n
+\n
+\n
+\n
+\n
+\n
+\n
+\n i8 hy qo xa jl wr le l5 ja jx zf ro vw wd wa cc mm wh fn yd td l8 ec rv th oc ix ir sm y4 gh pr qg ue cx ww zv c9 zv tx eo f5 gd km b9 wb rm ym yl xj u7 xz uk iq tm ux di if uc hc ge
+\n gr ty ph jh po wa iw ag wq r3 yd ow rb ip et ej yl a9 dk pu y6 su ov hf xe qe sd qr zt kp ml ea tp pg dq e3 s3 hh gn hz j7 hb qs qd v0 v4 w0 nu ee wk ez un rd sz wx e7 pn yf gh uh ki kx rb qv f1 bh sr yj ry r2
+\n q1 q8 wp w9 vs ww rq de qt wo qp sa rv mc sn u8 yl
+\n hv ra sa fr qs ps 4w z5 ls wt ad wy q6 zg bd vt wa e4 ft w7 ld es yg et ic pm sw ja qv ov jm ma b3 wu wi qy ug hs wh ex rt tj en ur e2 ut gv as ui dy qy du qo gv cy lx kw xm fl x2 hd ny nu hh dt wg wh rs wb wz yy yu tj ha ak rw sw io h1 ux ku v6 wc qa rv xb s8 qd f2 zo k2 ew w4 yh yu yi
+\n rs tt gp qh wt q6 lg zh vr b8 uy uu lh px jm ww qe xu fp fd rs qu ki dr fn gq gw jv oq zt 2r lc ke wg l9 x3 x5 7g vs ar e7 u2 s8 t0 av dj kl nm u2 zp gf yw ee oc tw a1
+\n qs uz wr gq q9 rl e0 pe dj a9 hp qw aw er kq pp uu pl zo wp fr r6 ej pv u5 hh av lw ko qc pn qj ez n8 wn eu tq
+\n po h9 rd qs hr la u0 um me wp 0p rl mv rc ab r0 fe fj fk qn jh iy cn lb bl ln b5 ll yg yh qt qp uz od dq as gn cr qa wa cu fy zy vo xk eq vg mr ns yy t7 yi op th yo ov pv em tc hg az io s5 ct os wu lq dr mp hk si gx
+\n hm k5 pw a5 qh nb q3 ql wr wt z7 oz wu wh kv q8 c3 mt mg hb a3 rz pz uo y1 rb av us ek dz q0 d3 qw j2 ls wy qq jf ng eo gl ed ix em he qt du hp jc f2 m9 qp hb l4 gy zf l6 qr dn cp x1 oh qk kk s3 hy wg zs ot wj sl oz ie e9 ay it u5 ai hm gh py hz qk ki h8 ja zu qb ei vc qj hg ev h6 yh u0 tb id
+\n qg d1 bt c5 r3 iv g6 d7 rc ml gk uh yn y0 zo uh qd wh ib uo u4 om qg ql yz
+\n hb a3 q5 pl yj lo qy ki sy fo rj kk zq dl wn 7a zi wn wm yr w3 tv r1
+\n ft k6 iz qn qj q2 q3 bl zd av ro wo lk tg ea ew ed y1 ia yl ic g6 po aw sc zm qn gl wq qw zr jp wt j5 gs vt qt yc rr op yw tl ye hr i8 tb uu j0 xd lz vu nl qd fu wg pf wj bt ee wh t2 tp sz um oo tg ha u4 f5 sw pq pr ju qk mh ki zb vj ob cx df hj ef cj q6 u9 tv rv o4 sy ru fq ir
+\n ps ko uk tz vv um t9 uk k2 ja o6 ob
+\n qs nb gh ld q7 jc sp el w0 py qx i2 qe la rl qw tu ti dq ue iv oi wa qr ed t3 fg oa of rr fv qz xn wu wq te hx
+\n yb ty pq az fi qg qn la bu ji lg wg q8 mi cv rl up lg om oq ym pv in aq gg js ha on ww qr bj vn pv he b5 mh qe cc mk qt rb eu qy rw tr qo ec op sn oh e2 ao iv e4 hy dt s6 qt p1 hb ih qs wg x1 bd l1 t1 ro r9 uv wb aw gu os t0 ah e0 s0 hj pe or qj zz ql fd ks qv bq qm bg ec ry oj u8 u0 yj ru r1 yx o7
+\n z4 wr qz cg nq ir bb gb w7 e5 zc pj e9 px uo fp ts aq db q9 iy qe zv xu a9 l1 mb qw tc qu fi hw ur de e4 hk lj wo wf fi ep rl wh vh ek vp oi sv rh ay hj px aa er tv do ir
+\n tr o9 gb tt pp qa qs a5 ps rf q1 kj by ub ru ox co o8 ny wp wa ws rd kk b1 zc rl rz uo ts ig fh db qm q0 bg rr fu ld lr wb en nd cw vr hy rn qr en em au p8 so oh ut hz gq wp ow be ky wj dw t1 pl er wc ot na r9 wl ou un um wx iq sc e8 sn re rr f7 hz h4 ce wz qx wx kp px tl tx ai wq hf ec 6u rz og yt ok yy yp
+\n sa pp a7 qm qh of je qj lo ph wt h0 ji cg z8 2v xs zl mo ik hm on tu d8 av ot pn iv ez ja qn pq wy 7r mq qu p1 tu p6 ti ur pj uy ui qo i9 qa nj xm s1 ya fb 7j ro wn t6 wz yu iq yi go en pb aj f5 hf ug uh hk av pr wl wz im ja v9 u2 ks it br wv wn se ia o5 ox ei r2 ig aj sp
+\n sa tn z8 ew uo eh g8 zt wy 27 ff uh te en pd eh hv 2e wh ty oi sw xx 2p qs mx wb q3 rl eq aa eu
+\n d4 ef ta zq j2 em c0 vv wf kj dw uk ql y9 rn
+\n sq nm kl w8 ur kz c1 pc y1 g4 oi jv wr zy ew by se ec yn ti gq gt rd l5 ej yp tk da qz qx ir wm on q2 to ew
+\n rd gu z2 kj qk bl 6d wy nw xq iu 8t ri uc kq nx ql oa vi kd o6
+\n ra gr he wy q0 ow ti ia pb ha qr lv ms qu pu qw qr ml qt ep sv i5 of fm oe nl xh x1 xz u4 ha ao fc ug pw nh n9 qv kh vx uq w1 u0 ei if
+\n q1 d2 qz zd jd qb wj nt ah mj ea ed y1 et fj qe en b8 ty iv ht fv tn tm sg jb ky ai en us tl ud iu zj ql u1 ci ru iw tw
+\n fr ub h9 pd ub jk vh z6 wu wh wp 5z yt w9 w0 uy om tl rc r6 ax d7 et y2 tw dz se vf ii m3 lf b4 jf vr qw qy uf es qp en tl to ye ue ph e3 uy i0 jl pz oe qo zp wp ft ka zf qd wd kr qf l9 mm wf qx ef t3 x8 ex rg ev s8 ys it da rw al hn tc f6 fv nd nc ad fj nr x0 bx yq ti rx ok tb hx o8 dp
+\n o0 jq un xu q8 wo qq gg ta oj ec az dl bl wb
+\n o9 ij pq gu gp nv qk gg la q4 nw bo z8 9a iw wu q8 eh wi nt jk ut ys c1 r5 up y1 yl py oy ht gd td db qn cz qw lp re c7 dh j5 ia bz dj qr qt wd wf qi rt sv ul uz tl ta yr e4 tm sg pc jv hc hv lc xg xm br vf r8 na wl ou td wc up rj s8 e8 ir ys ii qk p0 lt ho wb x8 bv lw w1 rz ew aa rv ry gx o8
+\n tt hn gn un db fu uq qf d4 q3 pp ji lf wu bx q8 hx kb ny t5 bn hb ex yf ef yj g1 g2 to yk g3 ej sk hy dv qc gj qv sy bg wr na wy bx z0 rc rm ml ug te qp i5 ue oj s4 im oq qt gx sa gt l4 sv at v3 bq mv wd x3 80 x8 aq xk rg yp en gs us dq ak tz al tx o2 dg f9 kv or h4 jy k1 jo h8 kp lt os kh as tn eu ul tm su an tw sp
+\n za yi pe sh pv y4 y5 hy th jg qy qt ke ti ue qk yy ie cq wl p0 lw mf er w5
+\n k9 bt xu kc me is o5 z9 kb gv ur rc oe sk qn ve wi mm rn eu to ue uy qa xf by t1 td t7 aw up yf pr dk cg zr sc 3d at rw ec rl st zo rn do
+\n o9 z5 wy vi ya ea ee fo gf va ov ww rr wr lb ro qq vr gj nw ru ym iv s4 hu tm wo wp zs br fs wg ej du y1 yt yu e7 eb em dd pq v7 cr um ae oz 0z kc tq rw zl rt wb y9 xv tm tq di eo te gc
+\n tt un qs qn a7 qh je qj k0 o1 wr q6 wy ab q9 qm wr ea er eh pi hi sc hs m6 w1 bv lo zr tn yk ep op es ve xx sb ux hg sa gq qp wd n2 zh wf xf wj y3 wl e7 os u4 on ip kn ko qp s7 ly zn ba wu u4 kh f4 zo y9 q6 oh iw tq
+\n qa a4 gu a7 cp z1 he ma q7 lu dp w7 ea rc ee d8 y4 tw ez im ae bv ii qe vb zt lc lv wm ro lk qr hp re tw yv es fp as zu oe qu qi bp wg cp p7 v4 ek rd wc ar rj tj e8 od e0 pm h2 h4 in qf wu wi 19 bj rl rc ee yj et tw ep
+\n gv qd kj cd t3 c3 ih ws rg mc rx lh fd g8 gh cc vw b7 qe at j7 qo ws wg oy t6 t9 go eb e8 us u5 rq oe zj jy oz cj wb be ei pm og se w4 yu xw su yx if
+\n o9 ub rd hw gs z3 ql nq ru wg jc 1t kv mr zm ah dd jk w8 ej aq ig y8 pp fj li wq jj cc qr no wy wu en bx yr qy oo es fy pd tk ix ph yr sf vx pn p2 jq fs ed oy yk os ie s9 u5 ak ud gd uf kb xc u1 xm eu xw 19 wn vh w1 to ee er aa rb rn ru an r1 ei
+\n se kl 7h b6 xs ym tp an ta qb gn uo pt xi cl qp qy op vr ym ri ti tl i5 e1 e4 i9 ff i5 qp jx ht ql uo en pe ku h7 iw wn w4 ey ia si
+\n ql xt wi k6 ew sf eg up eh oy sq ja g9 i3 qe cv l1 qq bv w2 la eu wg ec ef oh fs tb pc xd qs nl qu fn dy oi iu yf re fc hj hk xv zn zz w1 ew
+\n po al hm qk jt cd ju nm li rs w9 ev ut ea 2f r4 d6 ey im pa nu wr m4 is bc xz w3 eu tb ha ft p4 ti to hr dy af i6 iz r4 jb x7 wj xg na rf gi at pn gd re wq qz ze bo wc vz sm zo my ye u7 oh dk w5 is yx tw fe dp
+\n jl za gk cm wu vq jc zc iu mb oe fo fp ic sc 2l hy qr eb p5 pf dq pa fy lc td sz oo aw u1 rj fl tz nx aq xx oz xb 55 y0
+\n uq wr lh jv ri i7 ss qo gy bt s3 u1 dy ox hg it
+\n ps hr lf jx bn qq up eh ab yl pn jg ng bz gd qr yw i9 j8 zi 3v oz at hd cx oj u9 rt uz ro ov
+\n sq ga ny se cj id rg r3 pk kv ee sh ek dk sz pp q0 mn az kp ei qi ry em ph p9 gw hc m0 cp ea mn yf t1 5y wx ol e6 ec u2 e7 uh uj uk av ql lw qx zr qv mw qg cq ww wb pw tu w2 mf ut gk af yo ie ob
+\n hn um a6 q7 af du r4 up tp ej sk lo le m8 rp eu ei qi ky op of tp ur oj hu tb dy qu gt tf oz wc s7 e7 ua pw ax nb wx wy fj wn 18 wv es yq ok w4 uz yx yc
+\n pa qg qh q4 fv qz kx q6 cp gb c6 pr eh id in qw we bk wn qq b6 qy qu es ic s1 og gn wp op qf ic ro os yp rj fj ag oc ay da fv wl qp f1 yx n7 ea w2 ly yj iq iw rm o5
+\n o9 ps d3 lp wr qc md e5 rk w0 pm gx lf ku qt qp to tc pk fb tb qi lh nt yd vt ot ra tg gd zx wx vj rq cr hm ma jp vg u8 rt ei it
+\n dx dv h9 rf qf uw a8 qh uv k3 ri is yr r3 eq uu tz yn y6 qc ps jf wq xe wx lc qr j4 ku xx nb 4z sr tr uq p6 uz of i6 s1 fs pj tc hu qu hz f1 hp lj s4 qx tg yp gs ob tz ds sw pm ug hm ip ql le vl wq tb xv eq w2 yg w4 st o6
+\n qd q4 pa z6 qz ia 70 r3 mb iu es r5 gh t9 cj vz qw mb ko vt qr qt gh qo ty eb kq n1 xb ef rp ek gu rg s7 rj sn ai hg o1 uj pr jt fg v0 tq tx ww bj bm ct w1 zi rn ox iw ri
+\n al rd w8 vp yd yk r0 pi po se sr qa l0 qk ir e9 hm kc rz aa w6
+\n un pq qd a8 z2 qk z5 ws bi xy qx wg wp t4 mj gv qm rg c6 w7 w9 es y1 g2 ej yz gg qc qn wq qw m9 wx qe kr 27 fp fq m7 xp 3p qr rr tr ij il eh au s1 uc fx ut qu sj j8 j9 ya nr rz wg wh eg x8 sl t7 yu vf ay ds ap re dh qg qh qj hz qk zz qx k3 cy iq ox qv eu nx n6 6r lq n0 y0 uq tb sy iw fm an
+\n yv dc qs gm q2 cv ok wt b2 cj wu mr zj kn e5 iu pz r8 pe fp ot tq a9 y5 sz ez cl wq qq wv a7 ln ky jd qe qr yx rm qi ea ln te y9 ev en eh iv tx e3 as tn j8 wf xh co fl nc wk xz es rx ee wh ub aq u1 ar e7 up it iu o2 wl ko jo cu pc wo al hm uq rn ul yz ro
+\n pw na wu jd yf oe qr xr sk wa hw ql wg x6 s9 u7 am
+\n uv tr ub k7 qg he u6 jt gs z3 by tn bi av z7 jc ck q7 2n ny cx km mk rf pj xi lh sf up yj to ia ab tq fq pm fd qc qv ps su qw fu xu cm zb bc qr qt tn ei rw gl p1 xi qo tt ed ef ri iz yw oh tc uy tv as qu l4 qr t4 wx e5 ae op oa em tz gd dq rw ug dr ux qj be ko cg nl je aj xw q1 vv ax rl w2 yt aa u0 eu ah
+\n dc ph sq jt ql un q5 cg lk w9 ur uy pz uo sx qv qq cc ln fu ym ho su pn qa bq pd wj wj yk ou wl rk o2 pt uc km ja wm ry rm ob
+\n gb pw qf we q3 ls q4 sy bl lg q8 t3 wl rg ed io ef if oi hp lo kw wy qw ei yz rt es p6 fp hi qo bn qw wg cy np uv yy oa uo ir of em ug x9 qh nj n8 ea u8 er w6
+\n ij dg cd lw gk wu zl dd eb eq sg ia am in wq xt nk wr xj qq p5 pd pk as sd fn lj jw fk l9 nt wl oo fj sb u4 gs fx hg o1 dr fb hj h8 xc yq ch er e2 aa af ah ob
+\n a2 o0 hn pd iz hw jg q1 jl qz ip le me wi bb r3 z7 g1 eh td sw g9 qq c9 vy ud qo es ec tj uw dq ur hj dy oe zp lk l5 fl wj ys t2 ej t4 ek rs sl yu oa u3 gd pm rw h1 pr h2 py wl 2p s7 wq 6r mi 10 ox o6
+\n i3 qw ee ur cy nx r2 wj t2 ub ir aj cl qm u0 oz
+\n qd qn un qz xy nq an kg hc c6 w8 93 eq ts g9 wy mg w3 rb 3f wf rw kt op es ef at em s6 pc wg bw x1 xl wg hl yk yo eb ud hm hl py wb u4 zp bj bm se sr sy ox am
+\n rc ix qs ls qy at ut pk yo ys ec hs lq xv ks
+\n yb al zf ws cn ac ih th ww vb kt b3 xo qe qi te ea p8 tn qd ci ix xk pk bg rc tl f4 wb rb ru
+\n iy qd a5 jq jw qh sw fv oz cj hc qq ya ee yn pr av or us iv fa qb q9 bh ns d0 qe i1 b0 fh qy qu qi ry os ul hq ri ix e1 ao p0 qt sf qi uh ll ko lx nz sg jz hq sh p8 x3 wg rd sx yo yp u3 pv rq ds tc rr wx lr xb wn ep hh bk yw q6 og yr yg si tq do if
+\n hv qa qf jg he q1 kj qz bh lr kn rj th kz ef eh av pp i1 ar gl ur lr bz xp yr ze qt tn es fl hw s5 qa ed t4 wz sx rg sv e9 fz hf al h1 av bg ym ee yg
+\n k8 nn jy q4 wd lf xu q9 a1 4v yd mb r6 yh pb ta g6 dn d3 pl j1 jk wc cn wy 26 rr te ti fa e4 uy fb gr hb kd lc qf p5 wh au fa iv xo hf ot eg ra wv tp ec yo ah iu pw hj ac h3 py k2 u1 wb rl rz yt er w6 ru af yo ep
+\n qd uq qh qm q3 vg qc c5 rd vp ut eq on yn ii xp up r8 d0 sz qx ue pl lx qe wr qr lm nh qt ha qo ki ri e2 tx iv ao s3 ow kp xf rh ya r2 rk cw nt by wd j8 t1 hk y1 ns t6 wc ev sq rq yf ux aw ch qs u2 zn sm rt wb bk yq dh 8w w3 rc yg o3 yi ox ov ir
+\n u0 q7 qb ml or nu b5 1l xb tr tp in qt hz so v6 dq o2 qh wl nb rv fw
+\n ss jr zf zh xt oy hy aw y8 js ob wq ny or vy fi en tb qi j9 gt ib ot oy rd e5 y6 tg th pt gq wz rt rl ew fm ie ri ir ro ah
+\n o0 qj h9 wy ee g9 gk jd fg qt 3d fu ru iz tl fd tv ad hl wp oo wf nb ez sv tl f4 dr oy rp
+\n ak il k6 qh q2 vd k3 zd bo lj k7 km 5c ut rz yd up ua is r0 qn zq wq j1 qe cv pw fu md bw yw qq ra rw qu ex ik at y0 ru ti yw fz ic ao ow gm jc i7 nf p4 fj xg kr br xk bs mb pk hl wl ta ez sv e9 us om rw ap gq wl k2 qz h8 gu kf et ru tq ag uz rp
+\n yb az dd fu rf hw qg we u9 o3 q5 q6 ag c2 o7 wa kh w8 vo mc yg tu ua uh ta tw ih hu fj su bg ww bh kw ry ru wy ky wu wi fw 20 b9 qo ik oa ev hw s1 e1 e3 fc uu s5 tn qy hz jc do ou jq gb kf pf xl x3 yv lz iq eb e8 os sn fx dw qg ql wc ka n8 gf ly se tv yk di si o7 r2 rp
+\n il mj vi sd ia y6 wq rm p5 ux ho nr ef ej wq iq fn
+\n ft cs uo io er ic tw ig mm c9 xk ab ze uw i5 s1 e4 pl ui f2 lj p4 sf x4 kz ej ez eb ov of rw dy av qh f0 h5 ki qx cx eb og gk oz uc
+\n ul io zd kn w9 y3 wt qq wp jl i9 jk ca h5 wx wb tm do
+\n iy hv cs a2 ee yz y6 gk kq em qy uq ts w0 rq rr vt pb nc q5
+\n qn q3 vt vu yk ej fp tw zm qq qy y9 hh wo wg rh ep x5 wk mr el l9 av hz w5
+\n hq qz wy cx rh ur w9 e8 r4 fq im fj gj dm qn gl jn iz l1 yh mz rw e2 qo wh nt wk zw t7 e5 iq fh eb sn ud az uv fh sv dq q1 ku zs eb ue xq rn o6 do
+\n ub lo sq wr d1 mt o7 ts t5 rd xe iu yg ot gg se pp qc js lu xt j3 j4 wt pc vz 5o yr qw zw qr eu db sy eb em fo i0 ad gw m9 ig ih lc od n4 pg rx bi ni kq wl aw e7 az jo mk bo wb ei mi ep wb eq di do
+\n q1 ub xt db wt ws ik pl ee or to ej ic is fr jk ls c9 qq yg qt eo rw tp p8 dy pz gm hz or xs bt x8 t4 t8 s7 oj lt wv vx u7 w4 et ox yo
+\n po o9 ih dx qa rf qf pd d2 kl ad lh kb bd qm bb b1 z8 ew d6 yg d7 ym ti eh ic iv oi y6 sz dx qn ut qm gz pj zw jj 4d bk wb lm xb ke yx oo qp yb yn en fo yw fp e4 aa fd jz qu gw qa zs nl v9 wf qt qi vg ni wx hk 9f sz tg t0 ga de re io av h2 jt x0 h4 wx wc fg rb rn nc yz iy zp ds ep zw pr xv rz yh yk zp do hc ep
+\n hb ty z2 qz qz zh gw mg kb ve zz ti tp py el jp tg qc ar qv gx la qr cn lr nd ng ve qt 6g ml op pd uq uw eh i8 uy dt ho j8 wp wd qe xm w0 x4 qk el e9 pb sm pn tc gt ce oj jr mi ds wb ym ew u8
+\n ij yb hn u7 cd gj co dp lp b2 r5 ed ti pn qx g0 jb jn jj we bl ri ot pi rb yc sv ty oh ph hh e4 hy sd wp ll ft l7 wh ca ys wf wb t7 sv uo sb sn ha pb sw de un qc bz wo en as tb eu af eo
+\n d2 k0 wr q4 q5 c2 sj iv pm g8 m1 l1 5s ij aa lb xm vf ej ta ar th od sm cw gy bu qd q1 u8 ry rn
+\n qa ux q3 mj ex yu zx rk gi rl ya is py am tw ja js db ps dn qb qn gn lc pe qq vr qr eo qi ec oa ev uz yq of in ho qo jj jk wk wd zp wf lz t8 tk ha pv fz pn ug o2 pe uk kv gq v7 oi qv wv dj tv fn fw
+\n dx a3 k5 um uq jd og nn q5 qx cu wp rd ws d6 px ac oe rb up tp ej ek ih ff qc gj qm xk b4 dz jg sq jh eu yx eo re es ul yw tp i6 pj ho qi qf sn og xo yv pk wj wb go ar uo eb ir iy pq uh qg h6 vt wv sn n0 rx af uz hx eo
+\n yv ub ty gn gu fu dm ca q2 d4 cn ad iw k6 bf zl zz 2o w7 uo ee yk ix g3 am fw oi jo se ha vs qn iy qq 24 bl j6 g4 cw jv 1l ei qy ke j4 qi ep of ao hh tb gm sh lh vc uf vu wd p6 xm qt kh rk l9 s4 wh mr t4 oi rf iq op ox u4 e9 fk u5 it re uk f0 kb nd qk ce jp lr cy js qd qb sb tq n7 n8 ed ue tn ox o6 id r2 it
+\n qa pa jd qn qg jt gh q5 lg ag qv ah qn vr da rh w7 b2 rz rx d6 d7 eg eh yl a9 ek dl tw sc hp ha su gz lo qe le ns kt qy qi 1h kp mz qu es yb yn p6 eh fs ok as im dy px gq qp qs l6 iv rl zw dr 4r hi wj rp t6 go s8 e8 at e9 f3 ak dg f9 qh pt dz ww rv wb oc pv be wq cs q1 xr xx eq yr u9 sr tb yl tq if hc ig
+\n a5 co dh bt lw ck lh w7 3e mp r3 rz yf yh uh eh td y8 fg pa ar va dm su q9 d5 qw re vh he jc 1g ib xz qq qw yg vt rn rb cb ry ym em i7 hr ff f2 qp rd lx wg lb kh va jv qi xd wh wc el un sz tf gu oz ae e9 e0 iu dr io dt fb dh jo um wx s5 oa kx ly rn oc zy f3 hb tt wb u9 oz hx if ig
+\n ak o0 qd q7 eq g1 y2 pt dk g8 qb vs qe dh 5i pt yh qo ul tp oj sp oq di uh zg xn rx tp tf ie f6 cg rv zm xw zq 5f md sr yk ru ro
+\n a2 tt ub rs ij ml ow pe el gd va ue zm sa pq lc yw qi qw lv ep qo uj ym tl ye hj s6 uf qp 82 fk y1 wl oi t8 fk pb tx o1 sk lm oo xv n2 ad fk n6 dp on q6 rv
+\n qf jf kk nm oz q7 b2 xo fw kj rh ua oe yl gh vd qe gn wb pt wi z0 se gj 48 of i5 oh so hz wp ae wg nc kg xf ev pv ov au iy az f7 qb q5 eq yr tv yy ol ry o4 oc di ep
+\n po o9 dc a5 jd z1 sq ws b7 ti r9 sl ez aw tg zm si ng qe ky b5 pp eb od jl ff oe ce qp gy yv qk r4 xf kw iw sn tx gg uh cq ql qa 2s mt eq rb dp
+\n qs qz cd dl se q0 lv eu yi rw qo uh uj ul en tx wo qd e6 pv gg je zx kp qc q3 ye en
+\n un qs qh se ws lf so eq yf ef y3 g4 zb hs q0 no qw j2 y0 uu fb di f1 kq oa ul t3 ot fh ak yf fv dt f8 jo sx wx at wn cs lq zc
+\n ub qa qs ik pw uq a6 pd dm d1 qm d2 qk cv zd bi wd ne ah qb kg kh ij 1p rk w9 wt r5 d5 px uf eh yk oy pm i2 hp st qn si qm zw we ls px lr ri qr sr db hp qu xk fy os eg en uc ur i7 sa hp vn qs kw dn od rh xj w9 wk ph ap yh el oi oo e7 gp ay s0 f4 gf az jy qk ql qx 1k v9 qc jq zy n5 kg hd ww wv bj hj ur er rn ry eo o7
+\n df a6 dn je ql no q6 ox wo zl bn rh ya mv e0 yn pr gd pi y8 i4 c7 g1 j6 wo rv eu xg eo c0 yx ea sv os wp qw wl ou un t6 u2 os of f6 dt f0 jt wc ja ae qv rm ds pq y7 qk ck aa ux
+\n db iz jk zd wy wh c3 zk 2o rj hw vp on ed ac to g2 r0 id ta th qb dm pj m8 np oe pu bb tc gh ml rq uf tu eh ye tx gv pk jv j8 lk xs kd fi mx be wd t3 mr wk wl td eb ie tz dw rw pm re fb dj h6 ql wz wx qx qv u3 vz xe ex 2w ty ew xm oz an
+\n ty a6 we wi ro lj bn rh r5 g4 aw jd q0 gz xy m6 wu qq et oo ex qp tr y0 fi au e3 oj gm px lg wk tu ek tg u2 ov em dg uk nd qj cy hp wq mi bj q4 ia fm r1 ei ie ux
+\n tr qg h7 qk jl kc jr am mo w8 e8 td gl kw sd jo qr vl gs qe b9 mm fh eo uh ft ik e2 i0 uu ff qu f2 jq v2 wg kg ek aq wm yi yo s8 e8 sq ab cw wt ck pb pn xl bj yq wm ew xq su r2
+\n qk wa q6 jj ws ut gd gf ly ec pj sa pd wl e5 wc da kx zk zz zb wv rm te
+\n jq uz nv ql as jx z8 q7 o7 yt rl ea e0 ym y2 pr ia sz sq sr qq qr vk oe pe lr bl ll rm yx y0 eg ti e1 ue uu ui jx zd oq kd rg lv lb r1 fx ro me ts ay f6 fc io qg py qj qk qs ky qh y9 ok o4 am
+\n qh dl jt wy a2 yk y2 i4 zq kq we bb dg m6 qq zw rt ta tc ff xs xd qf g0 1d yg du wz iy sw tc dd hj hk mh ov zi wn hk ee yj af
+\n ra ak uw q3 cb ji wy fw gw t4 mu ts qw ww rj vo rl yd ug d9 gj i3 zw qw wy md qq bv rn qy pd tl ic p9 hr dr hh ui sf f1 i6 ws cy es ef t5 kr ek oo t7 ec e8 u4 od dq ji ch jr zm jy q1 zp yq 2e og yo tm
+\n tr tt qa qd jf pg qh jr sw ao q3 qz za wt js bl vw q9 ws uu w0 ya pl yf rx ee tu r7 gg dv it lo ww up js qq qe lz eu qy rr yb ri ay ye ta tv im sh ss uk qd qf bw ro sl wl t5 e5 um th ha fx re ii fv je hk ot cq km h8 ks bk vl qn xe te tt rl u7 iq ry ag dp o8
+\n sa z1 qj q2 nn wr z5 mq xu q7 gv t6 w7 r4 c1 mb sd ed ym ot ta ht ts tw gd tf g8 se ar gh fh qv qn zm hs qw qe oq wc xj vz xl wo rn i2 sr rq at yq uw s1 tx hy fm pc wo hv gy vu wd lc ul p8 wk wk el oz oa rh gp pn gf fx fc f7 rr dy x9 uk f0 py wl v7 cr ch qs wv nz lv lu 5o xe ym ly er yi ia gl ox r1 dp
+\n uv qd hm qf gp k9 kj we lf bs ej 2i el wl t7 rj w0 rz yf ys r8 tp py tq tw dl im qc db qq sd ry c9 oe if qw aw qu uh tt p5 p7 p8 oj zi oe qu qi lk j9 sk zs ka lc wh wk zq mq vh t2 ej r9 mr ez t6 e5 op rk ga pb dq ap f9 py qk qz wc kd pv bd sm dr u7 mf o3 yk di r2
+\n po a3 uw q5 q7 ck kb zj td zz yf jd wq xh ld qr w4 p1 ij fu tp qq sv y2 yt t6 e5 op dw iu pw jp ka qv 4u qf rm vb w6
+\n fy a6 qg cs z3 ql dc jz wy me cj o6 ba kv wp w8 ea r5 uo fw ib ig g7 gg sy bg qr cb cq ro xl xv ex tt ru pd hg im oq gq ao rl pl aq sz t7 e6 os uf ug gg pr ql qz vt mj px wb ci qf ov be bg ww mp mi rz u7 w3 ei yc
+\n gh cm ca rg uy pm y7 g8 lx yc qi re uh yn uq eh tz ph wo cr sv fp kh sl oi sx ov ga iu h1 je fd rv qv wi jy yy ry o4 tq si
+\n qd iz qh q3 cg lf wy xa ez eq om ug eg yj fo fp yz qx qe wb or jg xb c9 p4 tj y0 iz tc oj tb i6 p1 ka zf qe yp wj mv ra ez rd uh pt zl lm sz wc lr bq oc zq sr af gl ei ux it
+\n a2 qa h9 qh q3 fn kx ve wz us sj yz fd g7 vh c9 xq xj ln tz wp wf kg kk by vf j9 5y un yi e6 rh sn tx hj kn rb
+\n un qs fi qm jk js bd o8 bx vt eq ya xp yg pz ym dj fp tp ta oy dl qc cx qq m1 rt wn d0 wm yr qw aq qt tb ha p1 uk yn ef tj gv im sd hk pz jx zi wa wf ba l0 wd mq ej wv t5 ek iq pv ov f3 em ak rq hn hh f7 uk qh ot ju ng ji h7 wz cr v9 bj bk rc er ia is iw ei id ov pu hc aj
+\n pw gm qd jf u6 z3 jl q4 wt bi lr id wa wz w8 ya ev ew r6 yn ee io r8 ip ej td im si j2 jo d7 m4 pv iv yg qi il ti i6 ta ib ap fb hz wd vu wf wh kt kh og kk nm rp ti ek ns t7 y5 wc ae ir pv hf ub wc ho wb wn mi rn w6 yk tm te rp
+\n o9 un h0 a6 pf iq xi tg w8 z7 r5 om oq eg or y4 sr fh zv vw zq tc ws rq db rw eo ym tl fv i9 pz jx j7 hx oi qf x2 l9 x3 qj by to el sx ys yd ao az uj hl dl tj nz wn kg kh on wv w1 w5 gl ei
+\n gv az ql nm rc r7 yl ja zn q9 xw no iz qt pk x4 l4 tg u3 of zk wc go qb mo eq u7 tv rm ig fe
+\n o0 ik qd um qg k9 mb bu wy bx ny ws hm ea mb iu pe eg ey sh uh g2 ic iv aq td qx ja qb ha 2j lp xr wc vl wn wi sl tx qt rq ec vw of uw sm ic qy j7 ns hb 2q kw wf vp 1f x1 5c zs y1 rg tg oz e7 fh eb ie up e0 ap ve wq zz cr wz h8 wv go ly fk az pr rz h4 ew w2 ok w5 ia si ro am
+\n dv d2 cd qc zt 25 xp wd te es sh eo wn f4 wo tv oc
+\n uv qd qn hr bj b1 mw lg io sh lo qq xh m6 28 rn xx p7 im qt jn jw bm qf r1 mn ny ed em ii dd wn cz ds vc wb hh q4 yw ur rt ie o6 ux r2
+\n rs dh z1 jr cb vq r3 eq om y1 sg r9 if tw qb qn m2 vy dc b0 ik fa ib aa jz qu sg qs 1s be of w9 oz sv t9 oc pv rw dd o2 dh lq ka lu 1m qk q4 y0 ye yq w2 w6 si ob it
+\n o9 db iz fi qn qj mw 3v wp li e3 km zz yy mo ya rz mv yg r7 yh pc or r9 pm a0 td ih db lt pg jf gl re ww qw m4 j5 xi wi yd nh yg qr rm et ey ug re rr y9 y0 sb tu od ay of iv oh i8 ok uu sf gq lg wa nn uj qs cu kd xb wg cs 3k yv hk pn ii hh cw km wz wx wc n3 jr wm qn bd zo mo jo wm q6 w3 rt an hx ah am uc dp
+\n ps pt vq kc bs vu vo xu ee ib hv wj x3 nu ud yf qh wb lb gz
+\n ra o9 qs ty rd ps db pu qj u6 k9 nb qk oj ql wt jx bo ri xo o0 mk rh bm mj ut mb rc yn et yl pm ih i1 g9 qm xq oq bj wt jp xu pt bc eo ep qi ky sv uk fy ri i5 im dy hk ui tm f2 uf ug qd kf nc s3 fs 12 t2 ro du wk ek yt ej t7 s7 oc ay s9 pv fl s0 gf tx fc ac py v5 qk ce qz cr jp ck hp u3 zm xr ii yv ea cf hj ye w3 tp do tw ux
+\n o9 qa ik wt kc q8 wk sp yy w8 w0 ys ea om tu yz pn fe ae g9 ps g0 i4 qb fk qn qm ut j1 d6 4d cb vj vk xy j5 be wi ve qq gf qr j3 ug qo p4 sm s2 ut fd pl qt jz ui qy qu qa nk fj iz xh wk iv qz fb ro x6 ti sl rs hc oi wm us ai dw o1 hh ab qh qj ju ng wl zr vk tw 5a vc hk md yr u7 w2 yt tn eu ul ah
+\n uv ra qs ty jh q4 o4 bc vr o9 rg jz mc r4 ui g1 ey g3 sj am sq fj qn it xt ln dl jh b9 g8 dv qt yz ea ue ss w9 wj kk bi ym tg t0 ob ys iu uj qk nf v6 nj ox qb wy mw 1n pq eq w1 rx rp ge
+\n a2 pa e4 xy yd sj vs jj xj lm qy qp ri ux p8 pj tv xs wd wf oz gd sw rw uj uk qj k1 xx um eu bx my em ey
+\n az h0 qz iq bl kb xp yf y8 qn rv hx oc re gt k2 bo qg cf rl
+\n yv uj d2 mq hx ws w7 mv yn r8 ab an ae jn xw al up be qr zr ep re qo ec ur ap hp pn wp i9 rf wf vo qk t8 eb yd uk kv ww wx wt ox kh mi eq yj oz fn ie am rp
+\n ik df qg jg k9 wy kc ro wi ve bb rl ew io or eh sq oi qc qe d7 m4 pu gd db oo yv yq ix eh fl pg ib hu pl cr fr xd cy ke mx yh wk ag hf hk qg sj we mz gp u4 ak ma rz rv af ox di yx ob
+\n hn pa pw qd il qh q1 z3 wr t3 wo ws vu uu ld pe fo dj ot dx pp vl qq rr ls j4 fs dl ve c6 rq ln xk ec rt ty ik y0 tu yq fz s5 sd sh jn wa uj ws lx qr ca rz wd nu ek yy yi y6 uo os up f4 fz qk h8 qc wr at 18 ca ww rv sy ox o6
+\n dv wu wo uo m2 we rp b6 qe ik e1 bq w8 x5 ez fh u4 iy jy wu li f5 u8 w3 yl te
+\n sa ds qd no q5 ra jd qo ru r7 uo ar ud on ak fv dg wl qx qv ye yl ep ge
+\n ss rf qn bu gj rj uo yz tf m1 kw zr oo y0 pf tc dy qu v6 xh t4 oo um df je qh dz v8 ho wn wo 0w dj rv o3 du ro
+\n ij uj k7 me lg ih hv ws rj pl sd uo y1 yk d0 pt y4 g4 ou tw sq td fj ha qm qq 4a kw d7 xy m5 bx c9 yx nw tr qo uj fu en p6 s1 ht tb qo zp kq x2 wk wj wk yt wz sz ae iw ay fk ao ug pq qg k1 ql xx qc cl qk 56 bn oj yt et ut uy tw ir yc
+\n k5 pg cp z5 wr no zd tk ej an qx gj i3 su we up 3q yq fx ib tv qp ik wj yf u1 os rk jt qo qx n9 w1 rb
+\n k9 uv gs wr 3b mh km bm we w9 es or yk r0 g5 aq gf nq qv ll m5 yd zq qt qp sv ed p5 of eh i7 pz hl sg jn wa m0 nm kf w8 wj de e7 ar iy pn ly wn fx w3 rb ey am
+\n o9 d2 vg gk ex rf rc hy qm j4 ga qw rm ls yl cm en tl tp fp tb i3 qy qo j9 vn zf wf qg mb kj qi jb mq wl rj s8 lw um zt wb f4 xw f9
+\n ra go ls qx wi c6 b0 rw g1 yz fe g8 ow qq ra mz ex oa fu iz tl uc e1 p6 x1 tf rh tk fz ap hl qh k3 xb mw zm yb yw q5 aa rp
+\n yu qx sc xe j2 oq gs i6 i9 l0
+\n yv ss tt gu fi qj bt ql ls io nw gk hl up zv gl ni xt wy dz qe ud nw rw qu uw e4 qy px qf zw za ty ek t7 pv dg ho wn uq rx yx ep
+\n ga 1w ld wy o7 xr pk r9 g6 hu jg lx sd no xt wr zy ku l2 nw 9r rt i5 to tp tc s6 f1 ud ko xb rj qy es t0 f4 fx ii rr hm hj fb ji oi n1 vk ci 9e mt yc 2r tv gk yp ux
+\n hb hn k0 wy m4 w7 rc ts y6 j3 qe ve qy rt so di qo dp lk xf mq wl em f5 pr wl wn 3k ew yt w4 ri
+\n qa ss lq wr bx t3 r5 ed eg sx dn we 7n ra qe b9 rm wd rw eo oa ri e1 e2 ut ap hu qo ws uz ai tz nl cu wq ln wn ie aj
+\n yb rs un hm dg qm qk ao mw fn kv ur uo pj e9 sf ia tp tw a0 td sx fg su xq m1 om na vk wy xk em l1 z0 nh b0 mz qy p2 ru au iv p9 pz ug lz xn wf xg fk zu wj wd u1 e9 tl ak hf sw o1 pw dt gq v5 lm h7 nn nl wq uq zt o3 ad ry id ig
+\n a3 pp dv qs gn u6 jy kk io dt wt ck rg ua yd ya yh ax ac y1 pe pc pv fp fw dc qv zb dn q0 ju jj m1 ui lx qe qr t9 ja he wi vw m7 l1 jn qe wa qt xg rq qy yi qu p3 yb ed en tz so s3 tb ho fm px gw zo lx wf sm mc dq wj yg l4 uv yk tp t5 wz ol fk f4 pe kc dj wz qb zm wi br zk ww ty 6i vm eb lt eq w2 ey yp yz o6 ei
+\n fu ga io nt wp jz yf rv oe eh pt dz ih sx qx g0 qm hf xe lz gc d5 bh 2z cn d9 1r sz li bv qe 6d bb er xv yx p2 ea tj p5 ay uq dq pg oh qt s6 px sh ko qa nn oa bq cs kk hh cr wg tu y4 t6 e5 oz th sn ov u5 dw qg dh uk n1 zr qv 3d n4 yx xe wv eb h4 yo ro hx o8 rp
+\n ra gu hm a7 jw qm qh jr gs k0 ql xt q5 dt ru wy k5 wh fw lu kb am m6 bx vy qq ev rk 2s mc yd es io pc pv g2 ek tq tw in ih ae qc d5 ui qe wt qq m8 vr nb ee hu rw rr tt ed fi em e1 e3 hh hi sh zp qo wp l4 ws qf qf pg eg to un gu u1 t9 ox e7 u4 od ds de hh py ql h7 gy js vz gf y8 uq se do ro rp
+\n qs qg gk ta bf r3 hw r7 r9 sh ua g3 sq td g7 ha lu qw xr wy wu rz ko bb i6 uy as di qi za hv jw rf 1f 2u va ap qi rc du wk yt t7 u2 ob re ax v8 cg qb wy wn kg pn yi rn ru
+\n gr ra jq qf go ga jh gs q3 tm q8 k7 o8 mj ym er ip ua ej hy i1 dv qb vg cv m5 wy xk g5 wi ng w3 3w ud rw ug ep hq ta fc fd aa i5 hx qp wp v7 qs l6 l9 l0 jn ty t6 ie rj tk od ys on pq tc zl nh qc xv wc cu ks ei lm vm cj yi ad r1 si sp
+\n qa hm a3 ac q9 na rj if qw rr vw tj ib su qu wo dp j0 wf pf 2y wk ym ra wb ae ga gs f8 gq im ar pb ec f9 yu rm
+\n t8 ej an y4 td ez ln z9 lj qy sm uw dq us cp nu tg vn
+\n qa ds k5 hw k8 k0 ql hl 1r wi fw c6 w7 mz rj xy r4 e0 ym yh eg r0 us fs ib oi qv q0 ww lp gm ln bx nc qi l1 qe wg ea qo eb tk eg to ur jc oe dp hv wa 2q nk at rg wf wg ca xk jn pk yg er ot uv wb aq ol wx e6 ev sv uo vf eb ah ud da pe qg jr kn ju ng ae wv n3 iw ly kf cl pb wv tt vn eb vm u7 ew aa w6 rm gx r2 o8
+\n q4 q6 vk d6 eg pc pv r0 tw i3 q0 we tw sm e4 ow sn kg up hm qx zv nz wm u9 ul ri do
+\n po uv dc qs qd hm qg q2 jj sw kl me q8 xa wa xf z5 yd r4 rq sf px ti ia r9 yl dj dk ek qx i2 sr qv qb lb wi nf wu qe tv fh qo rr yb fy eb ri ai ok qt pc ud qi qa ws qs lc zh nc x2 cs t2 di ke wk sz oc yp s9 ys ai ln wz cg wc wv os qb f2 ec y8 dg wm rz yr ee rn sy du su eu fm ei o6 dp hc
+\n ft qj q6 wq up ut lg er uw db ll ws of og e4 1i r0 wx fh th vf re hm zi
+\n a3 ty pw ph cg uo r7 oi q0 lb c0 vl xx mh hu b9 qy tt sv p5 eh to hh ow tm oe si sk oi gt kq cu vi j5 wf el tf yu u3 ya uj dy qh ql ct wc el y0 o3 o6 if ge
+\n a3 dd by wt lf 2v bl 7c bn cf yo go yf ii et ey yl aq aw g8 ho i3 qb dn qn lu vf vg 2k le ml wy t0 4h xk qw b7 bb eu xr qu tt y0 os sn tl pf og tz tx pl ss us xd cu oa qd xn ke qf vp kh ny wk r8 ej rd t7 sc e6 rh ud tx al gg re hj ux qj gw xx zv xm iy ca vb yw en oh u9 aa w5 w6 ul oc an uc
+\n qa un dn hq hw d1 jr jy kk kl wt kz zf z7 cm q7 me xp wp mj rh ue e7 ys rz eq ew ed xp ee yj y1 to fw aq po i2 jn li on m2 na vq wu ck er yu db yi gl ty eh uw fp tx e2 fs uu sf jx oe jb qp cy bn qd wg 3z nu j9 mr t6 gp pv ha tl ai fx uf fc kx qh gw xb zt qv qb ir cq vb y9 ct ol fn ah hx sp
+\n db wt cm ch jc wi dd ys on td po y8 q0 wq kt eu tc tv or fr s3 na e7 uf gg re f5 tt aa tb ie
+\n a5 jw qh q1 qj oj xy my b6 es yg yl y5 zm pv qw qt qo ea ri ao in s4 gv i0 ad lh wa qf gm rk vs oy r0 ez ab lm qs qh ry ox
+\n ga ca z6 nr wo rg bm vu uu rj e0 ui io pe eh d9 ab tw fe tf fk wy ln md rk sk qq qw hy kp dc qy y0 p5 p6 p7 ic pg e4 jb ge wp qa bn xf ks zi oy e5 um wx ie yp fv je ng oj ja v9 bp qv er an pu
+\n a4 jw a8 o1 q3 un gh le nq q8 ig rg rl ea io er tu fp dk hy sq ae lo qq wt wy 5i xj cw dz oo qo yn ty y9 y0 sb ef tj uw ta ur i8 tb oq af hz qi wo sk zs qs vi wf kt nb y1 oy wk r0 ol ex ec tg t9 eb ap fv qk ji cr s6 et xq bf ep mi ax rt yu iq af am yc
+\n gr uv hv tr a3 qs lo u7 jy qz kl z6 gk gz ag kn rg k0 w7 wr rl pj ii yh up ac ot d0 g6 td y6 fr se pp dc g9 cl gx qw pl m1 ii qr vz oy nf eu eo p1 os y0 ri ix au uc ai fx p9 nm jj lz pa kw ul rg gw qh 4m eo qc l5 rp oy ej un yy yu t8 sv ud fx ac dy av gq qj ve sl bu th u3 rn nz n5 zm yz bd tx el ex n9 es rt rz rx ol sy rn yo
+\n ph cb jx wu ib vb ih ty oy tl vu
+\n df qd k7 z2 q2 ju jz zf cm mw yr gu rx yh ym ef pc qx jd q0 ow pw wt rj xo mf xl qq qw ud tw ku ik oa od ti hk f1 xs qd wf dm s2 ph xo ou sx ae iw t9 eb u3 rk ak hf dw ax oe zl zz wm sm el cx cw lq za tu yw rx yu rn fn yi ei
+\n a6 ql wr jx z7 wu xi ym fo if a0 dv ww lx zv dk tu sn hh ff hu zo ws rf wf aa ni kq uv t7 um go e8 ob sm tz hl uc zz ol lr kc n6 bk ry if
+\n qs gm tn rp iu pi qe ec to l1 wh ra wl it kx fd vx q1 ri
+\n gu pw qg we d4 ws q4 cn q5 me qv zj zl ex wr xo yg r7 eg et ey us iv po aw se cx az lb nz nc qq ew rs rq yx ep tj uq eh fz hg gv jc di wp sa nc ya cs fv qz ti wn aw e7 ox u6 pn re o2 hm fv qg hl dl v9 qv tz 6y rl ye rx ur tn eo
+\n gr qj z6 ld tm jw hc ed y5 se ke ht tn jb 12 yt ek ao io wv ew ey fm tw ir
+\n gv fr ak o0 gb rd dv gu qf qg qh jg ux qj ph k0 oj wa jz bi ja eg c1 fe qn b5 rs rg b1 vo z7 us d5 r5 ii tu yh y1 or ek sl pm hy dc th sy ww ze vb wt m6 iv mj qe 6f qt gk tq ru yq au ap dr hh qy sf qa ik kt wd rz ej t3 ot ej ub wx oz th s7 t0 ag ga pv em fz sw o1 ip qh nd h5 et ho cu yz tq wq wn et tn yo si ov a1
+\n ij rs rd qd pd qg qh z4 ql ip nq q5 xu bz lh o7 my 3w xe ws 2p w9 rk es er d8 pu y6 qc gl bv qa rv qt rb os ru fn qy qu hx or wa qs at zg mx xo bg yh ec os eb hd rw dw ip vw ki ok qx cu wb sn wm yj o3 tm ei ah
+\n tr rd pq qd um qj u7 q3 cf db k4 gl mr gw c3 bs k8 vi 4v kz cg rz et ey tp fq y5 el gd dx qx hp mn cz wq xh m4 av t0 vz m6 qw tv rq ei il sb tk eg uq tc wo qo zs rd nx 2y fo j5 l0 l1 hy vy t3 t4 yt va y5 rg e7 uo ox at ir ys hd uf fx re rr ac kc cq qk cw h6 kp xn zu bd cz ca pn pq w1 rx vc w6 yo is fw ir ov
+\n ra ij a3 qs qn jf qm nv cs cv kz q5 um q7 q8 km ya ys rx yn d8 sh pt fe se js ue rk m7 wp et ei qy to tz s4 af 3i lc wk ej hc ex t7 oc sm s0 tl fx re fb jr jp qc kc jr cc w3 yl oc ob ep
+\n sa yb qn k8 lf d1 c3 wp vr wl yd iu kb sz g7 mn jm lz sd m3 lv qq j1 ex qo ry ru em pk i3 hi rf fk nc wd vu yt td sc tg s9 tz tx dh x9 qh ku dz my yr w3 oj se ei gz tq hx ah fe
+\n w9 rl rc or fq a9 pp db gj hs lc qr ec p4 ph hb x1 ez u5 qx ea 6t tn
+\n a3 qa dd qf qn qm qj vj wi ag wo ig e3 wz r6 d7 ax pe rb ey r9 is ot tq oy if hy se qx ar qb vd qw qe np xy nd wi in gj qu y9 ev ti tb qt px ud wo ll cy wd hw kh fp wk wg wh ym vo ub rd t7 iq yo ox eb yp ys au u6 rq ii io pe qh nz vl be n8 wv hk og rc er yu u0 rn yl is do eo
+\n dd nn oc el yu tl rc rv r7 y2 hi qc qm wu cq qw xc kp tr fu ib zi qu wp vi ci qj nu zw t1 wl fh ev os f4 f6 f7 cd zc qx zy wu bs qn u0
+\n o9 gr fu a7 qk xu q7 wp el yu fp ou y5 pm pp qm jm st op uc fx tn hl zs kp bq p7 hi ys qj ki qc qa n6 oj ey w6 yk si
+\n q7 xo sr he uu sd s6 gy ws iz fk sw al v6 lq fh ie oh uz pu
+\n of ch zj rk rx rc g8 i1 jk tv ul fi e1 ic sp in jl jv j7 nm rp r8 go hf wx tb oz tw it
+\n se kc tj rx yh eh td pa zb qv c8 j5 ri eq b9 rm ik ev ul ti p6 en ok tn wp jm ws ke br wj rp en gd rq f6 ac ab zc rz ew tb ro
+\n qd wr d6 i3 j1 ww if qt yn fd e4 qf j5 yh t8 u1 ev qc wv pw u7 oj ok yz tw o8
+\n un pa jd qh qm dz pi z3 ny gs k0 wt xy z6 cj k5 gl bz d1 fq ye yr rh t7 ot if g6 im pa ps fk zw lx kr lv na wu vw eo cm te qo tr ec ty sb y0 i5 to ye so tc i5 sg ct qs sc ws qr xj 2u n5 rl cw dw ys qj yn qc y1 sl t9 ox sv s8 ya s0 tl ys rw tx fx ds rr cq cd ql qa au qg vg rx yt iq tn yl uz ei si r2 ob
+\n rs gm qk gg m3 rj eq mv yf sk gx ve eh iv i7 n3 pb uf gh uj tg ox ww bg oz su o6
+\n ih a3 uj rd qs df h0 jd d2 kj q2 ap wr ol nw bz q7 fq ir ra w0 eq ya r6 d6 eg ej pn py pp sr qb jb wq ni xe we lm be xo w2 qo mj qr hp tr qo qp ef of yw ai e2 i8 fb tm do dp i8 l4 wd p5 sn pf gr vs rx kz vh t2 wj ot ar t9 at ir dw qj nc cw fd sx qc mz lt pv br wv dr q3 yq vn ye yw dk oh rc w3 yt se ov ge
+\n ds h0 jw he qh jr jt ql me na ah xa tf wt pj pk om 97 rc yg ym oe yj eg dl fe sz g9 lo qq qw wx rr c8 ns vq m7 xl gs vr qw qr kq qi qo eb tk ue dw e2 i8 i9 hy hh qt f1 pc vv qs bn ij i0 uj xh wk qz ns ej un oi yi rh od ha tl re tc o1 uh ac ip qj we qh lq eb w3 w4 ia oz eu ri uz ep
+\n fr ij dl qk z3 qz wt z9 gq mr wo zz rd dd rz ee sw pp g0 sy vg ww iu pz uo cb t9 ld qr ei yx rw es ts zi wp wd gw wj hf r4 tt x8 wl t6 hc gp eb aj ai iu o2 nh qv ey kg dp wq f5 rt cg yw sr tb gj rb fm ro ah ig
+\n ss ux q4 ji xa mj mi ld rl pj r4 rx yg ti ix a9 ig gj j1 ww ii qe j3 mz vl qq ye m8 b8 yl qp ik ki eg uq fi ok fb oq fm sf oe hp v4 nk wg mx kt vs j8 yn wc wj ot td wn iw os u4 tl u5 rq de io x9 dl ql n2 ji wb if hx
+\n iy jk ql q4 wt kz fb q7 vy w8 ur ax uf ym yl py ou dl pm in sq ho j1 qr ls j6 ic sl ko xq jm qe qr qt yc es ry pf he i8 s3 pj tm oe qo lk wp j9 nb yd bu rs e5 yi ar rh ga ud al hh oe wx s6 do kv be pm w5 fn ey du do pu
+\n po rd qs il rf uq of jf nf ih w8 b0 ur pl us ed tz tu ef rb sj tf ff i1 pa dv ue fk m2 qr wt j5 c0 vw xo b7 p7 qt zi wo gt qa oo qd bt nt zq x8 ou e5 u2 fj s0 yd sw re cd qx jp wc ja ga jt bh hm eq rv hx gx
+\n iy ij pa gy qd qg he d2 qk d4 qz q5 nw wu am qm ft w7 rq yn ef oe pv ek fq sk y4 ts am fd qx q9 jf ju wy lm zw wp er sy qu oa ta jl ss gq fe wa p2 kq ws 2w dn xz t2 ej rp rs yy e6 iq ag e0 u5 tx dd pq fv jr qj ku oj ql wz fd s5 nj qx zt 2d qb nx pm ce f9 w3 er tw rp aj it
+\n ss qa gm dm qk c1 jd k0 t8 mk rk tk om yn tz r7 px ac av ot ts if fw ez y6 se qb ha su qn cl wx we qr zt kr mj rc qo es tj ym iz tk i6 fa i7 s3 pl jx du qu j0 ws v2 wj ys yv wd s4 wf nm dt wv ub ez ta wx e0 fz al ap qg wr ar wb fj n4 cz qg wq fc mp yq ev se eu am gx dp te
+\n a2 hv yb nv h7 jt lw xt lu wp yr rg 2o 93 uo pr ej ez jb lz ww az oq bk b5 wi qw rq hs te ea es ed fu ti uz fd tm jc do qi j9 zs j0 wd xv iz hr wx el ns oi t8 sc t9 sb fk hg cd rb mz wn 4i ov ln yr oz tm ro o8
+\n iy pi jt kz st tm rh ya b2 om ef eh tp el in sc qc g0 ps zq nu pq j3 oe a7 ja js ng tc qe pp eo em fc s3 hh i9 jl qy i8 lk wa ae 1p vh ox rk em hf dd jt rn tq is oc o6 so pi
+\n qs gm qn gw qb cx w8 ur yp up uy ek ez ar sy qb hd bx rl qt yi nw tt eb fl eh pg oh ib qy qi bp jz lf eo ph wh oy y5 om az tc ab wv wb kg ww eq ok aa uy w6 ag ig pi
+\n ra a5 db co qn d4 bu qz kx me nr q8 my lp t8 gu rk yn et y1 ej g7 yq d0 j6 b6 qq rn kw ei yc uq e2 s3 oj s6 jl kf rl ny wg mw t2 co el yy ez eb e0 al qg km k3 n2 zr tk qb n5 n7 et tm ul
+\n po uv a2 o0 rd hq dh hw a8 d4 wi z2 vt ww kb d7 pv tq fa ta dl oi y6 im ff ae qv sy si wq pq bn b3 lm b5 wi ku qu ru ul ri tx fb ss or sk wp qd w7 kh nn es hy wh rp um sx e6 rh rk pn sq rr hm dt ip dh pt wl h8 qc vj ly bq zn gd wn q4 hj yq xb mf ok tm ge
+\n ub pa fy qf dh qj q4 wt mw cm k5 gw kb el w7 w8 mx ya ii dj dk gd dc gh st qb iu jk qr bz vz ab b5 mf pu qe xd nq eo yb pd i6 ue dq e1 qo wo sp 1o n1 4v at qf fi of xj rj dq ew nm x5 wh na ub e5 um sb ob em pb re ip x9 h7 zv xm bw 1v mp zr w3 xm ee yg rv rt ia is ro ep
+\n cm bp hc rx y4 sr q9 jj rt qo uk ev to ff so bg eg y4 l0 go os ay tx qh hl qc wb
+\n z3 nn o9 xf fs gd g8 ns ec p0 tb wf uv iw jt wr dq bj u7 e2
+\n da td ta tw tf tt ay dq sf gi ae rl e1 gk af dp
+\n un fi dx wt m5 vo ys j3 i5 ad nr wj mn tg ox bs ia
+\n hv yv qa qf dg qj do ek w0 is sl ez sr i2 ww we rl vr qw y9 tu p5 uc hj i6 ud ws l5 qf xh kh lg wf wj uv tf t7 e7 dt qz ka xn cx xe fn it
+\n iy yv rs qg uw oh q3 lr vq bz ab zm wa ds b1 w9 rl rz uy wy om uo ef fo py tw fe qx i2 qc qb qn ww vg ke wr j5 j6 oy qq ng sl qw mj yh xf yk xg qu te p2 ft y9 uk ym uq so fx ff fn qy du f1 na lh wo qo ge sk v1 wg mc dq wj iv 1h pk 3s ej oy ek td ex ae yi t9 go e8 rk tz ud rq ax hz dk qz kf wm yq cy w4 h6 rt ry tn r1 gz ux pi
+\n d2 we aa cb o3 xi tu ti gd wq pl xg wc lm de e4 sj hc ic wc ra wc go o1 dd ip wl in wx js tv rx yi yc
+\n ty um hq co ux ql q6 wi bc kn q0 r7 yz ib pm g7 po qv re we bh 8j ru xo ra eu ud qy uh ec ty ry yn hw sm e1 pg p0 dr qy oe lc x1 kt xz pl t4 el t5 ex sn us dq rq ao f8 pr md ql v7 v0 n7 kh vn wm u7 cz et w6 gl yo ei di tw
+\n ub jg ph q1 q2 d4 q4 qz kl ld cn ji z9 ro ek gb w7 rh pk ea ax yj pv ot yl an sl y5 po im i1 zb fj qb i4 gl xq si m1 jj lb l2 ul sn ue s1 ta hg zu lh nd j9 ci qu wd bh ef ro ra aq t7 ex t8 od en fz fc df h7 qz n1 v9 zy 4a tc bb ea yw mf ia yp eo aj rp ob
+\n o9 qa h9 dn vo a7 qj jt ji ne kc cj zh wo q0 w7 e5 ui vi ya wy c2 r6 ui px yh y2 to pr ab dj pn a9 pm tw sq ig hi bg ni ry lv wy ic bc li qe im dv rq xy ki i5 fa fv uu af do vv za l3 bi kd nx w8 nt lh hu ra ub un ec rj ua fk ir s0 f4 uf dw jt k2 kz ml cl km wv vv es tb yj w5 rn yo af ru ah ig
+\n vg wr zh wo on ew ef ae ha id uf eg p9 ef gi al ng 16 rz o3
+\n qs jw qh cv z4 ok wt k8 kg km wa uu us sj oy iv tw jm c9 fo nd 20 qw w3 yi re qo yv rr op qp ue oh s3 uu px jc hx wf v2 br ep wg pz t7 t9 au re zj kn xc bo kg 1v hb wv tt u9 gj yu ry iw dp o8
+\n qd wi ij rh ef fe jm kw xj wh uk ef ti e2 j8 ou xo ny wh rp wj ub s7 pb nb qv ev o6 o7 yx
+\n gr dc ft qs gm qd dn k6 lo k9 nb as zg bz lw ui ee g4 dl qv q9 lu jg rx w4 yj ep oo sv uq hq yw ao fc e3 ui dy du sk gc gy qs l7 kz ed ej wl un yu wm oc gq qk qc ks tk ti eq em ly vl er ry sy yo ro eo
+\n lq d7 i4 7w y0 qt gw ch o6 eo
+\n fr hb dc o0 yb hn gi jh sw kj we o1 vg nm q8 bz zk bf ml ev ed r8 iv ht fg th qv vz d3 ng xj 0h 42 ew vt yg qr qt ha qu hs qp ij yn eg of tl p8 fz oh iv jl ss dy zu or sk uj co kt rp wb wx fg ev t9 rj yp u5 us ys ak rw al io kc dt jr hl ln wl wz gy wy qv qb mu hd ky ku zp ww yw rl oh ee w4 yz
+\n fu dg qf pg jg o1 dc by q4 st t3 lj ve jr am 2i rz ea lh pl ed pz y4 g8 i2 db g0 fj q9 qn bl en hr m8 qw rn qt yi ei yk qu xi uh fy yn ix uy gn jx f2 gr fi x2 zo pl vh ek sz u1 s7 ya em u5 da re f7 hl qh ju oz ar zb ci tk ob n7 vh og w1 ok er o5 ri ro tw rp it
+\n gv ra fr ub h0 hm pf qj kk zf zh rj eq d7 oe eh ib oi gg i4 jd ph nu gc qw rr m3 vj ry is dk qi rm qy qu ep p3 ed pd ta s3 tc fd sa im ow jc oe qi j0 gt bm vm zf nj rg w7 x2 nr wf hi rp wk co t6 t7 e6 ag eb u3 e9 f4 om o2 dk h4 gq jo cr oz ka kx rn wn do ep wb vn ef rz ew yi r2 ro so ob
+\n ft a4 qs pq iz pd u5 cs q3 qz ra rh w7 rk mv kv ee y1 to dj sj ta pn oi tf i2 th q0 vx vf ww 2l cb wt yq ku ye gs qe w4 qy qi xi tt es qp ed ef ti i7 tc pl jz ho zo qi za fy zy rk x2 r3 ht yv ex op ae iq u2 ag pb of dd h4 lq wx cy cu zy wm ry ef dj vx st ia ey te
+\n rs al qd uq ga qj sw we pa bi ba e4 yy mo d6 er et ti rb py ek am ib fe y7 fh jv mn qe qr oe c0 l1 qi mh 44 xe ei ev hq ix e1 pg pj ui hp pm fr qs kd nk 1v wj fa wf yt t5 vp ex wx fh pn ug fc pq io gh dg oy nf v6 bt jo qz gu me wm n7 br tx mt q1 su eu di uz am if uc aj
+\n da a6 q1 ph uv oj ji mp t5 mi rj cf jl w0 pk ew ii rv oe r9 ic id sl se su q9 vd we j3 ac d9 yw ew w3 y0 tk ao hr in e4 hu du qu jb wp cr qs v9 p5 vi xm kf s1 ea t2 wh y1 co iq yo au iy on ds fx yf qa zv qv f1 y8 wm u8 rc o3
+\n iu r5 el dz rt m9 hb lc x2 zp aw uz
+\n k0 px qe qr i2 yz qo ap t1 ou n4
+\n qg q1 wr wt wu 5x ij rg lq eg ia r9 is dl aw g9 xx w2 qt au i7 us jc f2 ge qa gt l7 lb mc x3 3p tz u6 kx f8 fb ku ag hd oj o3 fn tw
+\n ds rs k5 go qg ga qj gs by q3 xy q6 k5 4k o8 ws td mo w8 th ys eq pk yf r5 uo rb r9 td y8 tg ho qn gz li m0 oq kw qr g1 wy iv b7 vt qr qu ti to ta ut sa i0 pl oq sd ho qa gy qq l4 ks fu wg qg kj eh ez yu tf s7 os s9 ya em pq tc fv qg ve sx af ci ah qj bj df ry rl wm zy tv ol ey ox ri ie tq ir yc
+\n ak ra yb ds gt fy qh d3 ql jk jl ni zs q5 zf lf so wo mu yt wa w8 kl ue e7 2d mb yn tu ac pv id pm sq sw jo dv jd jg qq qw qe wr j5 wu 1h b6 vr yf cx lz rn ho gh qi es ev ty p7 fx fs s5 pl sf lh sh i8 qa xs 1o kq zg qh wk fs vo wl ez iq uo tj u3 gs ii je jr hk ql xx 1j v8 nz kf vz ww yw yt w4 rb ol o4 rn ux ig sp gc
+\n yv fr qa rd gm ps jd a8 qh ls vg q5 lg eh z0 vt mi vy rg lp ex ew d6 yg rv oe fs sz g6 sy ha cx qq wy j6 dk hr l1 qe gl ex ln uk sv ty at ru uc ts hi hl lg jv qi vc m0 fy xg qg eo hf mu mo kz ot np oy na el yy wz fh gp up ir e9 s9 f4 gf pw uh uj jr ab qh uc wl ce qz h8 v9 wv ie 37 eu gf yv 1m ma yw wm oh dk sr oc ei o8
+\n qn cd zf y4 oi dv xq q0 lc av cw ki xd lx qi gn bh em uf we ja ox iw qb wn my zs y9 ux
+\n qd qf we ls lf k4 eg bc e5 rl ea r4 oq er ip g2 yl ot iv ps gx qr wy xj vz xl bx 3o qr eu qi uj p7 uc ph in pk qt i4 gq wp v6 kw kd xk zw 11 yj wj rd oz th yo eb ya tl au tx qj wl dz wz cg zv qa rb wm 7a zs vj yw ee eo
+\n jd go qg d2 ji qn wa bf t8 ys eq ui d6 ed yn r7 is qb q9 lp lz qe c0 wu tx wa te qp 64 uq in qt qy wp j0 lz l5 og ca sz un ec rh pb pw h2 kv aw wy qf 16 rw ew tb aj
+\n a2 gr qs fu db qn q1 uc jr qk cn q6 b2 ne lg q7 q8 wi wp b1 ec rk yj pc fo iv sk gk jb qm zw m1 wx zt xy wy em 41 ee gh xg cn yv qp sn od ao pj fs ut s5 tb ad jc j9 xa uj ws kf wg vp nv fa wk mq x6 vh wv t4 ex iq 7r y6 sv ox ev eb rj rk em aj pq gh f8 th os sb mt ak q1 xr yw ti ee tb as ox o5 yo gx uc
+\n qj lp z0 aj wp vr wa bb xt w9 ya on ew ym ia ix pt tw dz jo ae cc qe lc qr cn b3 c0 ib ml qi uj qp pf p8 e1 s3 tn ui sg pn i8 hb ij qw pd ld fo ap ty ro 3b r0 sz ie gp rj e9 fk gd pw rr uj cf qz zr rq 4p kp pr vj w5 iq ey rn ie eo ir pi
+\n gr rs gy pw qd ga jj z3 kj ql nn bg dm zz uy pl e0 lh ef oe am y5 fd qx hi uw i4 q9 hs jb vd cx ni qw wx zt qr d0 wi 43 w3 cc b9 qa rw oa ev ry p4 en tk ti yq pd i5 og ic ye so tc de pj ff hl oe sj qs wf v9 xn gm wg xm 1f ph dr vg wk ns t6 um oa e8 sb t0 gs sm fx o1 de h1 uk qh zj zk ng ct gp nx xe 3z wm rz yk tn ro
+\n qa pt k7 og kl wy rp hx wp wa ui mx eb 95 ac eg dj yz aq in ih i2 q0 cz cb dg xi cq jc qe qt es ed sb en iz fp ta fc tv tn gw ka i0 lz sd il qf 1s iz qf nc xj xk ep r7 rp gu t7 wc t0 en tl iy iu pw kn km ql ct qp ch fl wm n6 rw eo qm vx ty ee ru ig
+\n um rf qd db qf od d1 mb u0 le xu wy q6 mt bc qw cm uu us r5 uf or tq ek sx i1 it la cb ax t0 wu ab 1t qq g6 ko g7 mk qr ey ha ea qp y0 en ue tv ho i6 i8 sp xs qf v9 jl kt rk qy ot 14 na ub aq op yo en tk ob on tx f0 qk jp vi iw tj x9 zi n6 wo wb se aa ag oc gx
+\n iy ub gy pt pd qf me xp w7 rj tk r4 rx ui ii r7 us pb pt g5 fw gf dm wi w1 eu re tq oo es pd ri tl og s2 fx ap ok i4 di lh f2 1i vm cp bh wj wx of on tx dt h2 hl qk wq qz lr tl f3 ce kp yr yg ro yx
+\n k6 qf cp la wp gv es pl uo eg am tf y7 i3 hd jk we d7 rl b8 gg ug es rt p5 eg em tz ow 3y eo wg t1 lc wk ol tj en ak fc f6 df gt ol qc rn tz wv rx di ov
+\n pp qd iz qm vk jg r4 pl ym y7 sc qn jf qy rq p8 yr di qu hb wd rf ks gw qg s1 x7 ec ae iw eb ai sq v8 h8 le ea vh yw yp
+\n ik a7 cp sq q1 lq ql wa qz lr zh rp ra gb w9 ys ui ym px up r9 pr ek qv qb hs bg wt ku pu dc p1 qo ik uk y9 y0 en hr tx ts pk jl ce lj l5 p6 v4 wk nu vg oy aq aw rg os az uj kc py ql oj qc pc fj jr bf cx es vn q4 y0 og w2 ue u8 is ag ie yc
+\n rs dd ik k5 hm dg k7 go q1 qk wt q7 wi ws t6 k0 go ii ee io ym ey sl sz sw jg si d3 qq qw nh lp cc kw xt m3 ip ln nf zm qq tc ex ry at iz p7 ux of he og dq e1 i7 pj sp s4 ok qt gt sd xf ow qr pd hd wj qh x3 yb lx wx um e6 t8 s7 uo u2 it sw pm rr qg h3 aq ze h8 ks zb kb bh ec wb vb w2 oj af
+\n ak ds dh jg cp ws q5 nq wy su q7 kb o7 ys sf et r9 ta sq y6 dn sy cx na j6 jc qi qw qe qr rb tn 3g eo uh tr ft ri uw of i5 ue ta fs s3 uy as ss qu ns lj wp zf wg sm x1 ix mc va mi rx ej yy y4 t7 ex u1 y6 u3 up en au ds ap kv qh kn gw k1 zv eu lu kh tx qk dr dh wm ti h5 o4 w6 yk af fq so aj
+\n uv sa hb ps q4 as wi ej qm zc yd yn fp y3 td hy ue qw qy es tu uq tx e3 jz ud sv l6 fu xh dq wk wx yi dj qz v0 qd ga mp wm yy tn fn yx
+\n qh qz ar qq ma kq rx qa st ei
+\n dc df il he c1 jt qn yd yn pe et pn pi d7 ke g2 j6 rl sk ng z0 m8 mh qw j1 eu qu rr es ec uk ev ul pf e4 sg jv m9 qf vd wk gu rh e9 f3 on qv vj dh aa ru ux yx o8 a1
+\n ra qs h0 qh bf q3 dv bl mr if ws df ev b2 pl om tz ax yk ta y7 aw dn zr ax qt m5 xx wp qy qi qo at ti p7 tv i0 fm qu sh so lk qp hb p5 xk ib vd hk t2 np ek yt um u1 ir sm yf ug az qj v5 wr fg zv af qv ck ay cs ww pq wn w1 yh as yk ei
+\n tr yb df um qf iz k7 q3 we cb cj ne zg a2 e6 ya r3 ut on rq io ow qx ja qv cx cv bh vj qr lv pc 3a rm ep uk ed ev au p8 so fx p0 ts e4 fb hj qt dy px sf f1 zo vx qa wa sa qs vm wf xg kf fz r3 bu t1 tu ez t7 va e6 fl tz uf gg io qg qj h5 zz nh qz zt et ba lu tq vz xe bb md u7 oh 5k rv rt tb yu tn ah
+\n gr da ty qj by we ls av kc qc wi wo xr mx cm yg oe xs pr ua pt dk oy hp qm qq zw vk xi ln he rx ko dz yt qe tv eu qi yz tt y9 ev ry ym ay uq pg oj aa s4 sg hp f1 qu wp qa bn vi os iz hw kt t2 rs wl r0 ez rf pv hs om dd f8 uj dj pt dk km k1 qz qx wc n3 nl wv qn zo vx ww dr yr oj r1 tq
+\n ra jg jr ao c1 wh rj fp gz iy lo gc dh qw qr 8p eo ev fu tl i5 uy uu ui qp mb hk yt ou aq oi e9 ip dt k2 qx vb mf id
+\n rd h0 qn ql la vg qz lw q8 ra sp ts pr av qc vs vg ku am z0 lo ry ev eh i8 aa pl dt du i4 zs w7 wj xl yg yh ra ex u4 pn lw gu pc on n9 n0 wm em tn
+\n gb ik rd ql xi bd yr e3 qq w7 ex rz on ui yg ax fo pv ab ta jp qw xi wi qw qe fh mz eo gk qu uj ed ev en fo ux ye fv jv ws lx kr kf n5 qj ea s4 vh ez um tj ir od ga tk f5 dh uk pr pt in v9 js sv qb zn wb vl zj wm ca mu zs ef rl yw u8 er id uz ah
+\n iy ij ub qs lo ql jk dv h0 wy cm q7 wu eh fq w8 hm w9 mv yd rz rx rv r9 eh pr ek dk el hi qc sy i4 qq lp jj we m2 g2 fo j5 wy m6 ve tx yg w3 rv rn rq qy hs tt y9 ry ym eh to e1 ur ff hk do wa kq jw p7 yp ky r2 wx oy uv ra yt t6 yy sz t7 wc s0 of ds om kx ng ql qz vj wt wb ly wm lw dh md ew w3 tv er as yu an gz si ro do
+\n o9 k7 q2 dt 1i wa uu t8 ut mv ef uo g3 gj hp jn nt cm rj ms wi b6 im qu eo yc ex qp eg sf do sh i8 ih qa wa wf kd yo xj ql wf ek un wx t7 s8 rj f9 qh qk k1 lq h7 in nj um bu qv ov n7 bh bn 3z w1 yt et o4 gl
+\n a2 gt rs ty rd rf qd qn jf qh k8 q1 qj ql d4 cg wt q5 z7 lr wf wu q7 sd yg yh g1 eg to el ih sw tf fg qx dv q0 wq qq uu px vl xi js jd ze la ud qy rr ky ft i5 em p8 p9 i8 hg im as jz tn qo ul wg 8d vs ap mq x6 no t3 ub wl tf iw rh ox ua pv ir us pb tx pw dg h1 uk ux cr sz ko wx jw vl rc tv af du ei
+\n gm we cm jx lf vq vw kb wk e3 df r3 r4 ew yf ti id fe fr su xr sl jg rq rw uq tp ss qy ws od nv wg ro t7 ar th ak da yf sw io jt cq v9 kb iy u9
+\n qd ga q1 h8 xt um wt nq wy wp a2 rg w7 hm cf tj ut r3 ch oe r8 pa qb jb zw mm wq pl m2 wr wy mh hi ei qy nw uf yv s1 fx ut sa tb ss hl qu qi zp nf zd ar l5 5h gm vo ix xk wk wf vf el r0 sx e6 uo rj f3 em dd uh qj cf wz n9 ga tc qk mu rt ye w4 o4 ad ag
+\n qa jr kz c3 c6 vp e0 ng wu ug ty uk tu to hr sp ud m0 ar pa qf wf kr fi ya kk wl xs ed mp x6 ub gu fh rj e9 ya om wl vj ha ex y0 id
+\n qm q2 oh cd q7 kk ld ys yd rv yk id wt qy iz ri fi i5 ic e1 ht 5z iq ha ai sq pn al gh un kt wq mi dr ax u8 u9 gk ru ov hc ep
+\n iy sa un h9 rf fi he uc u6 cd q6 wu zl zz rk lf yd rx d7 ef er rb d9 r9 im hu zv ps qb jf qm m8 qq ji g2 kt qq ew la xy qo es ft ik tl ye ur as tb m9 i8 qa ka qs bm zg ix ya kl t1 wj r9 oi um aw yo ie ys yf hg gq nh zc sb nw qf xm bc xr bj es rx w3 yj iq tm di gx o7 pi aj sp
+\n il qf pd k6 h0 na is q8 4p zl jl z5 hm ec io sf dk if gd qw 1a ld lf qr yx re tq y9 pd iz yw sa wp bn jq w6 v3 x2 br ta yi ha en o1 io ip pr kp nl lt kd eu kf kn n8 zs rx ux
+\n ih db gm jd wr zj xp vp qb c8 pc g7 uf uz p7 sh or xh xm wh mt no fh dh wv tk li qm vb ms if
+\n he ql wi bn c1 rc ip ia av or y8 mx yr dx ex gz 1p ic wf aj kn 51 bj wn o6
+\n hb ty dv gu ps qj ls qz ch q8 zh xp bs vt rh oe ot pb y5 y6 fr ih sc q0 re zx lm id xp yy qr ry ay p6 he dq s4 ff qt sd vx jb qo qp gb ws wd sd co fp kg s1 nm rp cu 8l y2 tf ev sn au us fz hj qg wc u4 au qh wv bn eq r1
+\n uw vr eq rx et rb fa ek id qx ui kr wn uf p4 tl au hw tx im sf yd dz bo wb xw
+\n uv yb ik qd gm gp k8 qk ao z6 ps mw zf jc eg a1 wa 7c zz rh yi lf pl r7 yh d8 g2 r0 tq su cz pl qe qe wr wv ku ho qt yv uj ij es ec ik yn ym uw tl sm he p8 fa ho wo gy ws zf bw nb 5q ql t1 ro rp ej xg uv el l8 rd wz rg go rh sv fh ya it pn hd ao az tc dr ac dy ot sj nd qz ok um ol sx xb wb wi n8 ji rz yr sr h6 et o3 ru rm pi
+\n rs fi ag c3 lw ys ef sg qu qi uq eh e4 gy qt ya ro hx oa f5 1j qa cl wq rl yh pu
+\n ub rd qd fi jl zk oq r8 y1 tp sl i2 qn sd cq 6d mj w3 p6 ta fm bo nv qi wh yj e0 ao uh kn h6 r2
+\n pa q1 fm c4 ig ex 2a yi mx ek ez dv jf qw qe 4s xt ld dh qq mg qr yc eh s4 hj yy s9 pv rr uj or qj cd wc ly x0 wv hh ye ew yh rb yk o5 tm
+\n pp q3 mw rd up td j2 lv af ih hb ee xh yy ua ug aa tb
+\n sa tr ds az qd fi dn hw qg dh qh nt z3 qz ad q7 q8 tf vu ue mx vp lg tz er yj to hy fr sw th qn hf gx jj pz wt lb cm m7 wi b7 vr lo yl qi ry ef sn uq ri fx oh i3 sd i4 ho vb wa qa ik uk ar hw l8 ya cw s4 wg r7 ot wk gu u1 fh th rk en sm u5 iy iu re pr hk qg kn gq cf h8 nj ct gp wb qg hj wm cy ok er tv u0 sy fq o6 gx eo sp ob
+\n yv ak ra co wy zj e7 ew tl fo ek ez im q0 jm bj lc tc rm ec ou bn sd os x2 lh wj ot oi y6 e6 yp ob sq p0 js qh el bg rr rc xw pu
+\n ih um k9 q4 ls jx ej om sf uh dz oi qx cl zm qw qr zc qe i2 i6 uu qp wp ws qd sd fj mx qk yn wj ub gu ar pn rr qg ln dl al vg mf w6
+\n tr ub ds jd gp qk jk d4 kv xo ws gi yo sj sl el tw i3 ow qe zx nx b4 qq ee eu uf uh ex p2 rr ea ry ef eb y0 en ri eh e1 oh fx fv sj jn xf qd vi l7 wg x7 r9 uv ek yt ns aw sx sc vf tk ud ds o2 pr kv ab gt v6 un qz wr wv rb os ie u4 rm zm rw n8 vc za q3 zu yy o3 yi ag pu
+\n ij a4 uj gg jy dt 1w rj a6 r3 ii pe r0 ej ta ts ff i2 ho ov wq kw qt ot m7 qq xv ei lv kr yx yb ri fa ur de pj hi si jq wg r4 x5 hj oy 5i u3 tx tc nd v6 oz wc qv bz qb qj zl dg ed ka vh w3 yt ey w6
+\n o9 ft az ps hq uq a8 ql we wg z8 ye wk bf rs wa c6 dd ys rl wy om pe ix y3 g4 dz gf se tg pa va jn jj al qw sf ma j5 qy wu xo dc rn se eu xb nw qu qi p4 ef ru sm eh im ad gm jv pm zd g0 wg qf ai qz ym qc t8 op iw ox ay tc av k1 ko vj qb zo wq bg q2 n0 rl yt as rn uz
+\n o0 jq qf he qh 7k q7 kb wp z5 tl ew yg et or ez jp g9 jv gk lx vk vw qa qo ou qg kk xz rx ro wc oa us ip x0 ku hp jr o3
+\n pp dc gi fi qf ql by we la za un qz q4 jc zh wp kg o9 qm bm wt r6 rw eg ix yl tp am a0 aw i2 fh th xq gc eq xx yr qt xt nw qu ri uq tl ue pj p0 hk vx uf jm kq ws jl 1s p6 ca he x2 wk wd r5 wg bi hk ro wj t5 sx fh sv e9 ya aj e0 pn ao ug ac kn h4 gq nj wr cu qs kf vx xw k1 og yt u0 yk di gx dp
+\n ij tt ss dv a6 uz gp qk cv lq ql un kz gj wt 4y fq lh z0 6h w8 vp r5 ee tu sg pv y4 pu a0 tg q9 gx qq qw we la wx rr ls zy qu wi xz wi xp ew qe rn ei qo uj rt fy ik tr tk sn pf i5 tc sp s4 in gv i0 f1 si ks nl kw bq co mu eh oi ec sc wc u3 ga fk sm om kb wx bo zj hv y0 en og q6 er tv tb rb u0 w6 tm
+\n rd ik og q3 q5 cn xp c4 ig mi e0 rc ym id tq ou po gg qb sy ob hf pk xr qr up j6 ng xx b0 qt tm eo vw ux yw pg tc e4 gy p4 xv pd wg n5 r3 wk iv rl ht oy uv ub wc ar t9 ga s0 em pw x0 pt bw wm vv vm yg fn ad af do
+\n hb gg kl q5 t1 mi a4 b9 r4 ee up pr g8 gl q0 cc kr c9 vq yy wa qy mz ty yn yq ai og tx tn nd ws 1d ky x3 sz td gu t8 op gs tz de av sk cy zm be wv qk og uc
+\n ph qj d2 cd q3 q4 bi wp vt oq y1 ps cw kn gz ij p4 sp e4 wa sx nj v1 w7 me s7 e9 tc k1 lw zc vj wb kb tw a1 aj
+\n rd a5 hq qg qh q1 la cd kl mp k8 mj vy zz yu ut uo sg yz hi gk sy q0 m1 qw b5 wi dz qw rc aw eu zr uk ti em yr lk kw nz wg fx tt wg x7 rr lm ju th tt eq oc o6 yx ro o8 a1
+\n a2 dm wy ej rh rg pe a9 oi y7 zt vk ga yf pp fh ml tj p5 sn tk im jv v6 lb pf zq ty wh t5 go sv e8 it f7 ac p9 cu bw kg qk f7 w2 ee w5 tq ep
+\n vs rg rj 70 ys nq uf ex hh jn kg ep e0
+\n df q3 u9 4j bn rj hw up td i1 dc hi zb wv g3 l1 rz qt qy ty tj ef eg sm tx ap in px af mx r3 r6 t2 t4 rd uo e0 iy ii hh qg zc v8 qc ch px zy zi ye og er tm if
+\n gr pq se pp qe lq n1 cy qb wb ey
+\n gn q1 ji sc nh pe yh qt ss rw hf kx zm o6 gx
+\n ih hq ap bl wi wa 3y er pc eh r0 yl ta ts dl gg fg i3 hp kw lc ls rl ff wg qi uh uk yq yw ok as wp gc jm qf to yy fh e9 pn qk sz nm li q1 vb yq 2e rl tv sy di sp
+\n o0 yb rf k6 qm fv q5 wi rp fe dd mz rz ee oe ia yz am ig hp fj su gl li we m2 ls xj md z0 uh yx eb eh ur i8 qy oe i5 jv ce jb jm lx ci kg oy hx e5 u2 tj kv qh qo af pv tz az vg yz ri ge
+\n il z2 d2 cs ba wa 1o ys uy ed er d8 sh qx sr qb jd ov xq nu lv g1 ku pu rp qq ee et rm eu xh i5 p8 tx in i3 bn v3 ap r5 oy sl oo dr dg hj lm sk ff vu cu wb kd zi wv mu w3 yt ok rv ol ey yx ah
+\n hv qs qf qm ph o2 zg wa a2 rl pz ow uo y2 ey ix us d0 ek fg ww j4 wv a7 wu qq bv te tr uj tp ue ts do qo cy uk j5 ra ou aq iq ev tj u5 tx gg df dg h4 qj nc wz v7 im kv jt y8 rz w2 yy ei ge
+\n gt df jg og k0 lq kz zf iw kh gv cn ur ea eq yj ix id ez dc qc st wq c0 lm fa lj qq mj sw qe xb rq qo yn ru at e1 p9 s2 ts i8 s5 i3 sf jc xa hb qq gy wd p5 ow qf wj 1n wd qz yt ex e5 op at sm ud tz yf tc ax f7 dg qg ve sl qv tl wn 2h ky yv f8 rt o8
+\n yv dh kj jl wr bi kc 4j nt c5 lo z3 e8 on or g3 g8 uq sr qm hd ll c0 nh ws qu ug ph tc dy oq qo nj wn t7 ox zj qj km h6 ql zz qz qc hn bk fw ob
+\n un qs fu k7 co je gp o1 bg dt vu rj mc rz rx r6 g3 ek qc uw fj li qw lx ku z9 br b6 mz yc ty tl yw yr e4 i3 ud ce i9 rf bq xh ep wf ej rp vu wl u1 os ay of pm ap gg dt hk ab ql lq qs lt nl u3 wq n7 bm ef xm yh w6 ru fq tw
+\n qn ql zj rg ed hs we qw re p7 p8 yr tv pc lh gx i8 wp lz cp fv lq 1b di
+\n rs q0 is q0 yq rl qq vr qa v3 tu in h7 zy u9 o7
+\n ak pw af z0 wa jh tf to ey r0 ta fe tf th wt m5 xu wu xo l1 b7 bv se w4 qi es dy ge vm l8 nv kh l0 j9 bi ez iw ux f0 gt zc 6w bf cx u8 w6 yo o6 fw
+\n gb py gp pg ql um lf bx 6q ra w7 vu rj ui pj tl ii y1 r8 ac eg yl sj tp y3 py im tg zv ll ip wt av fq qw dc yu ei uf qu tw y9 em tl dq fx hk oq zu jx hb i9 bq iz mv wd qi pz lx ek aw fg ag u4 ir tk of pb az f7 qk wz le qs wy wn dd bj mp yq zb cj rc tm yo
+\n o0 pa rd qf dn qg nm ji q6 cm wp ec uu ax r8 us aq se lt g1 bl vz jc mj 6h ul en yw e1 ye tc i0 do ge gn v2 r1 7f ed x8 rf oo t8 s9 u5 pb fc ug ab pt uc ce qz h8 u3 ga fl bc yq iq iw id o6 r2 te
+\n da qf qn nm wr jw c2 ig rj vi ys pl ed ii ax y1 ua r9 ia ab tq an ek dl sl jo g8 qv gl hs jf d5 c7 kt ix wy wi lm qq dz ko qe ff pp qt eu wd yx ec p3 rt ty ik p6 pg i6 e3 sa fd dr gb jl as hz qo j9 j0 qs qd wf p7 br wd x5 hh t2 wl el rf tg ar rj tk em ud pn rw av iq nl qv x8 ov wq wb ec vm y0 w2 ew 5k w6 fw a1
+\n a4 a5 z1 hr qk q3 mq zf qc wu q8 bd a3 xf es yn rc et d8 pr or yl fa se dv dn uy vz wu en mb qa tj uq i6 pl du jx f1 xs qs qd vm kd wh kh mv ed rp ra co tg oa u2 ie ha ir da pr cq uv oy qb qb eo ye rz rc ei o6 id if do yc
+\n a3 qs w0 po gx xo nh uj e1 lz os wj uv ud tx rr gq ve ch cs xz
+\n rs rd qs qd hw dh q1 ql dy mj zz ws vy pj ea mv yf om uf sg up ix pb ab ej tq fr tg i3 nq dn gc wx wc qr wr lv t0 cm wy wu ko qe qr ze ug oa ed ym p5 os uq i5 tp pg s1 ok tb fb vx ns p1 wa qs ka qd lx ps sf zy kj pl ro rs rd wz tf ev gp e8 u3 ir od f5 dh qj cw qk h6 ql ad qb fj tl al zs h2 rl eq rx er w5 eu yz id pu hc te
+\n pa pw q0 j4 4f vq iv yu ry fa e4 kw xm wj t3 ff ye w1 oj rv ul ep
+\n mw di ec wt rx ko i4 qo l3 iq iw py yl
+\n dx uv yv qa a3 ij ps qh cg qc 2n mc ut eq rz ea kc pz sj dl in db fk su qm qe m2 we 1q ke bn xy wb yq qq vr qw xc gf tn re oo qo p8 iv e2 tc e3 e4 fv ff pl sd qy qi si pm ws aa zw bu hu fn yj pv hs gh o2 dy ln v5 qv zb tk bq 4p qj zz wv 8n h1 y9 wm yw og mf u7 tq ov sp
+\n iy wt gx nd t5 r0 yl tg dc qc th wt ld nd zn tc ke qu qo qp tk fa hh gn qp 5d qd ar rg oz fh at ag 2a kd nx w2 w5
+\n il wp ee ym tu ef dl el qb cl qn ob qe qr m6 mf xq i2 ud fn pc gw m9 l7 fs eh gi e7 fk ys pe ok 30 mf o8 uc
+\n db k5 a7 je kj q3 we wt q6 ie ck kg kn gr lf pj io us id in aq jo qx su hd qm li qq jm we lc wc ld d8 lb xj em rn j4 tq oo eg fl sm he ue so hg ok dt qt px j7 qi nz l9 lj x8 wj na wk ez ex rg e7 u5 h4 kn ad cu oa qd do q4 eq w3 yy sy su r1 ri if yc uc
+\n fr ij ft db dn gp qh ph ga gg kl ws wt ab q8 lk wp mi w9 tj pk yf ew us yz id gd y7 dc qx hp qv gl jn q0 d4 qw re qe cn cq pt wu lm dk cz yy qr rq te qi rr ea ex ye dq ok qt sg qa nk wh kt bt bd lh wf yb hu mw el rd rg sb em on qg wq oj zx wv n4 bo qf bf re wb ev yq cl yu w5 ad ag id a1 gc
+\n qd ga dt ej kn r5 ax sg ix av am pu g5 ez fe qm nu ii zt wr vm qt jd im rb ml yx yv ru hr gv ad dw x4 ub hx wz rd ol oo rg yf f6 ii uk dl wl yw yu ie id
+\n yv ga z3 kk pp nq le lr bp qc t1 c2 hc vt lw jl w9 ur r3 ys iu es rc ud yj r9 pb ot ta sk gj jm gx xg sf lc qr ht ve sl g7 qy nw vw fo ta tb oq fn qu hc qp op nz ow wk zo zq yg wg ke yt kr yy sb tk rk tz iu o1 rr pr qh dl dz p0 n2 ci cd vn ms aa yh ry w6 af du gc
+\n q1 q2 mw bz k6 xf ec r4 rx yg ed d8 pv is sj qc q9 zw vf gc cv d0 xx rn ex uj ij ts ff ge i8 zg 4m x5 vh oy yy y5 wc tg at fk ob fv f9 ql bo k4 zn be ww ea ry tv w4 ru ov
+\n tu g2 tq od pk tm fi y1 uf ku wn ew
+\n hn rd um qg qh ph aa zn bc gv w8 rj ea es ui r7 r8 ey fw gh jf qn nu cc la 3u bx ve po et ei eo ea qp ul i7 uu fb dt pz qt m0 zf l8 kl t1 ej wj oy rf th rk gs sm em ap hg o2 ub wx ka hd br q2 hg y8 2e eq tb an oc it ep
+\n tt um gi qh lp kl lw q4 q6 ro b1 if y6 qc th g0 q9 qm j2 we xt xi nd is ng bc ku yw sm ye dw e2 f1 lg qo wp zs gy l4 ul lv w9 br xl ql vf as yg y3 t5 wc ec iy hf ii f6 re hk qz jp oo qx xv v0 f2 vx cd vb yq ew zu yx
+\n lo dt mt z3 rg av us pa xq wq qe qt yx y9 ev ry tk hu oe oi r1 x7 wk wz td jy ww qc 15 ba hd mo 72
+\n rs wi vt rh we jl ur tz tw ht y8 fh i3 qb qm b3 qy ep op yn tu ay hw fd ug qp qd x7 rs yy td u1 t9 sm uh dz ql 4t rw kn wn rc eo
+\n a4 d3 kk q5 q6 wf wg m4 2b vt w7 ur uo rw pc g2 sl if y8 fj va rr ld wn xo qw rn ml la qu ep re rr qo pd eg og e1 i8 ui qt px i4 jc gq oe jj ws ks qd ul zh sm ql tf go e8 os tk rk ay us u6 dw dh pr qh qj oy lm jo cf ff wm br k1 en og aa rb yj o4 te
+\n gb dd rd qd a6 qj wt jx z7 xi q7 kv mv uy pk or yk ek el y5 ez aq dx qx th sy jn pe vl fp xz m8 ng jh kq qr la ei ft p9 oh hj tn ho ud xs wa jq vn il zg p7 fp ic qk wd bu e7 go hd sq ug hh ip sl ch qc px wb hs rq qh bk rl ef yw dj yt u9 st yi uz uc a1
+\n al tt pq um uq un z6 wa vu w8 ed sj r0 tq pu dz qx js 2j na ip vz lm qq qe yj ud ei wf qi te p1 tu il tk iv dy i0 xg sf ix gp fk ai qk lm ql ch fg qv vg yw rl yy rv rm pu uc
+\n rd ik qd jd ph gs k0 q3 qz ia q6 af q7 6w o8 tg gi sj ou aq po ja qn q0 qq gc nh xt wr fs m8 qw aq wp ho qu rm uh tr qp tj ay fi ao i8 aa i9 tv gv qu wo lj vv wa jm qa qd uk nl g0 qd dn gw ic kj nn wf wg dy ej rp y3 rs yy e6 wc oz fh eb e0 of hd yf uf ab gw qc ww yc cd ji y7 n0 wn cg u0 rn yp ie a1 dp o8
+\n ih h9 qd xy yl ez g9 lt qm on vg rz dx qa kt p1 ex yx od uz e3 in sd oi qa cq dr me e8 ua ya dk wx bw 4p vx tn o7 pu
+\n ij rf fu jt gs ld wu q7 wo 2u bd k8 rg ws gi oe yl if sq hi dn jn qw bb cb wt lm sq vr qe wd qi qo tk uc hp i0 pa w6 fo v4 1m x3 t7 u5 sq ai hg ap hm ju fl tz wv w4 ry tn yl fm gl ox
+\n ql db ch wu rl ih qc 25 pb qq ty yw fp ao qy sp p1 qa rf iu rw qg uk gq km dz wv at qb jo eq ur rb ad
+\n ra fy gm iz qk qz lf bp kc is nr ws mb es tl d6 up pe ey sj fq ek iv pn sx ly qb jd jn q0 lp m2 xl fs xx rs b8 hu rn ey qo yn vr yq ti ai e1 so ts jz du do oi sa i0 oq ow 3r 1a wg qg r4 yv ty r8 wk wl s7 u4 of e0 gd pm yf h1 qg n1 lt sv qb eu wi mt ez w2 yk su dp
+\n rd qf dz aa bo pd pm qw rn tf ah wu
+\n dv jd he jt ao ql zg eq pz oe dj fw sc fj nt io fi lr xu ns mx qe qt ei rq qy yw em e1 i8 sp in jv wo ci fa x6 fn ej wv oi um yi oc au yf mt te az yv yi ad yo yz
+\n uv hv ty qd nv jh qj q1 ql we fv vj q7 gw fe wl vu w8 vp 6k yd r7 yj ia ey ot g6 dx tf im hu ae qx fh g9 lt fk hs su ov lo m1 cn t9 wi ki qq qw xx aw nw es yb vw yn ry pd ix em so ut oj du f2 lj qp jm w5 xh ny wg 13 wc qc ek el sx oo th uo yo at pv hn uh hj qj zk ql lw zx qv cc wv en yr w3 yy st uy iq ox an ah
+\n rs pa df il iz qm k9 bu jz bi ji du lo ts yy xf cv gu mc ii rc up d8 ey pv av to yz y5 fd qx sc qv jv qr xt bk m6 ot md qq qt rq ex p2 yn sb xc fp pj qt ce wp i8 j0 wa qd gn ps qf be qt wh ky l9 za wg rp wn fh rh em vn dh vw ng wz k2 h8 f1 nz zh yz q5 zy e1 yh ad tw ep te
+\n db wr a1 pk ew uu r7 d0 pn fe g8 la qq b0 ef os oh pk fm wa wk yi ev ua sq wu n5 tw xc er
+\n fr yb qa hm d2 q2 o1 oj ox dm oc km kj r5 px rb et r9 y7 vs pj q0 4s lm gs qe eu ep ti tl of jq od pf nr nb ea ej yy rh u2 iu qh dk zl qv xe 2k vc vb zb xn yg gk ox tw
+\n hb dc rd fu gu zd js wu xa c5 a5 w9 vo r5 d0 g3 oy ib i3 ha jm nu rr wy m8 b9 ws qu ru eg uz hw eh hg sp sf do jb zp dp nz wj wv fg ae ah ob hd dd gh dz qz xc s5 vi je n4 re bh ma wm as st tn yl
+\n wi w7 om ug qa x4 yn r7 gi re n3 n7
+\n ij pa qd qg uw qm d4 z4 q8 t3 mu yp uf ia pm ez ih qn jm nu kw qr j6 qw bb yu qs rw wf re qi ru jz tm gw lh ce xa wa xs bn nl ys t1 wk r9 gu oc u4 hd ku hp yg rv as yz ro dp
+\n qa ss dc gu qk cs cv fv nm z7 lf z8 xs a3 rk r5 ys eg y1 po qv cl jf xq vh we wr qr b3 bv yr wf re qo sv tj ti eg dq ic fx jz du qp vb ws nl wd wj zq vg t2 zf wb tf yu ex yi yp tj en ua ud dr pe qk dl lq qz h7 ol v8 cy vi wv ck el gd q2 yw w1 ye xq w5 gk o6 ob
+\n k5 hr jk ju k3 jq q6 zg wi id bb wa gb rf rq g1 et ot pn ht dc ww c7 we c8 cm xo mg w1 1l yx tr p2 oo lm ry ao e2 i9 e4 hi tn di lv cp ca 2u t2 no ub ex rk ys pw qg av py ql qo lb pn eo wb er tb yk ie id r2 tw o8
+\n ra qa qd ph jh d2 dx d4 2z jl q5 ld cm wu wi 2t wa dd lg ui to id in uq ww rr g2 wu rl qe 1l qi qo ec yn ed uw p8 ut sj ig p4 zh xm p8 vs vg x7 ot cu l6 sx gu yp t0 gs az pe nf wl qz nj lr cy wr qv tj s7 u2 ly be br ym w2 af ri it ob
+\n pp uv nb bu kz wi ah z3 c6 rg la vi oe ia ot pm dv gk 2h xq kq xg bv qr b9 j2 ec od ay p8 qi wp zd ay kg ea mq 6b qc un fh tl u5 av ub ji zx k2 wc zy 1x kc ah rw vc wv yq zv e2 rp
+\n a2 iy sa ft pp un qn qz ol lf mg wo fr vu ya rk w0 pj pl el dz i3 jd su ob c8 pb id b9 ep yn ru tk s3 sh sj xa l3 wa nj ke kr ic xl bd ej rg yo f3 al f5 sw re uh h2 av cq bo vk kf bd mu wq wm ew ue tv ol tb o3 ul ov
+\n iy a5 gu q2 se ls dt zf o4 dm ez jj uu ik ue w0 ya ea on ui tu rv y1 et r9 tq y5 ht dc fg i2 vs q0 av iv ku in il en ri p7 uc e2 ut sp fv qt gn f2 wo qa op v7 ws l6 wh ys zq t2 wc y3 sx yi t9 t0 ys of rq ug o2 av kn h5 ju ji ko v0 nz wn kf te dw u8 yt fn r1 ie yc it
+\n qj lw ji eq oe g7 jf jc yr qo v7 p7 wd ma xg wz qb u7 w3
+\n un ol eh g5 px b8 rr og gn mx yf wv sl on jo uz
+\n qg qm q5 wy eg ri bm mz d5 rx pt ek fs pi td ez ho gh q0 ll pl kq wr d0 l1 qq ko er qt wf ei p2 ru uq ye tx s4 hc zd vn ps ix zo wk t4 y3 xh ez rf u3 up ys ou xx zv qa wb at rm eu qj wv za zs eq zy rv ry tn tq yc ob
+\n ss qa pp rd jf a7 lp h8 um kc q7 wl rg r3 w0 wy tl a0 ih ly qm qq m1 xg qr up ja b8 yh dc lx rw ep ea ev ay ux to p7 tp tb i3 qu gq do gr za l8 rj og oy ub e5 ae tg t0 sq tx hj ad gs it vc bh yb eb w2 yg u9 w5 fn iw si di ah hc
+\n ub o0 ik ps qd q1 ga lp cf kl m3 z7 q8 ue ee ud ix g5 ib gd aq fh th pa qc pg ue ur xw ww qr vj m5 jd ng in tx ff xc er qs eo qi p2 ky pd eg e1 yr ut ib oj tb hi hk ho gm qu qi hc ou gn wg sn wh ix wj wj wg ot ra wl un e5 rg s7 t0 oc sm tz hf fx pw x0 wz th qv 1z zt n4 qb cl wn xq xr y8 rt y9 rz tb iw vb
+\n qn lq bu eg iw wi 2u 3q t6 k0 yd sd ed rb eh ek yz if pu y6 in fr qc qm ob il ma b4 en wu dk nh b8 qe bb mj ws qt ho yl ug qi ea tw uh p5 eg tl yr i9 pl lh ce i7 wp qa xs dn 7p kr p7 eo vs mb pk ni yh ef rp wj ej y2 iq y6 u5 em e0 ii md jy lw nj fh bq pc xm km q2 wv k1 rx u7 ut et gj tb iw gx fw yx
+\n qa pw k6 qn qg qh as u0 dy q7 wp hv 4z 4c w0 d7 et aw wr bl mx md j6 an wi qt lc yx ec tj ri fx ht in gm ua qo qa ik ys eq n7 wh rs wz wx e7 eb ak gg ip sj py ka rl su ag
+\n gb uz q2 qz wr q4 z7 ia ad je am my vi zc mx ym r7 yk ua pt g6 hy y7 sx ih qx pa hp jd sy gk nh no qq yg rc 3s qy ep p2 yb oa tr eb p5 en ic yr dw tc in hk qt zp i8 lz ks ci lg x3 wd xa x5 zf yt y5 op u1 oa iw fh oc rk ay pb pw uh qg zj qh h5 nf cd nv qx kp qs qb 6q cl kh xe u7 ew tv sr as rt o4 ey tn is
+\n hv qj bo ru z9 t3 lj q9 rg vi rj sd r8 g2 sj yl aq fe po pa qv jf dm qq re we la wt wu qq vt gj ei yz rr xk uk pf so pk im zu ua sg j8 sk zd sd xz zw kl wk ol um yi rh sv u5 pb tz dl oi wz h7 s8 qf wn cx f4 mo wb ed oh ee er ry eu ei oc fw
+\n hn a7 cv q6 cj q8 fs jv rl qq qi od dt l5 co qr zq ex u2 ah on pr wx kp wb yh gx
+\n gv qg je zg jc q8 fr r6 yn ii g1 pe sj ta el jo sr jv ni jj zr bj ns qr qi ur hz vu wh cs ep s3 hu ez rh u2 t0 dw uj oi wx n5 18 bf wb yq oh ov
+\n gb dc um jr mn we bl t6 vi pj c4 d7 rb ia yz tf qn dm ke xb ft au ix tv xd qq xg rx x6 vg r8 wz op h3 qj qx lr xv qc kc wp lq ea rn rm ri eo yx
+\n ra gt qs dv ik gn co qg qm qj cb qz z6 wt ji q6 dy qc b4 ws ds vu cf on yg d8 eh py hu tg qc hp qn d3 wq c9 pv pr or qq ml eo ug tw es il os fi uw to em ic oj ho px wo qp m0 qa 1o ks 7o cp wh wk wg x5 ee yn bi ef wj ns r0 ez um u1 iw eb ir fk ov s0 fl hn h1 pr x0 ux cd wz aq jp im k4 qv bp wm n0 vm u7 w4 gj tm uz te a1
+\n gv il ps db he nb wr ql kc zh tf mp lw ab us pn a0 tg pa th ps hf wc 1a yw l1 fs eq wp qr rw yv tr eh so i0 qf wf l7 wg na ou ah ay f4 io ip f8 cd h7 nj rn wb qb qn wp oj w3 w6 di id pu eo
+\n hm fu pd qk bi wf q6 wu b2 q7 q8 oc lj c3 o7 6s a1 jh rg rj 2s z7 ya id ez fr gh vl cl zq hd jh xh ru c0 bz wu dl qw km kp b9 rn eu yc yc p4 ru tk ux fo ue p9 iv tv s5 do l4 cu rg w6 os fi 4b uz l7 ld l8 fx jb ee wx rp ek tg e8 uf de qh hz h4 qj gq nb wx qc sv go wm zi zo tc 3k ez ec rz ye oh ck w2 sy ia gk rm ei si dp
+\n gi go z5 qz wj mg kl yh g5 y6 g9 xt p6 eh ap sa qu dw j8 ql yg aw t7 ir zj v5 v7 ba tw yq cz gc
+\n ps qn z3 sw gs q4 ie gx ye wz r3 us ef d9 pb y6 tg y8 qb gc ww az c8 cb lv wy a9 qq qw l2 c8 qu uf yx qo ic de ut e4 uu tb fn oe dp wa uj bq sg mx lv v3 ya xk wd by n7 ra cp gu va yo u2 sv rk ir ya hf kc kp bo qb gp qb yc ku q3 dj o3 ey ad si o7 tw ge uc
+\n dx yv ij pw a8 qm ph k9 dz q1 q3 cn wo wp my el bb uo on eh id yz am fe hy sw ha m8 vg wt vl wm qq w3 ls gj yx eo ef en ta e3 i3 zu hl m0 wd co zy l9 nn ea yj e5 rg gi fg gp u4 ir tl tz pm dd kc p9 zx sx qc qv kf ln on qm lw vn vm ew yg se as is di ro gc
+\n al tt gu qf qj xo q8 c4 ws e5 ur vp ea rz g3 fw sx th db kq wt sv tb ad hv 1u gt ss xk wj qj pk rp e7 ha fk f6 dr rr hk dk nf qo lr ka ie fk cz yz q3 ym ks gl
+\n gb q1 qk we q3 q4 t1 ox di ny wa ws gi ea rx yg r6 io ow y1 d8 ey ab g3 is ek pu ez dx qx th i3 jv fk io xh wt oe kr nd md pb vz wi ro se b9 tr yb p4 i5 p7 ux fp p8 sp in ok hj qy hz wa qq zd qd 3t wj aa dy 5u el yi uo go t0 u5 tl dq gd rw uf gg kb ux dj qj go wb zm lu tx vc es ev ry zt w2 tp w5 tn o6
+\n ra ps hm qf qg 4q we ql q4 z6 d1 wp vt xs tg 2s e7 r3 ys oq ef c4 av dj pn aw sr th hf gx uy wr ac zv m6 wn ko c5 qt qy yl yc uh od ri uq fz dq i7 tx fc aa uu qt oe i5 ge ce wa gb vn xg wh og ya xk fs ea yf zw wh ub 8x th iw rj ah ya e9 tl yd tx yf ii fc kx hl zj or qj mh ww kf zm lb ob qn wp ww wn ym u7 rv ie pu
+\n uj by wo ml dl qx m3 8i 2y r1 u4 hj h6 qa xv rn rm
+\n qa gm qh ql u9 ls e3 yk fa ts wr vj ac en id ud ke ye i7 fn tn f1 ks at me l8 kl hk lx rp ek l6 ek oi e6 wc u4 2h pn 9y zq qk ec cf yq oj vz tb o4 iw ox gx te
+\n gt ub hn qd qf hq dh q1 lp qk by ql lq we wr sy wy lh z0 ge k9 w8 th vp pz yg ti fo tp r0 g4 yz ig sx im i1 jv qn q0 wq nu 5t pw wm id qe gg qt xg wh en uc tz pj e4 tv i0 ff qt gm dp jb qp cr gr qa nk ws os wf ne wd mm wf t1 vu wz t8 e7 t0 od hs dq df av km v5 kl we fg cx al ax yq y9 rx yh ul hc
+\n we cf q4 cj bf ws ww yd tk ef ek y8 qv fk wt ko qe ep rt ik ut op mr j0 ej t3 s8 ir pt qk km ww cg wc gi lu n6 yr rc oc
+\n ak ft gy rd hn a6 uq q2 q4 lr ia eg d1 eb on sj dj pn pp qv i4 hs gx ww xj m8 ko im rt fi tc uy tb pl qy pc uf kf kt mv l0 qj x7 oi um tf ap uk wl ql zb vj wv tk re y7 de q4 rc ad rm ul is fq yx r2
+\n dx gb he dl k9 z3 qk lf ad ch js o5 vq zl rj wr th r4 tu uo r8 fp ic g4 fs g6 im fr wq bg no wt dg ru ln rp wi yd qq xz ew i1 kq qt rq wg sb pj hk qu vx oi jm pa vi x5 wf ni ro ot oy di un y6 yo rh sb us tz ac f8 av ve h5 ji mj n2 ci rm yx ep rt 5f yq u9 rb hx aj
+\n ih a3 pi mt do w7 zc nh qe wv rs xc qr ts ut pj im hp xa lv x3 ph tt sc od rr qh km oc rq xl vv jp ef st tw
+\n ft ik a7 lp jz jx k4 hz wo bv q9 6t ur rl qx qv js dm fw wd re ea fd hu jc qu zo p3 lx pf wk vf fj 2o wx sb gs it ol yp di eo ro
+\n tr ih yv h9 k5 qj qk nb wy gk q8 c6 mj a5 yi ur rl uy eq up yj r8 xs sh a0 ez oi y8 ly lp lx fu il ke zy cj sk xq 7u ey p2 uh yv qp rt y9 eg pf so ph tx tc uy e4 tn j0 gy ik vm ul mt nm mm x6 wj rp eh sb u4 ov of tc jt pt qj jy k1 s5 qs 7z do zi cx wq wb ma wm uw sr w5 o3 o5 su r1 yx fe
+\n h9 gm cp z2 fb zd gk ve o7 mt bc wp bd rg w8 rk kx mv uu rb or yk eh r0 y5 ht pu tf se ar fj hp su m2 cb c9 c0 b3 ns qq qw rv gg ij y9 oa od of pg i7 hk do pm 2n sj wa vm zw vg yy om qx nj v9 f3 ee w5 w6 iw sp ep
+\n da jq iz z1 ls z5 cg nt zk 1i gt w7 yi r3 xi yn pc fa ta ez in i2 qc uw si qw d5 kw il b4 fa ib 6c ud rq yl wg tr qp p4 ry sm ut s5 hi qi do j7 jn j0 qs iz p7 wg aq ex go ax ku nc h8 n3 v0 oc ah wm li zp rl h5 is eu o6
+\n gr sa a4 ik dm gp q1 wy m5 fw a2 t6 rj mx e9 et ej q0 ot wu em fa mj qe yg gh j2 te tj p5 eg tk em ao i7 di lh ce m9 wa wf ys eq l1 t3 ej el tf t9 rk u4 ay rw gg dr hj ac qg zk h6 dz ok zy kc mr fz iu hk yj oz ey ag id r2 ov
+\n ds fu ps vo qf qn pf a8 ph q4 cb le cn h0 jg gy b9 rk r3 pj yd oe ht pu ig ez hu q0 qm nu ww qw ow xh b4 is a0 qq hu bb cn xh oo qo y0 fz ue e2 yr fa pj in sa hj ui sp nj zg wj ge wk xg ra ex vs oz eb pv tl iu x0 ln cq xx iq s7 wv qs zn tl wn lr yr r2
+\n az qf fi qn u5 we jq zh wh c4 sd is y5 po oq ki sz qe rm qy yv p4 ye tb ho 1u gq r3 pl td ov u4 hg ax zj wz wb vl vv se 5k eo
+\n tt gi pd jk lq q6 wi gx mj ut ax av g7 qv zm lo 5y dh cw xo ve vy xg yv iv i0 qq xg jv l2 yi sc ga pv pn iu ug gy k3 cl oj tv yl di
+\n qk se pd gt rz uu d6 io d7 tq gf em ym tu ib oe v3 si wa nm wf qf wg rk kz yd hl wx cy bp mx et
+\n uv yb dd k9 ph q4 me o6 nr xa mu ld r5 rb g2 or fe pa fj hp db lu qn nr j2 bk kt xl rn wf qp tl uc dq i7 tx fv ar sf xm mx x1 zw yh lz mr t6 l9 s8 ah u6 x7 yw ol tq eo gc pi
+\n ia ys jh wy sb i0 cp u3 ql kl kh
+\n po al qg qm d2 gs q2 ap qz q4 q7 kv ah o8 rs 2o ex zx qw z5 r4 r8 y1 is ts y8 qc dm ll we wr sg lb jx wu jv qe ee qt qy es ed ym hw to tx hr s2 oh dt dy af di do qo oo qa w5 uz wh kh x1 t1 hk no r7 rp na sl ej op ev tj eb sb ya pb u5 tx ds o1 hz v6 lw jp k4 wv do wn aj bc wn yw to w4 as ey yk is ig rp o8
+\n rs ty q1 wt wy xp e3 wa yd d7 ht ts sz fk su kw xg bw cw qw oo fu od ix sd zu jn qd ci fi xh mo cp ev th ua e0 em kc lm cu u3 n8 xr yq ti yj fm yx tw
+\n dx z2 ga kb yo sf sk fd gf i2 vs qw vj vw qe eu mz tu sp xs qs es t0 eb ak uh hl n1 v9 wv kd o8 rp
+\n ds qn qj qz cb kz bo wi o6 z9 fq wq ml cv cb lf eq r6 r8 ic y4 am sz sx po jp g8 ze we wu en ew qw 3q lz kw tt ty ti e1 fx ut tc uu s6 ow gm sh qp vn l4 uj op xn wh qk wz rc wh uv um ar e7 uf az uh py h5 lq vt nz lu li lm dd rl er rt yu o4 eu yz if
+\n iz ld me z1 y2 dj ar qb b4 l1 mz ij ry to ad xs sd wf eo hj wl ex ie u5 pr zj gt oi wc kg my ex zt ks yg eu aj
+\n gr iy ft pq um qj dz wt gj cn ru kx q8 ws ue rk eb ee fo jb jf la ji ke qq qi qw rq yb qp il eb y0 iv ff zp l3 xm fi x4 r5 xd r0 ol wc t8 ae iw ox fk of pb qj ku xc ct wc ie xn zi wm rz w2 tb u0 su pi
+\n a3 ss je un zf vq zg wo mx d7 pm gd vn eu yk tq ik fu ai qt qf j0 to yy at ii qk wz lw n7 ly
+\n ub dz rv qt rm wg ea pc j9 qa mr h8
+\n a4 wp td ur px qq ki yx go wc tm an
+\n po gn rf a5 uw qn q1 nn we is z8 wj ca t5 ij eb tz ef pr ix g3 ek ta a0 y6 sq pa wq cx kq qw we rt c0 mz pv py wi cw mj qt qu 0e oa tj ux pf to hr ao tx yr ts fd fv s5 ui qu j7 gw ug ss cy ks qf xm fk wg vp kt mv qj mn lk vh yt ol rf th os e8 tj ua rk on pq dg kv km wq kp ad bp os bw pb qh wp zs q6 u0 gj yu o5 if a1
+\n a6 he pu vd cd q4 jz z6 qc jc bz eh wi b1 ed ym eg fo us ib td y8 gj zm pk lc qr wu mh qw sw fi ue j0 xm kz y2 ev aj df h3 qk qc tx rr rl rc ut ad so ro tw
+\n a2 pa we kk eg q7 lh zj wp 4z gi yd yg rc io ix r9 jb xe rr iz jd ij tz p9 qi l4 pa g9 s4 vi tj pb hd f4 qh qk lq qs hn ro
+\n gn k9 qz aw wu ki yf e2 pk v8 xk wg 5y t3 sl u4 ya gd hn ql zr oj ig
+\n fr qn qh ph k0 q2 nq wi zz rh rx ee ef uo d7 ix el fh qv dm vg px wi m8 qq gh ud qy ec fu yw uw sa tb lg us sk wf 5h qf sh vp wk qk zw qz wg aq of ys ak al f5 re f8 pr ku qx wc u1 lr qs wb f4 cw k2 ka hk mf yr w3 ro ir
+\n gr qh ql wh kv e4 r4 oy lu qw pb et uj tb tn xs kr dt td t8 e8 uc xn eq yi af
+\n q5 dt ed y1 am qv ut gx m7 yt rr yq yr dy sh mt wd wm th bv ym
+\n tr qs ca lp uv q3 wu o5 c1 rx om ee er ta ou i1 jb rt ry os ti fc ss px jn gy jz vp ea tg ay rq u6 al de qc zt wn ez rz eq aa rm ox
+\n uv ds h9 fy rf jq he qh h8 d4 wr wf du ck wi km yp ut rv io g1 rb av y4 tw a0 hy sz qx gh ha q9 qw ze 1a bz bx bv qw po ee wa qi xk ri i6 ic he tm hl sj jb qp wp jk qr kf sm l8 be x3 qu ql t1 x6 yy fg rj ua ug qg kv k1 wl v7 xx bj ae wc n3 zy tl tz zk wq re n0 yw oh yr oz eu fm do ux uc
+\n hb pa h0 pg q3 mw q6 mg ls lh am sc gz al j2 wt t9 lm qe j2 rm re rr ry fl yw ux i0 2e eo bt vh ra ys sm pb on tx re ff wn wv tu rt ox ul ge
+\n al fw zb p6 hi qy ay ou rg sx ag rz uy
+\n bx wi kv t5 3w e7 sh ht ff nu la xo qi s3 uy jb 1o vm vi l6 be x3 ny pk aw u1 rk fx km qc be rw yn ey eo ro
+\n dn q3 jf w0 e0 lh rv zv js j2 xg ld hr qe mk s3 dr kw kc dh h2 ql cg zv n3 ym yt aa as
+\n ft ty qh pi d3 qz ip wu wi q8 wj a1 mg mj ut wt r3 om ua y3 ou fd dc zw lp xe cn dh ng qe kp qt mz xy ef ay od tz p8 i0 hu hz qo kw jw qf kf 3y v3 qj w0 ib ew t4 fg oc e9 ua ov hs u6 f9 h6 vj qv li wq iu yv xv rc w6 rm r2
+\n d2 d4 av jc si rs ut 5q pa mm s4 e5 tc km
+\n qa uk uw qh vd d3 q4 xo wo c3 wl wa w7 w9 mc r4 y2 fp r0 tw fr g8 ae qn lp sd bk en vr gd hu j1 xv xg rw ep wh ed fu ul eb fl fz i7 ht jx ns v3 ll zs j0 op xf qf l6 l7 sn wk zw wg ej ti wb wz t6 oz rh rj uf je av dj h6 ql wl oi im v8 zr qv wn ku wb bj ef o4 yl r1 ei so if uc
+\n k7 qg q5 kx oz mu wl ws rh b2 rk yh qn qe 6o 1y mj ei pf ye e1 dw hj hx do qo gc rh v2 zw x5 t1 t3 yu th e9 em au qh f0 qk km ql kp wc 5p vx bg ea ev wn wm w2 rx o3 yk ru
+\n a2 gr qa az dd gm d1 k9 hr we bz lg mg ny wp xd mp yo pj uy xs ua pt g4 tw ez jv q9 qn wr nd md nf qq ng pi bb j2 eu yl ij ty sb os eh hw i6 hg m9 nj wa qs w5 qf nz zh hw wh be zo fs rz me yk y3 ub t7 t8 u2 u3 en ha fl yd hf qh qk wc 1x ze w1 oj ee w3 ey du uz id ah pi
+\n o0 hn qz q5 du 2b bn a4 ex rj y1 dj yz y5 ig tf th js qv 5e gc j3 ls d8 yw bc cz tx mb wf ij ty ai as hi lh l3 qd n1 7o wf wh qh wg ot ra l6 el e5 s8 dg vm 3f 7o wn yw gj tb et
+\n fu a5 cp ch hx hc rd eh tg g4 li sw sf il eg eb zj 2o cg ew uc
+\n qs uc rp ml eb yd if pa c7 oq vk wu ot yq rl uz tv gb zu vm w0 sc tf ud qk wm ko yy er tw
+\n ak tt ub pa pq il jq q1 hr k0 uv ql q3 kk zs q5 z8 is lh q8 w7 qw es ii av yz dl ht td g6 vs jm zr px bj no g2 g7 la c7 xt mz yx tt ym os to s1 ur ta s3 gv pl qy pc qi sh jv j8 gr l3 bi oa wd fy v1 s1 zp hg 5e t1 rp wj ms wl t5 el wm at fl e0 sq h3 dl qz ka ox tj qb wb wq re xr rx em ee yu ri do uc a1 rp
+\n uv rs un qs um il ul q2 jy kl wo a1 rj tj pk ys r5 yn uo oe y4 ou y5 ar zb g0 qn gx zt lb 2v rm qy nw yz lm eg og i7 ht ss qy qi ge wf bw lv lb wh cs wk hf 7g yb zw hk ns ol rh th yo f4 rq dt uj qo fd wx nk rv ka fl mu rr q3 w2 oj ee rt w6 ru ul
+\n qs hq qf qn d1 k0 q2 kk o5 na si bv mx e9 tz d8 tq dl ez qv jf zw ww wu xo b8 w3 i2 te p3 ry iz s1 ut as s5 hk wo wa l6 wh bq xk wj wd ra gu yi u1 t0 ak ai tc ax ip uj nf zb wv bd wo fz qm qj pe md ew rv gj ol yk tn iq yl is si ie r2
+\n d3 ni wr ws li mj ds sh sl qx vs rp ft ik e1 sd af ho xn wg zh 6b rp eb f3 u5 uf df py k1 wz vk vx k2 dg wm er rv rb
+\n gv iz qz wo o7 k0 oq ti r9 us ib ps g0 jm jb tq ue iv pj sa cr kh t1 ot wc at e9 ys o2 ab qj ww za rn yi
+\n ty qn qh nt ql la q3 kl wt q5 mp mg o9 ls lh g2 id ez sw hu qb cx nu pl kw wt vz v2 1t wi mh qr eu rm qs xb ei ij uj yb sn ai iv pj oj de hy gv ka lz pa nx wg wj kj cw zp wk eq wj t5 ns rf e6 rh ev t9 eb ir e0 sm gs gd ds f5 dd de fc f8 x0 lm qz wz xc wc kx cu wv ks lv kv wn pv ei wm ju ww yv zy yt e2 rb w6 oc o6 tq ig
+\n q2 o2 gj q6 zh mg li mo vo ch tl ax ip ho wt ln ro wo qr tr tt os fo e1 de hg gb sk w5 fp kg mm l6 yi u3 fl hs u6 fx re rr dl wb jr el rw pm rt to rx w4 gx
+\n yv a3 qa uz k9 q2 o2 bp ny zl mj vo tk rx ui g5 pu qx nr xt ls lm rv qs yv ik fz tv wp nk gn qh qi yf ek e5 pb au tc ac kc br qz 4t qc mx ly wm kb ez w2 u8 ei o8
+\n rf vo q1 o2 wt q5 oc 5l a2 es oe sc cx wq qw ky em tx rm p2 qo ft ed uq fs i9 ok lz v3 au xj v4 wf l3 eg ej ex wl rv qv ak mi hm cj yr w4 si
+\n a2 tr qa fy qd qh oh kk lq dy bz oc jf wa k0 ip pm po qx wq cx we wr bj j5 yq qe gg rq rr oo ru od ix qt af or sj qo jn gr sk wd nc xo xl wk hh yf eh ek aq ex ar en tl ys rq pm ug ql qz wb wn yw og xw an if it
+\n ak kk wu ig df w0 rb y4 fr gg i2 qb qw yf j1 ij ue s2 qt ad i5 yp ai l9 wk km ql zn yb ee rb ir te
+\n hb q2 ld wt q7 qm km ws w7 vi iu yf rc g1 pr ot a9 pn dk ib qx hi qc jd jg hd q0 lo jj cn wb mz ec qp uj y9 tu yq au tp hg pl jx vx j7 wd 3y ca au rq kv qg dh k2 ok cf qa wv bp dw iu de k2 rt hj wm rc er o3 ey fn si if so
+\n hq q1 qj d3 ws as ld mu rj ut d8 ey ou ib ez gf y7 qx qn vz qm vd zw ww d8 xu v1 av b6 mg gs bb g8 rm qy yv rr ry oa tb dt jb qa j0 qs l5 nz qg wj t4 td t6 eb ua s0 pn ii ac x9 qj k4 wc v9 s7 cj zy wo 10 hn yq vz u0 fm uz ux
+\n ra pp qd d2 vg wj qn rh we ht st jm bv wu wi qy y9 de gw wa sb uz r1 qu pz ot td rg go e8 sn iy zr wc s0 ww ea pw ac w1 h4 w6 rp
+\n fr uv pa jt qk q4 ls wu wi mt xa vu tk ed rb pe fp am sr hp qv m1 gc en yw qq qt ud ey eo p3 tj tu en ix ux ye tp ic s3 ad hz qi uf qa kr wh vd lk yn 5t u1 t0 od rr x9 f0 zj kn nk wp zs se rv ei pi
+\n yb dc qs py qk nb jj ql q5 m3 mg zz e5 i1 zr lc zx xu vq hr xp by ei yx gl qi qp ij eg ai ph ap tn dy zp qp bp kf j5 ib vd eg el yy td yo ie ag em fc kx zx h8 wv sv q1 te wv vm yq ol if a1
+\n ak rd rf qg lo nq xy z6 q6 mw c1 cu z8 q7 vw wp a2 zz w8 yo uu ee yn r8 av yz y6 pp uq dv i3 db jv q9 2l xg rp ib lj sq tx tc mj mk qr rw te p3 ik eg pj e3 i9 im tb tn fm na j7 lj wa ct rg v4 he x3 kl bi r7 wj y1 l6 wk el 9f t6 gu tj od e9 tz re uh o2 zk ki cf lw jp sc s6 qs qb yn yw ms md w3 rv as yi ox du yz ir yc dp hc
+\n yv gy ik k5 db gm ux qj gc w8 ea g6 dx po jb 5t pv wi rz qp jv v1 ea en al ii dt qj py w4 if ux
+\n iy pd yg qq p4 in qa y1 yy ta fb zk s6 lu
+\n ql ws rv yj jk ke lm ff lb fx s4 av uv wl n1 rv dp
+\n qh d3 rs ih rc aq we 7y ud t3 h2 zt cu oc
+\n fr hn k6 je q3 k4 tm zh lj aj li a4 t7 w7 kx ut pl rc ih th hp wq pl ls ma oe lf wu l1 ve lp qt qy fi ti he oh hi ow tm cu p7 nr va r3 tt wk wc s8 s0 hs al o2 hk x0 qj lm v5 wl qz 7u iw os lu ah wm hk e1 o4 rm fq ro so
+\n gr sa rd um pf ca ga ql qz wt ld z6 vw kv my xt cn wr eq tk rw fe qx qc qr qr rk qa qi ex p3 p5 dq ff pc sh cy oq v4 wg s7 yo ya od rq dt un bw zm da bg q5 ru ah
+\n iy qd k6 dm oj qz zd vr w0 r7 d8 et y1 eg yj gz qq p3 il i8 ge wp sx s1 wj t4 lm jo qp pw xc vm sr uz ig
+\n qf u8 iq rg rk g4 im ih oq fp a0 ib tc uj tn nc kz ll u1 un qv ck lv vv
+\n a4 df um jg z2 lq wr tn xu id wo ez rk rz ew d5 ti ix to r0 sk fa fe fr hp jk wr v1 ms wu jm rc qt tr ex uk vr to tz ut hl sg hb qd xn rj jc 6x mo wz rp ek y4 oi oo ae sc e9 od pn hg wz js qv ln ju rx yg as rn gk o7 so it
+\n dd qs qd py k9 lw wt db gk zf nw wh t2 nf zx w8 rj ue w0 tl ew r6 ui ef g1 or ej pn an tq ou ff qv gj jv q0 kq 2l uo oe ku wi w1 tx qe rv 1l ws eu lv p4 ru fo tz ph ib fv uu i3 qu oe pc gw wp sx zd kw w6 bo w9 cs cw my qz zf rg fh e8 ay yd fz rw fc ng qz cg wx qp oz qv ly ha cx al iu rt mp e1 ee w4 tn ul ru o6 ag aj
+\n qa kv e5 bm yj j4 m5 rj qe ri ht oi qf qe t6 e5 aw t8 wc dw un yb
+\n iy jg jj d4 ju ol wy bs wk wq t8 a9 y4 ta dx jp qc q9 su si ut q0 m8 qq 4a zy qq zq sw po qe qt la sn p6 ht oj hy hh qi gc bn w7 au ya kz na oa ox ov je fb or wl qx ze cg we fk tz tv cg uq w6
+\n dx sa qa qs db go lo z3 lf ox jc wj 93 tj tk yf ii ef fo ua sk g5 fs el oi fr sx fg se q9 xq qw j3 m6 4h qq l2 eu rq qu qi hs uh p6 ix fx qa i0 wf ke bq ne wh xl ms un ex sx yi ua pb s0 rq ak ao fc pr qj cw wq vy wv u2 3h wq re yw eb gl eu
+\n hv gv il jd go qh d3 we q4 q5 ej lk my gv a2 ds ex e7 rk yf fq pu ff qx ho js gx j1 qe kw gm ja ns wy ln d0 cz xt te xu tt sb em ix ic p0 i8 im ui di gt ws os r1 qy pz l6 e5 e6 op sb pv sn ii rr v6 ql le zy pv mt da yq ol w6 yz ag it
+\n ds gy dg jf qg uw qj uv q5 q8 q8 q0 qm e5 rk yd tz pv if qn ju cv xy ki qw mj ls yv ru of tz so yr oq qi m9 sc kw qf zh jx wh kg l0 t1 pz un fj os ha sn f3 e0 om ab cw ct nj zy wn fl ww vn fn tn ie ov
+\n co qh jr jj cb bi wt q6 ra qm zx ur r5 an fw tg jm re j5 vl em sl xz qe wa 45 nq ex yb ed ef ph e4 tb s6 qy lz cu gm pd gq mc ca 85 yf wf hu sb eb fk fv dt cq lq qz ww wv xr n0 eq ok er et iw r2 o7 fe it
+\n ra dx og wd wt o9 i4 it pk qo ic dt hj jl oq sf lz wd ca hi fg f5 ap x9 gq nd iy q6 ep
+\n o9 gb a5 z5 q6 wu w0 tl r9 dj if ts ig it zq ll qw qy ep ed ry p5 ut hh dr i0 hl qp qa zs wd ya ot xk s7 e9 om io dl ki k2 wv q1 5g er rb rm
+\n qs w0 om ed tk ta th gf ii av og 6o ee o8
+\n po ty rf qf he qc hz bv c5 mi rh ew tu ef sh ix r0 d0 pb tq fw ig g8 fh i2 uw hf qw qr sf cn wi fh qt hp nq yv fy tj od ux ut fb hu tn qt oi qs oa xm dm fa nm qx yy oo ec ev ox sb ya rk ys ud jy dz zv qc zb qb 17 tb lt yt u9 w4 rb st et ry yl o5 di ux
+\n gb gt az uk gm qh d3 bt qz wd ld o3 bl cm q7 ck k7 we b2 yd ua ew tl rq yg us tq js fk jb gz jn jg qq in qr rq qy 3h c0 qp p3 yn ef sb ym jl sf sh hv qd p4 fj od ix kz ni wj wz tg t0 tj e0 sm om kx ku cw nb zc aw cy qv bq kg wq pn zz wv cd wn yr se o6 pu eo gc
+\n gy rf qf k6 qh qj cd q3 kk cj fw b4 fr mj w7 bm wr ya z7 wt w0 r8 ip ti is pn am y5 qb hs jf qw uu wr np qt wi 1t bx qq qw aw er cv qy rw eo oa iz fp iv qi jm nk kr qf xm eo nr w0 qj bi t3 uv wk ek wn ex e5 rf rh ga it f5 pm hm f8 qj gy jp le wc qc lt s9 zu lb q1 ju w1 uw w3 oj tn tq ir r2 te
+\n ak gn pw a5 qh k9 qk nb 2l qz wr kv mt gt w7 zx ii oe ug ix sz qx qc ar sr zb su vg qe np yg qt yj sv uk pd uq pf of eh jb sk gy ws ke kd be og kh x6 me wz e6 yo iw ah rw pm rr qg pt lm ql qz wz qs ly wb wn q3 ry rx gj ia o5 ge
+\n gy qm d3 q3 ia c1 ta ex e5 e8 eg sy cl jf qe nj nh m9 qa w6 ek iw kv qg ab n4 w5 iq do
+\n uv gv qa un az jd qm eg iw nr q8 zj ny c5 vu rl rx yn et ia ua is ot pt hu im gj qv vv xe xu 1g wo vt qt st qy rw qi wh ft es uk hw to p8 fn f1 hp qu sk p2 l4 zf qf g0 fi l7 be ky iv mn xp nn dt 6b ro kw uv ra tp e6 sv s8 sn tl fz iy qh hz ve v8 h8 th wc wy qb xm s9 hs wq zs yq tu en zt w4 dp yc
+\n sa ak gi hw qm gp pp qz fm id lh 6w 9h xr w7 ui ow rb oe ia us fq g5 y5 ig oi y6 im gk ze qe gn 3o ye xz jh qe db qi p1 ep re op te y9 os pj e3 p0 zp qa ih l4 cu zg wg sn rh lf fz ic kh ni wh vh wx th ag u3 f6 uj jy k3 2a wc kv lu wo hb eq w1 rb xw yo ei o7 gx
+\n hw wd r0 g4 sz b7 pi sn tc in qt zs rg eu
+\n iy hv hb hq qf z3 q2 xy ia tm zf jw wq a3 rk w0 d6 eg et is id po tg gh ob jj wr np no wt ja wy xl l2 yr bt bb tc cx qr rn qt lc rw sy ex y0 ru od to tz og ye hr pj de tv e4 qt ad oo qa jq fj l7 fo wh nt pl ro wl vp yy tf va e6 fg th ar s7 os at s8 re df pe hj f0 qx qc x7 lu nc zo tx bf ww pq cg w1 rx id pu it fe
+\n qf fi ld 4o ge da t5 zz mo zx vi ui w9 pj rl rz r4 uy r5 sf av ot fq tw sc zv g9 qv i4 ut iy m1 wy xo b0 ud cb qy rq ug wg sn fo ix uc aa i9 ss sd di sh j8 qp xa ep w0 7h wl t7 iw tj ya hs e0 fz hd u6 hh dr dh uk qj qk wx ol xb qv wb s8 15 wy zm jr nx it eo fx ww yv zy to ee yu yi iq ey iw rm uz yz ob
+\n po ra ik qd qf je jr lp wr ji ne wu 2b nt wa e7 rx xo ia yl ta ig ff hp gk jf q9 vd si gc qe rk wu by yg rq sb os fu eh em ux ic ao pj hy im du qy cr 2e l5 qw v1 lf mv wk rx dy rp ra rg gi eb hs au ap bo oa sn zi f6 h1 zt ey yz do
+\n lj vu y2 if qr wr ta so kg 3k ol u1 f5
+\n yb cv mq lf zz ue ui dx qe tv qu ex tz hh tb dy ds wi rb
+\n hb gt qa h9 rf qf qg k9 q1 lo q3 ql z8 gl zg q8 1t wo vr rg ez ws mo w9 yo r3 yd e9 ea sf a0 im tg y8 ar qb ni wr qr wv m4 ix d9 nz yq fa if yr bt qr mz qi ea rr xx at ic pk qi za hv kq w7 co xj wd x4 zs wh y3 rf ec u2 e9 ah s0 uh io un h8 iq zb bs nr be zo fz vb wm pr yw md rc ur er ia yl ox ei ux eo tw o8
+\n qs rd rh yf px ow d8 tq ig ih cl qr yw qq in qy wc ek rh ya qg cd x9 qm lq to o3 ul a1
+\n a2 cp as gk kc 4u zj z2 t5 zz rb eh sh sx fg fh g9 hp vd gx oq cv pe wv b8 qe cc nw tr il tl e3 qu l4 mt wk wh aq td e9 gf lm qz bu jq my wp vb dg y0 ye yq w6 r1
+\n ij az qn ph qv bv bf mz iu is y8 ar fh q9 hd qq ji sf ld up qo p2 at sp in qi nk l5 e0 rw px 5o ew oc te
+\n qd jr pa q5 w9 hw hu y8 dn qn zw wr ma ei xl dq i7 i9 vb sx wf wh na wl um e7 s0 h2 nh nk fj yl wn iu u7 as ad ey so uc
+\n la up ic g5 ay ic x8 u2 ar eb wb yr aj
+\n po da rd un qg uw lq m2 4r wg q8 z9 t3 zc d9 ae st q0 li qw wt kr qu ry en sm qf kf kh ny yt gi rh u5 em tc kv h8 qx lr jq ef
+\n a2 dh qh q1 h8 qz z6 kx z8 bv 3q df pk tl d8 tq tf g8 zb qw 5p zm qe cv yb ec uz iv e2 gq wp uh kq ws lc wk x3 t8 rj fc io je dk lr lt wv wt bw be eo q4 ye yy rv ok yo yp ir ig
+\n rs ij ty ps ul wr bh kb rs z4 z8 er px uo up y1 rb fo jo gg dv ph q0 jn xw ww d8 rp yd yf tx b0 op yn of jl tm px fm jc zf qd pk wh rp uv tp t9 ir yf ug qg v5 ku qz fd k4 cu mw zn iu bg lq ly rv su
+\n ik dm cm or tw pu lp eh qd kk j0 em ng tw
+\n ra ds qk cg q7 k6 4p t6 yu lq go yd eq r8 fw am dm xy cm v1 cz eo qi ij yn eg hq tc sj qa i0 oa l6 p6 wj vd wf mr yt ex e6 yo t9 ev s8 en rr bq kg hb lm re bj ms w1 et du
+\n o9 gy bl wz t8 hq iu ix av y5 y8 jn j1 np xt t9 vw qq 43 xv 9w yi ft es hy op lg vs hg wd ef wx ou ox sw dr ze xr st fm ah
+\n a3 wr fb jc c2 w8 rx fe q9 hd xq qq wi te y9 e1 qt qi qs nl ca bh u2 md tv hx
+\n ra jh q3 aa t3 1o eq lh rv fo us pt dj pm pi qn zr bj xj cm ix a0 ra hi eu nw yc p3 ru ri ue e2 jl hi wo g9 xn qh wl wx go yp rr dj nd ch u3 fj bd jy vn w1 ia ox tm uz
+\n ma y5 bl qi g7 ri fl ap 7a yo ko rp
+\n um dh pg wq r5 sf ia ta an hs ne q9 wt sh rk yi ym of tb oq do hv wj ic oi sc pe sc wq wb wm tq
+\n hq qm gg q4 xu k4 k7 uo wt kb et fo ey aw g0 xi am in qy eo qi eb ay ue og nt kl wx s9 df qg f9 v6 rv sv pc tl my bj wb eq h4 o3 ri
+\n tt uq qh nb qz wt jx ya on om io ow ha qp e2 fd e4 hp hx p2 vm xg xn ra l8 iu yf jr qh k4 1l oa tk zp yw rz sy ul yx eo ep
+\n ij yb qs fi ul qk by ql jl wr bi q5 bl tm q7 xp k7 vy gi tj rl rx yf ym tu er r8 pe ip ej y4 fd jn gx zt vj xt xh rj kt cm ri nh zq pp eu rw to pg e1 ue dw e2 so tb gm qi jb nk gy pa v1 xj fl kh 3k kl ed wx wc ek yy ez wc iq yo u4 it tz ak hn f8 h2 hl uv wz h8 gi nk ch zt wt bw kn yq e1 tv zp ag it
+\n qs rf jq go qh a8 jj xt le wu qq yd d6 d0 ff qc su c7 lc wp ty y0 tu ti pf ta aa ug vb rf vi rx no un yu e5 7r up rj ag ha hs fc wz bo qv bp tv ki er
+\n yb qa rd lo ok q6 o6 ba r6 ow or yl am aq gd dc ho cx c0 wu g4 ib c5 ep re qo ed yw iv ta hy jc pn xs oq xn bo zg ps kr iz yp wh wj xl xo zq me na ek wl wx wc rg uo ir tk aj da rw hm io uj fb jt qj dk nh zx jp qx wc zr zy zu nc xe ww wv vn h2 q6 en ew ad yl af eo if r2
+\n yb o0 dn z1 q1 sw qk po xt wr ls z8 ox wu jd ro q8 lh mh wa rg ea c3 pz tu g2 is a9 pn tw po qc sa jj vh ax xh kt wy jv mg nh kp b9 qi od ht e4 uu ij qf sf nc wk ap wd qz rd yi s7 tk pb it f7 o2 f9 kv qh h4 ln wz gi qd zn xm sn 39 yn rz u7 yr yj is ie ag ir tw
+\n po dx uv pq jd dm d2 hr cs gs d3 q4 wr np ab di mh vt w7 w0 on tl ia ta aq dz y7 i1 qc pg q0 wq j2 c7 la cb il wr lv na ru 4g vz nf bc sl qq qp qt ud rq wg ex uw he tz ye p9 ui ou vu at ix w0 vf bi ed yh wh ra y6 wc u1 t8 fj ov iy tz kx h1 hj jy qj h6 ng jo wz cj ie mt rq te n9 mp ma q5 8w rb o7 sp ob
+\n po ra dg ca qj q2 is kn rd ws lq tu ym yl y5 tg pp qw we cn a7 1t jd m7 wo yr sz qa hp ei qy ec p4 hw p7 to au iv ht qt qy qo l4 lz xm wd yf wg ez s7 en f3 tx yf rr f8 cw ji qv yz ry ew w2 oj w4 w5 st rn oz ri o6 dp aj
+\n gm jg ju q5 np lf q7 xo 1y qn k0 jo pp qx th q9 4f or ro pu bv eu nw uq ao dy jb j9 gr rd nz wj wj r9 co ta rk od dd gg hm df pr km ng oj qc sb qd wb tz cq ex wb vb ty eq tv iw
+\n fu uq co qk jl cg ld lg wo vr gc bd rj r3 yd rz iu ew d6 io to sh y7 jp db dn qn qm si xg qr ls jo lr wy rk wn m7 qu bb es op qp ru en ta e3 in hy dy hl vc gc gt jw ke 2t wh rk lj hg oy e6 yo ev em fz rw pq re dg qk ku oi qz k4 qv li rq n8 ec 4d yb wb e1 iw id o6 ir do ux pi ep
+\n a2 wu jd ef dc mn 5e qp pl xd ag ay
+\n yv o9 al a5 uq qg jw pi z2 jt cd q5 3m zl ez vu rg jl rz yf ix sj fp d0 tq ff ha hs zw om ni m0 xg c8 a7 ki qw cc ei xg j3 tt tu il p6 ix tp tx ib sp hg p0 fc pj su qu jv sj lk qp ws qs gm 1x mx lv wj qu l1 dt wh wv un aq fg rg e6 uo ar ie up it sw tx f6 o2 h3 qc qa ho vj u3 kd zy n6 my ww vc lr em w2 se rt o4 yc a1 te
+\n qs dv pa ty iz uw qh jj z3 tn jc eg e4 qq w7 ut r3 uu kb up g1 fo iv if fd gd sc qm qe xg ia wb he ky hu tv rw qu rr es p3 ue s2 as i0 dt qt hz jm j0 gy ci fi hw nv ea kk vf rx 68 ti rp wl oi vp at om io uk pt qh qj dl cf lr cx wq ku ki w2 yh af ul sp yc it
+\n ub yb dc ty gm dm go nv we ql by la o1 ju o3 jx fm aj wa rg e4 vi a6 r4 xo tz oe ip pv dk tq a0 tf fg tg i4 pz sd ry ky mg hy g7 eu qy yi rw qp eg yw hw sm uc i7 dw fx s3 sf zo m9 xs vn rf ci nz kr qt 9y pj lk ee pz ef rk e0 fx uf az fc qg jr oy lq cg qp um ad wc zn bw n6 my xr mp tu en o3 iq ir ro
+\n da a3 d1 jr dz ca ql nu q3 cf o6 nr mt lk yr rs lp w7 a5 pj ys ym r8 ey to fs dz im ih sw qx qv zn gl j1 xe lc zc vw 6a mh b9 qt rm re oo qp p4 tk ix p7 og tz yr sp aa hk ih lx qd mx 4n kk vf el oo td ae yo fj uf pr hl qj qk wr qc qv kf yz my wq hn zs dr ee u8 rv et ru ie ag tw
+\n gt ph z0 zl mu ui av zm om ui vh qr he qr es fl ws w6 nc ra rk kp ol wm yu it
+\n dd df jq jd ux ql el 3r ya uu iu ee eh g3 sj us ib pp qc jv hd bh zt uo d8 b3 xu bc rq te uh ex tt eb il qu pc ge sj qp ih xf 3r gr yh qx tu wl wn sz up ay it ab jt qz v7 wn li za 6o w3 fn yk eu ie gz ro
+\n yv o9 qf eg eh mh jh rh r3 rv ix y3 a0 sr qc qq qr wr qe bx ki m8 mk qi lm uk eb ai ur e2 xd nc ca eo mb ed uv rs up ya of hn lw wz qz et qh wm zr rc o3 r2
+\n ss qg qj ph qk q2 cs z4 bi qc cj q8 qn w7 rj ys ea r4 uy om rc ii fp sj ej yz el qx qv zn gk q9 hs m2 ii d7 nk c8 j4 qq dl gg pp ei qo yc od fo eh fp ta hy ok tv uu us dp qf sb zg ks sg n3 wh x2 nr cs wk kh wk wf ew 7h 7k oy t6 gi rg yp s9 ya e9 pb tc dt dh hk h2 pt qh h7 wz n1 qv kd pm cc xr kp yk tm ge
+\n gr qa ft tt gn qs pw pu ca ph ls cg cn zf bz q7 z0 c3 qn gv w7 rg ut e8 ii er ip sg y3 oy ek ht gd qx g0 qv db su jn qq lz uu jo ru an wi kn sq nh qr qy yx eo qi xz y9 ru pd au p7 dq he ut ok fd jz ui hc j9 l3 hb xd jq gy kh wf xs sl rs aq ez y4 ts um yi e0 gh dk py v5 qk ql ko jq wc nk v0 wb qv br iu wm 6p sr gk yp pu
+\n o0 pa pf z3 jt jy z7 cm ne w8 yz fd fg zn qq ll vg wr wb ia xx yj ty eh e1 so ts tc s4 i0 tn wo wp wa op va wk x3 vg qx rs sn au f3 tz sq hn rr o2 fv un k2 vj ey dj
+\n iy ra ij ty a4 un rf qg dm jr kj uv we cv gk wy z8 oc wp mo jl mz ev ch rv tu ax y2 g3 oy y6 im uq qv hp qb hd iy lp nk w2 bb ho ep tr os en sm p8 p9 hy ss ui gm qi oo vn ae qd w6 ps dn wd wg ro mr yt ol oz rg s7 u5 tl yd rr ax f0 cq ku qx ze n4 wn kt ca jy bg yc zs yw rz w1 eu rm r1
+\n hv fu ca q8 mt la r3 pl yh to sy yh tv x4 tg yp ov wn ze sp
+\n o9 qa az gm qd pw hq pd ga qj cd q3 jk pd du c2 zk xf t8 eq om es rc ua y3 pu ig qx se qv db st qn ii lx qe wt xk nx ku br qe qr qt rm eu xf xb rn qu qi ep qo rr ex xk p5 ym fi uq to ux ix ai hj gn zi oq qf kd wf xn kr w8 rl kk mq rp rf u1 s7 oa fh e7 yp e0 pr ql sx ck ag kg kt mp eb rl em ee w6 du rm yz if ep
+\n qs pi am 6a ut r4 ii sd ua ib y6 pa kt pb wm qq dz qt qp y0 he p8 ue tb qu or qo wh 40 8j t4 sl rf iu gh hh qc iq bf rl wm mf oh ew is dp
+\n da ps a7 jr z4 q3 bu xt ip jx q6 np z7 bp lg bz ye wo ig bb ww rf om uu ef r8 ey pt ta pn y7 gg th dn pg qb ri qq 42 qw zw b9 b0 xb qt qy yl wh xk ft at yw i7 sp de pz fn qy si m0 ik wf sg cq ql hk er eg lc ek na wc iw ir rk ua e0 ak iu sw ap uj av ab hl uv zc qa wc jw vj qv vk ay kg xw on rw 1b wn rl eb vm eq h4 yt oz eu uz
+\n a2 qa rd cp qh ub vg ws u0 4g bp da yo ev kz eq uu ee ef yk pr sj sk fe oi lt uy j2 gn io vk ns 27 ln wu ve yr l2 qu qi ry il ul tj eg ux i5 yr tx ph oj gq or zp wa qs gy iz v0 qt wj ic ca lh yb np ej sl td l8 yi iw s8 e8 ys yd sq al dt pt tg te yb eu tq r1 ir fe
+\n tr h9 go qj b1 wu q7 zh el tg mb ys ed ii er r8 xs pe r0 sw db ov m7 d3 re no nu zr pq ji wr lc or qw ee yy qr rn rm re qi te ea qo yb yn y0 uz uq iz tl yr i0 fm wp qs qd he wk kl ew as hl ez oo ox ie s0 f4 dl wq wl ww lr qc qv vk mt my kn ep em yt sy am so rp sp
+\n ak ft qg bg ji q6 bk xi tf mo ur pj yk ua qv wq gc qe ke ef eb tk uq i6 oh iv gb qs rx el yo rr pe wz wx ho xq tc mo yk du r1 tq oc hc te
+\n ra ub qj jh jt dx ql q6 da tf r3 ew iu sg tp yl el gc 6n tt ry pd ye ff lz kt yp fl yf dl rn
+\n o9 hb h9 qd dh qg q1 qj jy se q5 wt nr qv ge c5 el 6y uo rv ax pe et r0 fe y6 dx qx ha qq lo we zy v1 wy dl vr wa qr rm qi qp yn tz pg ph de p0 do qp wp wf bw xh ky xz wh hl to ek rd sv rj rq re h1 qg qh kl f1 zm 18 ez xe vm en 5j o3 rn fw fe it
+\n db c2 bb o0 w8 kl kc y4 qx zm pk cw id ve mh lp rq jb fl x1 qi wd lx f3 cy bq dd ye fn ig
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index 7a610e40ce7..daecabb5b72 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -196,3 +196,7 @@ CREATE TABLE array_index_op_test (
i int4[],
t text[]
);
+CREATE TABLE test_tsvector(
+ t text,
+ a tsvector
+);
diff --git a/src/test/regress/expected/oidjoins.out b/src/test/regress/expected/oidjoins.out
index b7ad2b813c1..bd55dc24ae3 100644
--- a/src/test/regress/expected/oidjoins.out
+++ b/src/test/regress/expected/oidjoins.out
@@ -697,6 +697,142 @@ WHERE tgfoid != 0 AND
------+--------
(0 rows)
+SELECT ctid, cfgnamespace
+FROM pg_catalog.pg_ts_config fk
+WHERE cfgnamespace != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.cfgnamespace);
+ ctid | cfgnamespace
+------+--------------
+(0 rows)
+
+SELECT ctid, cfgowner
+FROM pg_catalog.pg_ts_config fk
+WHERE cfgowner != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.cfgowner);
+ ctid | cfgowner
+------+----------
+(0 rows)
+
+SELECT ctid, cfgparser
+FROM pg_catalog.pg_ts_config fk
+WHERE cfgparser != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_parser pk WHERE pk.oid = fk.cfgparser);
+ ctid | cfgparser
+------+-----------
+(0 rows)
+
+SELECT ctid, mapcfg
+FROM pg_catalog.pg_ts_config_map fk
+WHERE mapcfg != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_config pk WHERE pk.oid = fk.mapcfg);
+ ctid | mapcfg
+------+--------
+(0 rows)
+
+SELECT ctid, mapdict
+FROM pg_catalog.pg_ts_config_map fk
+WHERE mapdict != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_dict pk WHERE pk.oid = fk.mapdict);
+ ctid | mapdict
+------+---------
+(0 rows)
+
+SELECT ctid, dictnamespace
+FROM pg_catalog.pg_ts_dict fk
+WHERE dictnamespace != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.dictnamespace);
+ ctid | dictnamespace
+------+---------------
+(0 rows)
+
+SELECT ctid, dictowner
+FROM pg_catalog.pg_ts_dict fk
+WHERE dictowner != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.dictowner);
+ ctid | dictowner
+------+-----------
+(0 rows)
+
+SELECT ctid, dicttemplate
+FROM pg_catalog.pg_ts_dict fk
+WHERE dicttemplate != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_template pk WHERE pk.oid = fk.dicttemplate);
+ ctid | dicttemplate
+------+--------------
+(0 rows)
+
+SELECT ctid, prsnamespace
+FROM pg_catalog.pg_ts_parser fk
+WHERE prsnamespace != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.prsnamespace);
+ ctid | prsnamespace
+------+--------------
+(0 rows)
+
+SELECT ctid, prsstart
+FROM pg_catalog.pg_ts_parser fk
+WHERE prsstart != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsstart);
+ ctid | prsstart
+------+----------
+(0 rows)
+
+SELECT ctid, prstoken
+FROM pg_catalog.pg_ts_parser fk
+WHERE prstoken != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prstoken);
+ ctid | prstoken
+------+----------
+(0 rows)
+
+SELECT ctid, prsend
+FROM pg_catalog.pg_ts_parser fk
+WHERE prsend != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsend);
+ ctid | prsend
+------+--------
+(0 rows)
+
+SELECT ctid, prsheadline
+FROM pg_catalog.pg_ts_parser fk
+WHERE prsheadline != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsheadline);
+ ctid | prsheadline
+------+-------------
+(0 rows)
+
+SELECT ctid, prslextype
+FROM pg_catalog.pg_ts_parser fk
+WHERE prslextype != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prslextype);
+ ctid | prslextype
+------+------------
+(0 rows)
+
+SELECT ctid, tmplnamespace
+FROM pg_catalog.pg_ts_template fk
+WHERE tmplnamespace != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.tmplnamespace);
+ ctid | tmplnamespace
+------+---------------
+(0 rows)
+
+SELECT ctid, tmplinit
+FROM pg_catalog.pg_ts_template fk
+WHERE tmplinit != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tmplinit);
+ ctid | tmplinit
+------+----------
+(0 rows)
+
+SELECT ctid, tmpllexize
+FROM pg_catalog.pg_ts_template fk
+WHERE tmpllexize != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tmpllexize);
+ ctid | tmpllexize
+------+------------
+(0 rows)
+
SELECT ctid, typnamespace
FROM pg_catalog.pg_type fk
WHERE typnamespace != 0 AND
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 247c8c95837..a8aecd1dee6 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -776,6 +776,7 @@ ORDER BY 1, 2, 3;
405 | 1 | =
405 | 1 | ~=~
783 | 1 | <<
+ 783 | 1 | @@
783 | 2 | &<
783 | 3 | &&
783 | 4 | &>
@@ -790,10 +791,12 @@ ORDER BY 1, 2, 3;
783 | 13 | ~
783 | 14 | @
2742 | 1 | &&
+ 2742 | 1 | @@
2742 | 2 | @>
+ 2742 | 2 | @@@
2742 | 3 | <@
2742 | 4 | =
-(30 rows)
+(33 rows)
-- Check that all operators linked to by opclass entries have selectivity
-- estimators. This is not absolutely required, but it seems a reasonable
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index 6a31d52bcfc..922c6af685d 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -115,6 +115,11 @@ SELECT relname, relhasindex
pg_statistic | t
pg_tablespace | t
pg_trigger | t
+ pg_ts_config | t
+ pg_ts_config_map | t
+ pg_ts_dict | t
+ pg_ts_parser | t
+ pg_ts_template | t
pg_type | t
point_tbl | f
polygon_tbl | t
@@ -135,6 +140,7 @@ SELECT relname, relhasindex
student | f
tenk1 | t
tenk2 | t
+ test_tsvector | f
text_tbl | f
time_tbl | f
timestamp_tbl | f
@@ -142,7 +148,7 @@ SELECT relname, relhasindex
timetz_tbl | f
tinterval_tbl | f
varchar_tbl | f
-(131 rows)
+(137 rows)
--
-- another sanity check: every system catalog that has OIDs should have
diff --git a/src/test/regress/expected/tsearch.out b/src/test/regress/expected/tsearch.out
new file mode 100644
index 00000000000..1a397b6680e
--- /dev/null
+++ b/src/test/regress/expected/tsearch.out
@@ -0,0 +1,893 @@
+--
+-- Sanity checks for text search catalogs
+--
+-- NB: we assume the oidjoins test will have caught any dangling links,
+-- that is OID or REGPROC fields that are not zero and do not match some
+-- row in the linked-to table. However, if we want to enforce that a link
+-- field can't be 0, we have to check it here.
+-- Find unexpected zero link entries
+SELECT oid, prsname
+FROM pg_ts_parser
+WHERE prsnamespace = 0 OR prsstart = 0 OR prstoken = 0 OR prsend = 0 OR
+ -- prsheadline is optional
+ prslextype = 0;
+ oid | prsname
+-----+---------
+(0 rows)
+
+SELECT oid, dictname
+FROM pg_ts_dict
+WHERE dictnamespace = 0 OR dictowner = 0 OR dicttemplate = 0;
+ oid | dictname
+-----+----------
+(0 rows)
+
+SELECT oid, tmplname
+FROM pg_ts_template
+WHERE tmplnamespace = 0 OR tmpllexize = 0; -- tmplinit is optional
+ oid | tmplname
+-----+----------
+(0 rows)
+
+SELECT oid, cfgname
+FROM pg_ts_config
+WHERE cfgnamespace = 0 OR cfgowner = 0 OR cfgparser = 0;
+ oid | cfgname
+-----+---------
+(0 rows)
+
+SELECT mapcfg, maptokentype, mapseqno
+FROM pg_ts_config_map
+WHERE mapcfg = 0 OR mapdict = 0;
+ mapcfg | maptokentype | mapseqno
+--------+--------------+----------
+(0 rows)
+
+-- Look for pg_ts_config_map entries that aren't one of parser's token types
+SELECT * FROM
+ ( SELECT oid AS cfgid, (ts_token_type(cfgparser)).tokid AS tokid
+ FROM pg_ts_config ) AS tt
+RIGHT JOIN pg_ts_config_map AS m
+ ON (tt.cfgid=m.mapcfg AND tt.tokid=m.maptokentype)
+WHERE
+ tt.cfgid IS NULL OR tt.tokid IS NULL;
+ cfgid | tokid | mapcfg | maptokentype | mapseqno | mapdict
+-------+-------+--------+--------------+----------+---------
+(0 rows)
+
+-- test basic text search behavior without indexes, then with
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
+ count
+-------
+ 158
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
+ count
+-------
+ 17
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
+ count
+-------
+ 6
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
+ count
+-------
+ 98
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
+ count
+-------
+ 23
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
+ count
+-------
+ 39
+(1 row)
+
+create index wowidx on test_tsvector using gist (a);
+SET enable_seqscan=OFF;
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
+ count
+-------
+ 158
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
+ count
+-------
+ 17
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
+ count
+-------
+ 6
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
+ count
+-------
+ 98
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
+ count
+-------
+ 23
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
+ count
+-------
+ 39
+(1 row)
+
+RESET enable_seqscan;
+drop index wowidx;
+create index wowidx on test_tsvector using gin (a);
+SET enable_seqscan=OFF;
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
+ count
+-------
+ 158
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
+ count
+-------
+ 17
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
+ count
+-------
+ 6
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
+ count
+-------
+ 98
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
+ count
+-------
+ 23
+(1 row)
+
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
+ count
+-------
+ 39
+(1 row)
+
+
+RESET enable_seqscan;
+insert into test_tsvector values ('???', 'DFG:1A,2B,6C,10 FGH');
+select * from ts_stat('select a from test_tsvector') order by ndoc desc, nentry desc, word limit 10;
+ word | ndoc | nentry
+------+------+--------
+ qq | 108 | 108
+ qt | 102 | 102
+ qe | 100 | 100
+ qh | 98 | 98
+ qw | 98 | 98
+ qa | 97 | 97
+ ql | 94 | 94
+ qs | 94 | 94
+ qi | 92 | 92
+ qr | 92 | 92
+(10 rows)
+
+select * from ts_stat('select a from test_tsvector', 'AB') order by ndoc desc, nentry desc, word;
+ word | ndoc | nentry
+------+------+--------
+ DFG | 1 | 2
+(1 row)
+
+--dictionaries and to_tsvector
+select ts_lexize('english', 'skies');
+ ts_lexize
+-----------
+ {sky}
+(1 row)
+
+select ts_lexize('english', 'identity');
+ ts_lexize
+-----------
+ {ident}
+(1 row)
+
+select * from ts_token_type('default');
+ tokid | alias | description
+-------+--------------+-----------------------------------
+ 1 | lword | Latin word
+ 2 | nlword | Non-latin word
+ 3 | word | Word
+ 4 | email | Email
+ 5 | url | URL
+ 6 | host | Host
+ 7 | sfloat | Scientific notation
+ 8 | version | VERSION
+ 9 | part_hword | Part of hyphenated word
+ 10 | nlpart_hword | Non-latin part of hyphenated word
+ 11 | lpart_hword | Latin part of hyphenated word
+ 12 | blank | Space symbols
+ 13 | tag | HTML Tag
+ 14 | protocol | Protocol head
+ 15 | hword | Hyphenated word
+ 16 | lhword | Latin hyphenated word
+ 17 | nlhword | Non-latin hyphenated word
+ 18 | uri | URI
+ 19 | file | File or path name
+ 20 | float | Decimal notation
+ 21 | int | Signed integer
+ 22 | uint | Unsigned integer
+ 23 | entity | HTML Entity
+(23 rows)
+
+select * from ts_parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
+<i <b> wow < jqw <> qwerty');
+ tokid | token
+-------+--------------------------------------
+ 22 | 345
+ 12 |
+ 1 | qwe
+ 12 | @
+ 19 | efd.r
+ 12 | '
+ 14 | http://
+ 6 | www.com
+ 12 | /
+ 14 | http://
+ 5 | aew.werc.ewr/?ad=qwe&dw
+ 6 | aew.werc.ewr
+ 18 | /?ad=qwe&dw
+ 12 |
+ 5 | 1aew.werc.ewr/?ad=qwe&dw
+ 6 | 1aew.werc.ewr
+ 18 | /?ad=qwe&dw
+ 12 |
+ 6 | 2aew.werc.ewr
+ 12 |
+ 14 | http://
+ 5 | 3aew.werc.ewr/?ad=qwe&dw
+ 6 | 3aew.werc.ewr
+ 18 | /?ad=qwe&dw
+ 12 |
+ 14 | http://
+ 6 | 4aew.werc.ewr
+ 12 |
+ 14 | http://
+ 6 | 5aew.werc.ewr:8100
+ 12 | /?
+ 1 | ad
+ 12 | =
+ 1 | qwe
+ 12 | &
+ 1 | dw
+ 12 |
+ 5 | 6aew.werc.ewr:8100/?ad=qwe&dw
+ 6 | 6aew.werc.ewr:8100
+ 18 | /?ad=qwe&dw
+ 12 |
+ 5 | 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32
+ 6 | 7aew.werc.ewr:8100
+ 18 | /?ad=qwe&dw=%20%32
+ 12 |
+ 7 | +4.0e-10
+ 12 |
+ 1 | qwe
+ 12 |
+ 1 | qwe
+ 12 |
+ 1 | qwqwe
+ 12 |
+ 20 | 234.435
+ 12 |
+ 22 | 455
+ 12 |
+ 20 | 5.005
+ 12 |
+ 4 | teodor@stack.net
+ 12 |
+ 16 | qwe-wer
+ 11 | qwe
+ 12 | -
+ 11 | wer
+ 12 |
+ 1 | asdf
+ 12 |
+ 13 | <fr>
+ 1 | qwer
+ 12 |
+ 1 | jf
+ 12 |
+ 1 | sdjk
+ 12 | <
+ 1 | we
+ 12 |
+ 1 | hjwer
+ 12 |
+ 13 | <werrwe>
+ 12 |
+ 3 | ewr1
+ 12 | >
+ 3 | ewri2
+ 12 |
+ 13 | <a href="qwe<qwe>">
+ 12 |
+ :
+ 19 | /usr/local/fff
+ 12 |
+ 19 | /awdf/dwqe/4325
+ 12 |
+ 19 | rewt/ewr
+ 12 |
+ 1 | wefjn
+ 12 |
+ 19 | /wqe-324/ewr
+ 12 |
+ 19 | gist.h
+ 12 |
+ 19 | gist.h.c
+ 12 |
+ 19 | gist.c
+ 12 | .
+ 1 | readline
+ 12 |
+ 20 | 4.2
+ 12 |
+ 20 | 4.2
+ 12 | .
+ 20 | 4.2
+ 12 | ,
+ 15 | readline-4.2
+ 11 | readline
+ 12 | -
+ 20 | 4.2
+ 12 |
+ 15 | readline-4.2
+ 11 | readline
+ 12 | -
+ 20 | 4.2
+ 12 | .
+ 22 | 234
+ 12 |
+ :
+ 12 | <
+ 1 | i
+ 12 |
+ 13 | <b>
+ 12 |
+ 1 | wow
+ 12 |
+ 12 | <
+ 1 | jqw
+ 12 |
+ 12 | <>
+ 1 | qwerty
+(135 rows)
+
+select to_tsvector('english', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
+<i <b> wow < jqw <> qwerty');
+ to_tsvector
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ 'ad':17 'dw':19 'jf':39 '234':63 '345':1 '4.2':54,55,56,59,62 '455':31 'jqw':66 'qwe':2,18,27,28,35 'wer':36 'wow':65 'asdf':37 'ewr1':43 'qwer':38 'sdjk':40 '5.005':32 'efd.r':3 'ewri2':44 'hjwer':42 'qwqwe':29 'wefjn':48 'gist.c':52 'gist.h':50 'qwerti':67 '234.435':30 'qwe-wer':34 'readlin':53,58,61 'www.com':4 '+4.0e-10':26 'gist.h.c':51 'rewt/ewr':47 '/?ad=qwe&dw':7,10,14,22 '/wqe-324/ewr':49 'aew.werc.ewr':6 'readline-4.2':57,60 '1aew.werc.ewr':9 '2aew.werc.ewr':11 '3aew.werc.ewr':13 '4aew.werc.ewr':15 '/usr/local/fff':45 '/awdf/dwqe/4325':46 'teodor@stack.net':33 '/?ad=qwe&dw=%20%32':25 '5aew.werc.ewr:8100':16 '6aew.werc.ewr:8100':21 '7aew.werc.ewr:8100':24 'aew.werc.ewr/?ad=qwe&dw':5 '1aew.werc.ewr/?ad=qwe&dw':8 '3aew.werc.ewr/?ad=qwe&dw':12 '6aew.werc.ewr:8100/?ad=qwe&dw':20 '7aew.werc.ewr:8100/?ad=qwe&dw=%20%32':23
+(1 row)
+
+select length(to_tsvector('english', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
+<i <b> wow < jqw <> qwerty'));
+ length
+--------
+ 51
+(1 row)
+
+-- to_tsquery
+select to_tsquery('english', 'qwe & sKies ');
+ to_tsquery
+---------------
+ 'qwe' & 'sky'
+(1 row)
+
+select to_tsquery('simple', 'qwe & sKies ');
+ to_tsquery
+-----------------
+ 'qwe' & 'skies'
+(1 row)
+
+select to_tsquery('english', '''the wether'':dc & '' sKies '':BC ');
+ to_tsquery
+------------------------
+ 'wether':CD & 'sky':BC
+(1 row)
+
+select to_tsquery('english', 'asd&(and|fghj)');
+ to_tsquery
+----------------
+ 'asd' & 'fghj'
+(1 row)
+
+select to_tsquery('english', '(asd&and)|fghj');
+ to_tsquery
+----------------
+ 'asd' | 'fghj'
+(1 row)
+
+select to_tsquery('english', '(asd&!and)|fghj');
+ to_tsquery
+----------------
+ 'asd' | 'fghj'
+(1 row)
+
+select to_tsquery('english', '(the|and&(i&1))&fghj');
+ to_tsquery
+--------------
+ '1' & 'fghj'
+(1 row)
+
+select plainto_tsquery('english', 'the and z 1))& fghj');
+ plainto_tsquery
+--------------------
+ 'z' & '1' & 'fghj'
+(1 row)
+
+select plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd');
+ ?column?
+-----------------------
+ 'foo' & 'bar' & 'asd'
+(1 row)
+
+select plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg');
+ ?column?
+------------------------------
+ 'foo' & 'bar' | 'asd' & 'fg'
+(1 row)
+
+select plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'asd fg');
+ ?column?
+-----------------------------------
+ 'foo' & 'bar' | !( 'asd' & 'fg' )
+(1 row)
+
+select plainto_tsquery('english', 'foo bar') && 'asd | fg';
+ ?column?
+----------------------------------
+ 'foo' & 'bar' & ( 'asd' | 'fg' )
+(1 row)
+
+select ts_rank_cd(to_tsvector('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+'), to_tsquery('english', 'sea&thousand&years'));
+ ts_rank_cd
+------------
+ 0.0555556
+(1 row)
+
+select ts_rank_cd(to_tsvector('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+'), to_tsquery('english', 'granite&sea'));
+ ts_rank_cd
+------------
+ 0.0238095
+(1 row)
+
+select ts_rank_cd(to_tsvector('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+'), to_tsquery('english', 'sea'));
+ ts_rank_cd
+------------
+ 0.2
+(1 row)
+
+--headline tests
+select ts_headline('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+', to_tsquery('english', 'sea&thousand&years'));
+ ts_headline
+--------------------------------------------
+ <b>sea</b> a <b>thousand</b> <b>years</b>,
+ A <b>thousand</b> <b>years</b> to trace
+ The granite features of this cliff
+(1 row)
+
+select ts_headline('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+', to_tsquery('english', 'granite&sea'));
+ ts_headline
+-------------------------------------------
+ <b>sea</b> a thousand years,
+ A thousand years to trace
+ The <b>granite</b> features of this cliff
+(1 row)
+
+select ts_headline('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+', to_tsquery('english', 'sea'));
+ ts_headline
+------------------------------------
+ <b>sea</b> a thousand years,
+ A thousand years to trace
+ The granite features of this cliff
+(1 row)
+
+select ts_headline('english', '
+<html>
+<!-- some comment -->
+<body>
+Sea view wow <u>foo bar</u> <i>qq</i>
+<a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a>
+ff-bg
+<script>
+ document.write(15);
+</script>
+</body>
+</html>',
+to_tsquery('english', 'sea&foo'), 'HighlightAll=true');
+ ts_headline
+-----------------------------------------------------------------------------
+
+ <html>
+ <!-- some comment -->
+ <body>
+ <b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i>
+ <a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a>
+ ff-bg
+ <script>
+ document.write(15);
+ </script>
+ </body>
+ </html>
+(1 row)
+
+--Rewrite sub system
+create table test_tsquery (txtkeyword text, txtsample text);
+\set ECHO none
+alter table test_tsquery add column keyword tsquery;
+update test_tsquery set keyword = to_tsquery('english', txtkeyword);
+alter table test_tsquery add column sample tsquery;
+update test_tsquery set sample = to_tsquery('english', txtsample::text);
+select count(*) from test_tsquery where keyword < 'new & york';
+ count
+-------
+ 1
+(1 row)
+
+select count(*) from test_tsquery where keyword <= 'new & york';
+ count
+-------
+ 2
+(1 row)
+
+select count(*) from test_tsquery where keyword = 'new & york';
+ count
+-------
+ 1
+(1 row)
+
+select count(*) from test_tsquery where keyword >= 'new & york';
+ count
+-------
+ 3
+(1 row)
+
+select count(*) from test_tsquery where keyword > 'new & york';
+ count
+-------
+ 2
+(1 row)
+
+create unique index bt_tsq on test_tsquery (keyword);
+SET enable_seqscan=OFF;
+select count(*) from test_tsquery where keyword < 'new & york';
+ count
+-------
+ 1
+(1 row)
+
+select count(*) from test_tsquery where keyword <= 'new & york';
+ count
+-------
+ 2
+(1 row)
+
+select count(*) from test_tsquery where keyword = 'new & york';
+ count
+-------
+ 1
+(1 row)
+
+select count(*) from test_tsquery where keyword >= 'new & york';
+ count
+-------
+ 3
+(1 row)
+
+select count(*) from test_tsquery where keyword > 'new & york';
+ count
+-------
+ 2
+(1 row)
+
+RESET enable_seqscan;
+select ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city');
+ ts_rewrite
+----------------------------------------------------------------------------------
+ 'foo' & 'bar' & 'qq' & ( 'city' & 'new' & 'york' | ( 'nyc' | 'big' & 'apple' ) )
+(1 row)
+
+select ts_rewrite('moscow', 'select keyword, sample from test_tsquery'::text );
+ ts_rewrite
+---------------------
+ 'moskva' | 'moscow'
+(1 row)
+
+select ts_rewrite('moscow & hotel', 'select keyword, sample from test_tsquery'::text );
+ ts_rewrite
+-----------------------------------
+ ( 'moskva' | 'moscow' ) & 'hotel'
+(1 row)
+
+select ts_rewrite('bar & new & qq & foo & york', 'select keyword, sample from test_tsquery'::text );
+ ts_rewrite
+-------------------------------------------------------------------------------------
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
+(1 row)
+
+select ts_rewrite( ARRAY['moscow', keyword, sample] ) from test_tsquery;
+ ts_rewrite
+---------------------
+ 'moskva' | 'moscow'
+(1 row)
+
+select ts_rewrite( ARRAY['moscow & hotel', keyword, sample] ) from test_tsquery;
+ ts_rewrite
+-----------------------------------
+ ( 'moskva' | 'moscow' ) & 'hotel'
+(1 row)
+
+select ts_rewrite( ARRAY['bar & new & qq & foo & york', keyword, sample] ) from test_tsquery;
+ ts_rewrite
+-------------------------------------------------------------------------------------
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
+(1 row)
+
+select keyword from test_tsquery where keyword @> 'new';
+ keyword
+----------------
+ 'new' & 'york'
+(1 row)
+
+select keyword from test_tsquery where keyword @> 'moscow';
+ keyword
+----------
+ 'moscow'
+(1 row)
+
+select keyword from test_tsquery where keyword <@ 'new';
+ keyword
+---------
+(0 rows)
+
+select keyword from test_tsquery where keyword <@ 'moscow';
+ keyword
+----------
+ 'moscow'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow') as query where keyword <@ query;
+ ts_rewrite
+---------------------
+ 'moskva' | 'moscow'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow & hotel') as query where keyword <@ query;
+ ts_rewrite
+-----------------------------------
+ ( 'moskva' | 'moscow' ) & 'hotel'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'bar & new & qq & foo & york') as query where keyword <@ query;
+ ts_rewrite
+-------------------------------------------------------------------------------------
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow') as query where query @> keyword;
+ ts_rewrite
+---------------------
+ 'moskva' | 'moscow'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow & hotel') as query where query @> keyword;
+ ts_rewrite
+-----------------------------------
+ ( 'moskva' | 'moscow' ) & 'hotel'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'bar & new & qq & foo & york') as query where query @> keyword;
+ ts_rewrite
+-------------------------------------------------------------------------------------
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
+(1 row)
+
+create index qq on test_tsquery using gist (keyword tsquery_ops);
+SET enable_seqscan=OFF;
+select keyword from test_tsquery where keyword @> 'new';
+ keyword
+----------------
+ 'new' & 'york'
+(1 row)
+
+select keyword from test_tsquery where keyword @> 'moscow';
+ keyword
+----------
+ 'moscow'
+(1 row)
+
+select keyword from test_tsquery where keyword <@ 'new';
+ keyword
+---------
+(0 rows)
+
+select keyword from test_tsquery where keyword <@ 'moscow';
+ keyword
+----------
+ 'moscow'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow') as query where keyword <@ query;
+ ts_rewrite
+---------------------
+ 'moskva' | 'moscow'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow & hotel') as query where keyword <@ query;
+ ts_rewrite
+-----------------------------------
+ ( 'moskva' | 'moscow' ) & 'hotel'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'bar & new & qq & foo & york') as query where keyword <@ query;
+ ts_rewrite
+-------------------------------------------------------------------------------------
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow') as query where query @> keyword;
+ ts_rewrite
+---------------------
+ 'moskva' | 'moscow'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow & hotel') as query where query @> keyword;
+ ts_rewrite
+-----------------------------------
+ ( 'moskva' | 'moscow' ) & 'hotel'
+(1 row)
+
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'bar & new & qq & foo & york') as query where query @> keyword;
+ ts_rewrite
+-------------------------------------------------------------------------------------
+ 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | ( 'big' & 'appl' | 'new' & 'york' ) )
+(1 row)
+
+RESET enable_seqscan;
+--test GUC
+set default_text_search_config=simple;
+select to_tsvector('SKIES My booKs');
+ to_tsvector
+----------------------------
+ 'my':2 'books':3 'skies':1
+(1 row)
+
+select plainto_tsquery('SKIES My booKs');
+ plainto_tsquery
+--------------------------
+ 'skies' & 'my' & 'books'
+(1 row)
+
+select to_tsquery('SKIES & My | booKs');
+ to_tsquery
+--------------------------
+ 'skies' & 'my' | 'books'
+(1 row)
+
+set default_text_search_config=english;
+select to_tsvector('SKIES My booKs');
+ to_tsvector
+------------------
+ 'sky':1 'book':3
+(1 row)
+
+select plainto_tsquery('SKIES My booKs');
+ plainto_tsquery
+-----------------
+ 'sky' & 'book'
+(1 row)
+
+select to_tsquery('SKIES & My | booKs');
+ to_tsquery
+----------------
+ 'sky' | 'book'
+(1 row)
+
+--trigger
+CREATE TRIGGER tsvectorupdate
+BEFORE UPDATE OR INSERT ON test_tsvector
+FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(a, 'pg_catalog.english', t);
+SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
+ count
+-------
+ 0
+(1 row)
+
+INSERT INTO test_tsvector (t) VALUES ('345 qwerty');
+SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
+ count
+-------
+ 1
+(1 row)
+
+UPDATE test_tsvector SET t = null WHERE t = '345 qwerty';
+SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
+ count
+-------
+ 0
+(1 row)
+
+insert into test_tsvector (t) values ('345 qwerty');
+select count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
+ count
+-------
+ 1
+(1 row)
+
diff --git a/src/test/regress/expected/tstypes.out b/src/test/regress/expected/tstypes.out
new file mode 100644
index 00000000000..4167fd49745
--- /dev/null
+++ b/src/test/regress/expected/tstypes.out
@@ -0,0 +1,495 @@
+--Base tsvector test
+SELECT '1'::tsvector;
+ tsvector
+----------
+ '1'
+(1 row)
+
+SELECT '1 '::tsvector;
+ tsvector
+----------
+ '1'
+(1 row)
+
+SELECT ' 1'::tsvector;
+ tsvector
+----------
+ '1'
+(1 row)
+
+SELECT ' 1 '::tsvector;
+ tsvector
+----------
+ '1'
+(1 row)
+
+SELECT '1 2'::tsvector;
+ tsvector
+----------
+ '1' '2'
+(1 row)
+
+SELECT '''1 2'''::tsvector;
+ tsvector
+----------
+ '1 2'
+(1 row)
+
+SELECT E'''1 \\''2'''::tsvector;
+ tsvector
+----------
+ '1 ''2'
+(1 row)
+
+SELECT E'''1 \\''2''3'::tsvector;
+ tsvector
+-------------
+ '3' '1 ''2'
+(1 row)
+
+SELECT E'''1 \\''2'' 3'::tsvector;
+ tsvector
+-------------
+ '3' '1 ''2'
+(1 row)
+
+SELECT E'''1 \\''2'' '' 3'' 4 '::tsvector;
+ tsvector
+------------------
+ '4' ' 3' '1 ''2'
+(1 row)
+
+select '''w'':4A,3B,2C,1D,5 a:8';
+ ?column?
+-----------------------
+ 'w':4A,3B,2C,1D,5 a:8
+(1 row)
+
+select 'a:3A b:2a'::tsvector || 'ba:1234 a:1B';
+ ?column?
+----------------------------
+ 'a':3A,4B 'b':2A 'ba':1237
+(1 row)
+
+select setweight('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd zxc:81,567,222A'::tsvector, 'c');
+ setweight
+----------------------------------------------------------
+ 'a':1C,3C 'w':5C,6C,12C,13C 'asd':1C 'zxc':81C,222C,567C
+(1 row)
+
+select strip('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd'::tsvector);
+ strip
+---------------
+ 'a' 'w' 'asd'
+(1 row)
+
+--Base tsquery test
+SELECT '1'::tsquery;
+ tsquery
+---------
+ '1'
+(1 row)
+
+SELECT '1 '::tsquery;
+ tsquery
+---------
+ '1'
+(1 row)
+
+SELECT ' 1'::tsquery;
+ tsquery
+---------
+ '1'
+(1 row)
+
+SELECT ' 1 '::tsquery;
+ tsquery
+---------
+ '1'
+(1 row)
+
+SELECT '''1 2'''::tsquery;
+ tsquery
+---------
+ '1 2'
+(1 row)
+
+SELECT E'''1 \\''2'''::tsquery;
+ tsquery
+---------
+ '1 ''2'
+(1 row)
+
+SELECT '!1'::tsquery;
+ tsquery
+---------
+ !'1'
+(1 row)
+
+SELECT '1|2'::tsquery;
+ tsquery
+-----------
+ '1' | '2'
+(1 row)
+
+SELECT '1|!2'::tsquery;
+ tsquery
+------------
+ '1' | !'2'
+(1 row)
+
+SELECT '!1|2'::tsquery;
+ tsquery
+------------
+ !'1' | '2'
+(1 row)
+
+SELECT '!1|!2'::tsquery;
+ tsquery
+-------------
+ !'1' | !'2'
+(1 row)
+
+SELECT '!(!1|!2)'::tsquery;
+ tsquery
+------------------
+ !( !'1' | !'2' )
+(1 row)
+
+SELECT '!(!1|2)'::tsquery;
+ tsquery
+-----------------
+ !( !'1' | '2' )
+(1 row)
+
+SELECT '!(1|!2)'::tsquery;
+ tsquery
+-----------------
+ !( '1' | !'2' )
+(1 row)
+
+SELECT '!(1|2)'::tsquery;
+ tsquery
+----------------
+ !( '1' | '2' )
+(1 row)
+
+SELECT '1&2'::tsquery;
+ tsquery
+-----------
+ '1' & '2'
+(1 row)
+
+SELECT '!1&2'::tsquery;
+ tsquery
+------------
+ !'1' & '2'
+(1 row)
+
+SELECT '1&!2'::tsquery;
+ tsquery
+------------
+ '1' & !'2'
+(1 row)
+
+SELECT '!1&!2'::tsquery;
+ tsquery
+-------------
+ !'1' & !'2'
+(1 row)
+
+SELECT '(1&2)'::tsquery;
+ tsquery
+-----------
+ '1' & '2'
+(1 row)
+
+SELECT '1&(2)'::tsquery;
+ tsquery
+-----------
+ '1' & '2'
+(1 row)
+
+SELECT '!(1)&2'::tsquery;
+ tsquery
+------------
+ !'1' & '2'
+(1 row)
+
+SELECT '!(1&2)'::tsquery;
+ tsquery
+----------------
+ !( '1' & '2' )
+(1 row)
+
+SELECT '1|2&3'::tsquery;
+ tsquery
+-----------------
+ '1' | '2' & '3'
+(1 row)
+
+SELECT '1|(2&3)'::tsquery;
+ tsquery
+-----------------
+ '1' | '2' & '3'
+(1 row)
+
+SELECT '(1|2)&3'::tsquery;
+ tsquery
+---------------------
+ ( '1' | '2' ) & '3'
+(1 row)
+
+SELECT '1|2&!3'::tsquery;
+ tsquery
+------------------
+ '1' | '2' & !'3'
+(1 row)
+
+SELECT '1|!2&3'::tsquery;
+ tsquery
+------------------
+ '1' | !'2' & '3'
+(1 row)
+
+SELECT '!1|2&3'::tsquery;
+ tsquery
+------------------
+ !'1' | '2' & '3'
+(1 row)
+
+SELECT '!1|(2&3)'::tsquery;
+ tsquery
+------------------
+ !'1' | '2' & '3'
+(1 row)
+
+SELECT '!(1|2)&3'::tsquery;
+ tsquery
+----------------------
+ !( '1' | '2' ) & '3'
+(1 row)
+
+SELECT '(!1|2)&3'::tsquery;
+ tsquery
+----------------------
+ ( !'1' | '2' ) & '3'
+(1 row)
+
+SELECT '1|(2|(4|(5|6)))'::tsquery;
+ tsquery
+-----------------------------------------
+ '1' | ( '2' | ( '4' | ( '5' | '6' ) ) )
+(1 row)
+
+SELECT '1|2|4|5|6'::tsquery;
+ tsquery
+-----------------------------------------
+ ( ( ( '1' | '2' ) | '4' ) | '5' ) | '6'
+(1 row)
+
+SELECT '1&(2&(4&(5&6)))'::tsquery;
+ tsquery
+-----------------------------
+ '1' & '2' & '4' & '5' & '6'
+(1 row)
+
+SELECT '1&2&4&5&6'::tsquery;
+ tsquery
+-----------------------------
+ '1' & '2' & '4' & '5' & '6'
+(1 row)
+
+SELECT '1&(2&(4&(5|6)))'::tsquery;
+ tsquery
+---------------------------------
+ '1' & '2' & '4' & ( '5' | '6' )
+(1 row)
+
+SELECT '1&(2&(4&(5|!6)))'::tsquery;
+ tsquery
+----------------------------------
+ '1' & '2' & '4' & ( '5' | !'6' )
+(1 row)
+
+SELECT E'1&(''2''&('' 4''&(\\|5 | ''6 \\'' !|&'')))'::tsquery;
+ tsquery
+------------------------------------------
+ '1' & '2' & ' 4' & ( '|5' | '6 '' !|&' )
+(1 row)
+
+select 'a' < 'b & c'::tsquery as "true";
+ true
+------
+ t
+(1 row)
+
+select 'a' > 'b & c'::tsquery as "false";
+ false
+-------
+ f
+(1 row)
+
+select 'a | f' < 'b & c'::tsquery as "true";
+ true
+------
+ t
+(1 row)
+
+select 'a | ff' < 'b & c'::tsquery as "false";
+ false
+-------
+ f
+(1 row)
+
+select 'a | f | g' < 'b & c'::tsquery as "false";
+ false
+-------
+ f
+(1 row)
+
+select numnode( 'new'::tsquery );
+ numnode
+---------
+ 1
+(1 row)
+
+select numnode( 'new & york'::tsquery );
+ numnode
+---------
+ 3
+(1 row)
+
+select numnode( 'new & york | qwery'::tsquery );
+ numnode
+---------
+ 5
+(1 row)
+
+select 'foo & bar'::tsquery && 'asd';
+ ?column?
+-----------------------
+ 'foo' & 'bar' & 'asd'
+(1 row)
+
+select 'foo & bar'::tsquery || 'asd & fg';
+ ?column?
+------------------------------
+ 'foo' & 'bar' | 'asd' & 'fg'
+(1 row)
+
+select 'foo & bar'::tsquery || !!'asd & fg'::tsquery;
+ ?column?
+-----------------------------------
+ 'foo' & 'bar' | !( 'asd' & 'fg' )
+(1 row)
+
+select 'foo & bar'::tsquery && 'asd | fg';
+ ?column?
+----------------------------------
+ 'foo' & 'bar' & ( 'asd' | 'fg' )
+(1 row)
+
+-- tsvector-tsquery operations
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca' as "true";
+ true
+------
+ t
+(1 row)
+
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:B' as "true";
+ true
+------
+ t
+(1 row)
+
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:A' as "true";
+ true
+------
+ t
+(1 row)
+
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:C' as "false";
+ false
+-------
+ f
+(1 row)
+
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:CB' as "true";
+ true
+------
+ t
+(1 row)
+
+select ts_rank(' a:1 s:2C d g'::tsvector, 'a | s');
+ ts_rank
+-----------
+ 0.0911891
+(1 row)
+
+select ts_rank(' a:1 s:2B d g'::tsvector, 'a | s');
+ ts_rank
+----------
+ 0.151982
+(1 row)
+
+select ts_rank(' a:1 s:2 d g'::tsvector, 'a | s');
+ ts_rank
+-----------
+ 0.0607927
+(1 row)
+
+select ts_rank(' a:1 s:2C d g'::tsvector, 'a & s');
+ ts_rank
+----------
+ 0.140153
+(1 row)
+
+select ts_rank(' a:1 s:2B d g'::tsvector, 'a & s');
+ ts_rank
+----------
+ 0.198206
+(1 row)
+
+select ts_rank(' a:1 s:2 d g'::tsvector, 'a & s');
+ ts_rank
+-----------
+ 0.0991032
+(1 row)
+
+select ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a | s');
+ ts_rank_cd
+------------
+ 0.3
+(1 row)
+
+select ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a | s');
+ ts_rank_cd
+------------
+ 0.5
+(1 row)
+
+select ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a | s');
+ ts_rank_cd
+------------
+ 0.2
+(1 row)
+
+select ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a & s');
+ ts_rank_cd
+------------
+ 0.133333
+(1 row)
+
+select ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a & s');
+ ts_rank_cd
+------------
+ 0.16
+(1 row)
+
+select ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a & s');
+ ts_rank_cd
+------------
+ 0.1
+(1 row)
+
diff --git a/src/test/regress/input/copy.source b/src/test/regress/input/copy.source
index 326f1b84b62..376329d250d 100644
--- a/src/test/regress/input/copy.source
+++ b/src/test/regress/input/copy.source
@@ -39,6 +39,8 @@ COPY hash_txt_heap FROM '@abs_srcdir@/data/hash.data';
COPY hash_f8_heap FROM '@abs_srcdir@/data/hash.data';
+COPY test_tsvector FROM '@abs_srcdir@/data/tsearch.data';
+
-- the data in this file has a lot of duplicates in the index key
-- fields, leading to long bucket chains and lots of table expansion.
-- this is therefore a stress test of the bucket overflow code (unlike
diff --git a/src/test/regress/output/copy.source b/src/test/regress/output/copy.source
index 527c2a80285..5a88d6ef20a 100644
--- a/src/test/regress/output/copy.source
+++ b/src/test/regress/output/copy.source
@@ -21,6 +21,7 @@ COPY hash_i4_heap FROM '@abs_srcdir@/data/hash.data';
COPY hash_name_heap FROM '@abs_srcdir@/data/hash.data';
COPY hash_txt_heap FROM '@abs_srcdir@/data/hash.data';
COPY hash_f8_heap FROM '@abs_srcdir@/data/hash.data';
+COPY test_tsvector FROM '@abs_srcdir@/data/tsearch.data';
-- the data in this file has a lot of duplicates in the index key
-- fields, leading to long bucket chains and lots of table expansion.
-- this is therefore a stress test of the bucket overflow code (unlike
diff --git a/src/test/regress/output/misc.source b/src/test/regress/output/misc.source
index d4201a1fcac..7aac0461be2 100644
--- a/src/test/regress/output/misc.source
+++ b/src/test/regress/output/misc.source
@@ -656,6 +656,7 @@ SELECT user_relns() AS user_relns
subselect_tbl
tenk1
tenk2
+ test_tsvector
text_tbl
time_tbl
timestamp_tbl
@@ -665,7 +666,7 @@ SELECT user_relns() AS user_relns
toyemp
varchar_tbl
xacttest
-(99 rows)
+(100 rows)
SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer')));
name
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index b7cc56c6213..a8f5c799d9a 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -1,6 +1,12 @@
# ----------
-# The first group of parallel test
-# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.42 2007/04/02 03:49:42 tgl Exp $
+# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.43 2007/08/21 01:11:30 tgl Exp $
+#
+# By convention, we put no more than twenty tests in any one parallel group;
+# this limits the number of connections needed to run the tests.
+# ----------
+
+# ----------
+# The first group of parallel tests
# ----------
test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric uuid enum
@@ -10,14 +16,16 @@ test: strings
test: numerology
# ----------
-# The second group of parallel test
+# The second group of parallel tests
# ----------
-test: point lseg box path polygon circle date time timetz timestamp timestamptz interval abstime reltime tinterval inet comments oidjoins type_sanity opr_sanity
+test: point lseg box path polygon circle date time timetz timestamp timestamptz interval abstime reltime tinterval inet tstypes comments
-# Depends on point, lseg, box, path, polygon and circle
-test: geometry
-# Depends on interval, timetz, timestamp, timestamptz, reltime and abstime
-test: horology
+# ----------
+# Another group of parallel tests
+# geometry depends on point, lseg, box, path, polygon and circle
+# horology depends on interval, timetz, timestamp, timestamptz, reltime and abstime
+# ----------
+test: geometry horology oidjoins type_sanity opr_sanity
# ----------
# These four each depend on the previous one
@@ -37,7 +45,7 @@ test: create_function_2
test: copy copyselect
# ----------
-# The third group of parallel test
+# Another group of parallel tests
# ----------
test: constraints triggers create_misc create_aggregate create_operator inherit vacuum drop_if_exists
@@ -59,7 +67,7 @@ test: select
ignore: random
# ----------
-# The fourth group of parallel test
+# Another group of parallel tests
# ----------
test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete
@@ -67,12 +75,12 @@ test: privileges
test: misc
# ----------
-# The fifth group of parallel test
+# Another group of parallel tests
# ----------
-test: select_views portals_p2 rules foreign_key cluster dependency guc combocid
+test: select_views portals_p2 rules foreign_key cluster dependency guc combocid tsearch
# ----------
-# The sixth group of parallel test
+# Another group of parallel tests
# ----------
# "plpgsql" cannot run concurrently with "rules", nor can "plancache"
test: plancache limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning largeobject xml
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 85c03f33c9e..a11a8702334 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -1,4 +1,4 @@
-# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.39 2007/04/02 03:49:42 tgl Exp $
+# $PostgreSQL: pgsql/src/test/regress/serial_schedule,v 1.40 2007/08/21 01:11:30 tgl Exp $
# This should probably be in an order similar to parallel_schedule.
test: boolean
test: char
@@ -33,12 +33,13 @@ test: abstime
test: reltime
test: tinterval
test: inet
+test: tstypes
test: comments
+test: geometry
+test: horology
test: oidjoins
test: type_sanity
test: opr_sanity
-test: geometry
-test: horology
test: insert
test: create_function_1
test: create_type
@@ -90,6 +91,7 @@ test: cluster
test: dependency
test: guc
test: combocid
+test: tsearch
test: plancache
test: limit
test: plpgsql
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index 21efae2d55b..e43371eed93 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -231,3 +231,9 @@ CREATE TABLE array_index_op_test (
i int4[],
t text[]
);
+
+CREATE TABLE test_tsvector(
+ t text,
+ a tsvector
+);
+
diff --git a/src/test/regress/sql/oidjoins.sql b/src/test/regress/sql/oidjoins.sql
index 7d2dd3dd1fc..773c2afe7fa 100644
--- a/src/test/regress/sql/oidjoins.sql
+++ b/src/test/regress/sql/oidjoins.sql
@@ -349,6 +349,74 @@ SELECT ctid, tgfoid
FROM pg_catalog.pg_trigger fk
WHERE tgfoid != 0 AND
NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tgfoid);
+SELECT ctid, cfgnamespace
+FROM pg_catalog.pg_ts_config fk
+WHERE cfgnamespace != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.cfgnamespace);
+SELECT ctid, cfgowner
+FROM pg_catalog.pg_ts_config fk
+WHERE cfgowner != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.cfgowner);
+SELECT ctid, cfgparser
+FROM pg_catalog.pg_ts_config fk
+WHERE cfgparser != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_parser pk WHERE pk.oid = fk.cfgparser);
+SELECT ctid, mapcfg
+FROM pg_catalog.pg_ts_config_map fk
+WHERE mapcfg != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_config pk WHERE pk.oid = fk.mapcfg);
+SELECT ctid, mapdict
+FROM pg_catalog.pg_ts_config_map fk
+WHERE mapdict != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_dict pk WHERE pk.oid = fk.mapdict);
+SELECT ctid, dictnamespace
+FROM pg_catalog.pg_ts_dict fk
+WHERE dictnamespace != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.dictnamespace);
+SELECT ctid, dictowner
+FROM pg_catalog.pg_ts_dict fk
+WHERE dictowner != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.dictowner);
+SELECT ctid, dicttemplate
+FROM pg_catalog.pg_ts_dict fk
+WHERE dicttemplate != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_ts_template pk WHERE pk.oid = fk.dicttemplate);
+SELECT ctid, prsnamespace
+FROM pg_catalog.pg_ts_parser fk
+WHERE prsnamespace != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.prsnamespace);
+SELECT ctid, prsstart
+FROM pg_catalog.pg_ts_parser fk
+WHERE prsstart != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsstart);
+SELECT ctid, prstoken
+FROM pg_catalog.pg_ts_parser fk
+WHERE prstoken != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prstoken);
+SELECT ctid, prsend
+FROM pg_catalog.pg_ts_parser fk
+WHERE prsend != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsend);
+SELECT ctid, prsheadline
+FROM pg_catalog.pg_ts_parser fk
+WHERE prsheadline != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prsheadline);
+SELECT ctid, prslextype
+FROM pg_catalog.pg_ts_parser fk
+WHERE prslextype != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prslextype);
+SELECT ctid, tmplnamespace
+FROM pg_catalog.pg_ts_template fk
+WHERE tmplnamespace != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_namespace pk WHERE pk.oid = fk.tmplnamespace);
+SELECT ctid, tmplinit
+FROM pg_catalog.pg_ts_template fk
+WHERE tmplinit != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tmplinit);
+SELECT ctid, tmpllexize
+FROM pg_catalog.pg_ts_template fk
+WHERE tmpllexize != 0 AND
+ NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.tmpllexize);
SELECT ctid, typnamespace
FROM pg_catalog.pg_type fk
WHERE typnamespace != 0 AND
diff --git a/src/test/regress/sql/tsearch.sql b/src/test/regress/sql/tsearch.sql
new file mode 100644
index 00000000000..2e257fff3f5
--- /dev/null
+++ b/src/test/regress/sql/tsearch.sql
@@ -0,0 +1,292 @@
+--
+-- Sanity checks for text search catalogs
+--
+-- NB: we assume the oidjoins test will have caught any dangling links,
+-- that is OID or REGPROC fields that are not zero and do not match some
+-- row in the linked-to table. However, if we want to enforce that a link
+-- field can't be 0, we have to check it here.
+
+-- Find unexpected zero link entries
+
+SELECT oid, prsname
+FROM pg_ts_parser
+WHERE prsnamespace = 0 OR prsstart = 0 OR prstoken = 0 OR prsend = 0 OR
+ -- prsheadline is optional
+ prslextype = 0;
+
+SELECT oid, dictname
+FROM pg_ts_dict
+WHERE dictnamespace = 0 OR dictowner = 0 OR dicttemplate = 0;
+
+SELECT oid, tmplname
+FROM pg_ts_template
+WHERE tmplnamespace = 0 OR tmpllexize = 0; -- tmplinit is optional
+
+SELECT oid, cfgname
+FROM pg_ts_config
+WHERE cfgnamespace = 0 OR cfgowner = 0 OR cfgparser = 0;
+
+SELECT mapcfg, maptokentype, mapseqno
+FROM pg_ts_config_map
+WHERE mapcfg = 0 OR mapdict = 0;
+
+-- Look for pg_ts_config_map entries that aren't one of parser's token types
+SELECT * FROM
+ ( SELECT oid AS cfgid, (ts_token_type(cfgparser)).tokid AS tokid
+ FROM pg_ts_config ) AS tt
+RIGHT JOIN pg_ts_config_map AS m
+ ON (tt.cfgid=m.mapcfg AND tt.tokid=m.maptokentype)
+WHERE
+ tt.cfgid IS NULL OR tt.tokid IS NULL;
+
+-- test basic text search behavior without indexes, then with
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
+
+create index wowidx on test_tsvector using gist (a);
+
+SET enable_seqscan=OFF;
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
+
+RESET enable_seqscan;
+
+drop index wowidx;
+
+create index wowidx on test_tsvector using gin (a);
+
+SET enable_seqscan=OFF;
+
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt';
+SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt';
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)';
+SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)';
+
+RESET enable_seqscan;
+insert into test_tsvector values ('???', 'DFG:1A,2B,6C,10 FGH');
+select * from ts_stat('select a from test_tsvector') order by ndoc desc, nentry desc, word limit 10;
+select * from ts_stat('select a from test_tsvector', 'AB') order by ndoc desc, nentry desc, word;
+
+--dictionaries and to_tsvector
+
+select ts_lexize('english', 'skies');
+select ts_lexize('english', 'identity');
+
+select * from ts_token_type('default');
+
+select * from ts_parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
+<i <b> wow < jqw <> qwerty');
+
+select to_tsvector('english', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
+<i <b> wow < jqw <> qwerty');
+
+select length(to_tsvector('english', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf <fr>qwer jf sdjk<we hjwer <werrwe> ewr1> ewri2 <a href="qwe<qwe>">
+/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234
+<i <b> wow < jqw <> qwerty'));
+
+-- to_tsquery
+
+select to_tsquery('english', 'qwe & sKies ');
+select to_tsquery('simple', 'qwe & sKies ');
+select to_tsquery('english', '''the wether'':dc & '' sKies '':BC ');
+select to_tsquery('english', 'asd&(and|fghj)');
+select to_tsquery('english', '(asd&and)|fghj');
+select to_tsquery('english', '(asd&!and)|fghj');
+select to_tsquery('english', '(the|and&(i&1))&fghj');
+
+select plainto_tsquery('english', 'the and z 1))& fghj');
+select plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd');
+select plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg');
+select plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'asd fg');
+select plainto_tsquery('english', 'foo bar') && 'asd | fg';
+
+select ts_rank_cd(to_tsvector('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+'), to_tsquery('english', 'sea&thousand&years'));
+
+select ts_rank_cd(to_tsvector('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+'), to_tsquery('english', 'granite&sea'));
+
+select ts_rank_cd(to_tsvector('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+'), to_tsquery('english', 'sea'));
+
+--headline tests
+select ts_headline('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+', to_tsquery('english', 'sea&thousand&years'));
+
+select ts_headline('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+', to_tsquery('english', 'granite&sea'));
+
+select ts_headline('english', 'Erosion It took the sea a thousand years,
+A thousand years to trace
+The granite features of this cliff
+In crag and scarp and base.
+It took the sea an hour one night
+An hour of storm to place
+The sculpture of these granite seams,
+Upon a woman s face. E. J. Pratt (1882 1964)
+', to_tsquery('english', 'sea'));
+
+select ts_headline('english', '
+<html>
+<!-- some comment -->
+<body>
+Sea view wow <u>foo bar</u> <i>qq</i>
+<a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a>
+ff-bg
+<script>
+ document.write(15);
+</script>
+</body>
+</html>',
+to_tsquery('english', 'sea&foo'), 'HighlightAll=true');
+
+--Rewrite sub system
+
+create table test_tsquery (txtkeyword text, txtsample text);
+\set ECHO none
+\copy test_tsquery from stdin
+'New York' new & york | big & apple | nyc
+Moscow moskva | moscow
+'Sanct Peter' Peterburg | peter | 'Sanct Peterburg'
+'foo bar qq' foo & (bar | qq) & city
+\.
+\set ECHO all
+
+alter table test_tsquery add column keyword tsquery;
+update test_tsquery set keyword = to_tsquery('english', txtkeyword);
+alter table test_tsquery add column sample tsquery;
+update test_tsquery set sample = to_tsquery('english', txtsample::text);
+
+
+select count(*) from test_tsquery where keyword < 'new & york';
+select count(*) from test_tsquery where keyword <= 'new & york';
+select count(*) from test_tsquery where keyword = 'new & york';
+select count(*) from test_tsquery where keyword >= 'new & york';
+select count(*) from test_tsquery where keyword > 'new & york';
+
+create unique index bt_tsq on test_tsquery (keyword);
+
+SET enable_seqscan=OFF;
+
+select count(*) from test_tsquery where keyword < 'new & york';
+select count(*) from test_tsquery where keyword <= 'new & york';
+select count(*) from test_tsquery where keyword = 'new & york';
+select count(*) from test_tsquery where keyword >= 'new & york';
+select count(*) from test_tsquery where keyword > 'new & york';
+
+RESET enable_seqscan;
+
+select ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city');
+
+select ts_rewrite('moscow', 'select keyword, sample from test_tsquery'::text );
+select ts_rewrite('moscow & hotel', 'select keyword, sample from test_tsquery'::text );
+select ts_rewrite('bar & new & qq & foo & york', 'select keyword, sample from test_tsquery'::text );
+
+select ts_rewrite( ARRAY['moscow', keyword, sample] ) from test_tsquery;
+select ts_rewrite( ARRAY['moscow & hotel', keyword, sample] ) from test_tsquery;
+select ts_rewrite( ARRAY['bar & new & qq & foo & york', keyword, sample] ) from test_tsquery;
+
+
+select keyword from test_tsquery where keyword @> 'new';
+select keyword from test_tsquery where keyword @> 'moscow';
+select keyword from test_tsquery where keyword <@ 'new';
+select keyword from test_tsquery where keyword <@ 'moscow';
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow') as query where keyword <@ query;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow & hotel') as query where keyword <@ query;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'bar & new & qq & foo & york') as query where keyword <@ query;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow') as query where query @> keyword;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow & hotel') as query where query @> keyword;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'bar & new & qq & foo & york') as query where query @> keyword;
+
+create index qq on test_tsquery using gist (keyword tsquery_ops);
+SET enable_seqscan=OFF;
+
+select keyword from test_tsquery where keyword @> 'new';
+select keyword from test_tsquery where keyword @> 'moscow';
+select keyword from test_tsquery where keyword <@ 'new';
+select keyword from test_tsquery where keyword <@ 'moscow';
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow') as query where keyword <@ query;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow & hotel') as query where keyword <@ query;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'bar & new & qq & foo & york') as query where keyword <@ query;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow') as query where query @> keyword;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'moscow & hotel') as query where query @> keyword;
+select ts_rewrite( ARRAY[query, keyword, sample] ) from test_tsquery, to_tsquery('english', 'bar & new & qq & foo & york') as query where query @> keyword;
+
+RESET enable_seqscan;
+
+--test GUC
+set default_text_search_config=simple;
+
+select to_tsvector('SKIES My booKs');
+select plainto_tsquery('SKIES My booKs');
+select to_tsquery('SKIES & My | booKs');
+
+set default_text_search_config=english;
+
+select to_tsvector('SKIES My booKs');
+select plainto_tsquery('SKIES My booKs');
+select to_tsquery('SKIES & My | booKs');
+
+--trigger
+CREATE TRIGGER tsvectorupdate
+BEFORE UPDATE OR INSERT ON test_tsvector
+FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(a, 'pg_catalog.english', t);
+
+SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
+INSERT INTO test_tsvector (t) VALUES ('345 qwerty');
+SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
+UPDATE test_tsvector SET t = null WHERE t = '345 qwerty';
+SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
+
+insert into test_tsvector (t) values ('345 qwerty');
+
+select count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty');
diff --git a/src/test/regress/sql/tstypes.sql b/src/test/regress/sql/tstypes.sql
new file mode 100644
index 00000000000..29a699f90c4
--- /dev/null
+++ b/src/test/regress/sql/tstypes.sql
@@ -0,0 +1,95 @@
+--Base tsvector test
+
+SELECT '1'::tsvector;
+SELECT '1 '::tsvector;
+SELECT ' 1'::tsvector;
+SELECT ' 1 '::tsvector;
+SELECT '1 2'::tsvector;
+SELECT '''1 2'''::tsvector;
+SELECT E'''1 \\''2'''::tsvector;
+SELECT E'''1 \\''2''3'::tsvector;
+SELECT E'''1 \\''2'' 3'::tsvector;
+SELECT E'''1 \\''2'' '' 3'' 4 '::tsvector;
+select '''w'':4A,3B,2C,1D,5 a:8';
+select 'a:3A b:2a'::tsvector || 'ba:1234 a:1B';
+select setweight('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd zxc:81,567,222A'::tsvector, 'c');
+select strip('w:12B w:13* w:12,5,6 a:1,3* a:3 w asd:1dc asd'::tsvector);
+
+--Base tsquery test
+SELECT '1'::tsquery;
+SELECT '1 '::tsquery;
+SELECT ' 1'::tsquery;
+SELECT ' 1 '::tsquery;
+SELECT '''1 2'''::tsquery;
+SELECT E'''1 \\''2'''::tsquery;
+SELECT '!1'::tsquery;
+SELECT '1|2'::tsquery;
+SELECT '1|!2'::tsquery;
+SELECT '!1|2'::tsquery;
+SELECT '!1|!2'::tsquery;
+SELECT '!(!1|!2)'::tsquery;
+SELECT '!(!1|2)'::tsquery;
+SELECT '!(1|!2)'::tsquery;
+SELECT '!(1|2)'::tsquery;
+SELECT '1&2'::tsquery;
+SELECT '!1&2'::tsquery;
+SELECT '1&!2'::tsquery;
+SELECT '!1&!2'::tsquery;
+SELECT '(1&2)'::tsquery;
+SELECT '1&(2)'::tsquery;
+SELECT '!(1)&2'::tsquery;
+SELECT '!(1&2)'::tsquery;
+SELECT '1|2&3'::tsquery;
+SELECT '1|(2&3)'::tsquery;
+SELECT '(1|2)&3'::tsquery;
+SELECT '1|2&!3'::tsquery;
+SELECT '1|!2&3'::tsquery;
+SELECT '!1|2&3'::tsquery;
+SELECT '!1|(2&3)'::tsquery;
+SELECT '!(1|2)&3'::tsquery;
+SELECT '(!1|2)&3'::tsquery;
+SELECT '1|(2|(4|(5|6)))'::tsquery;
+SELECT '1|2|4|5|6'::tsquery;
+SELECT '1&(2&(4&(5&6)))'::tsquery;
+SELECT '1&2&4&5&6'::tsquery;
+SELECT '1&(2&(4&(5|6)))'::tsquery;
+SELECT '1&(2&(4&(5|!6)))'::tsquery;
+SELECT E'1&(''2''&('' 4''&(\\|5 | ''6 \\'' !|&'')))'::tsquery;
+
+select 'a' < 'b & c'::tsquery as "true";
+select 'a' > 'b & c'::tsquery as "false";
+select 'a | f' < 'b & c'::tsquery as "true";
+select 'a | ff' < 'b & c'::tsquery as "false";
+select 'a | f | g' < 'b & c'::tsquery as "false";
+
+select numnode( 'new'::tsquery );
+select numnode( 'new & york'::tsquery );
+select numnode( 'new & york | qwery'::tsquery );
+
+select 'foo & bar'::tsquery && 'asd';
+select 'foo & bar'::tsquery || 'asd & fg';
+select 'foo & bar'::tsquery || !!'asd & fg'::tsquery;
+select 'foo & bar'::tsquery && 'asd | fg';
+
+-- tsvector-tsquery operations
+
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca' as "true";
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:B' as "true";
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:A' as "true";
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:C' as "false";
+select 'a b:89 ca:23A,64b d:34c'::tsvector @@ 'd:AC & ca:CB' as "true";
+
+select ts_rank(' a:1 s:2C d g'::tsvector, 'a | s');
+select ts_rank(' a:1 s:2B d g'::tsvector, 'a | s');
+select ts_rank(' a:1 s:2 d g'::tsvector, 'a | s');
+select ts_rank(' a:1 s:2C d g'::tsvector, 'a & s');
+select ts_rank(' a:1 s:2B d g'::tsvector, 'a & s');
+select ts_rank(' a:1 s:2 d g'::tsvector, 'a & s');
+
+select ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a | s');
+select ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a | s');
+select ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a | s');
+select ts_rank_cd(' a:1 s:2C d g'::tsvector, 'a & s');
+select ts_rank_cd(' a:1 s:2B d g'::tsvector, 'a & s');
+select ts_rank_cd(' a:1 s:2 d g'::tsvector, 'a & s');
+
diff --git a/src/tools/findoidjoins/findoidjoins.c b/src/tools/findoidjoins/findoidjoins.c
index 19522c9b1cd..6d42f12c8ba 100644
--- a/src/tools/findoidjoins/findoidjoins.c
+++ b/src/tools/findoidjoins/findoidjoins.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-2007, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/tools/findoidjoins/findoidjoins.c,v 1.4 2007/01/05 22:20:04 momjian Exp $
+ * $PostgreSQL: pgsql/src/tools/findoidjoins/findoidjoins.c,v 1.5 2007/08/21 01:11:32 tgl Exp $
*/
#include "postgres_fe.h"
@@ -83,7 +83,9 @@ main(int argc, char **argv)
" 'pg_catalog.regoperator'::regtype, "
" 'pg_catalog.regproc'::regtype, "
" 'pg_catalog.regprocedure'::regtype, "
- " 'pg_catalog.regtype'::regtype) "
+ " 'pg_catalog.regtype'::regtype, "
+ " 'pg_catalog.regconfig'::regtype, "
+ " 'pg_catalog.regdictionary'::regtype) "
"ORDER BY nspname, c.relname, a.attnum"
);