aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/tsearch/dict_synonym.c11
-rw-r--r--src/backend/tsearch/dict_thesaurus.c33
-rw-r--r--src/backend/tsearch/spell.c97
-rw-r--r--src/backend/tsearch/ts_locale.c105
-rw-r--r--src/backend/tsearch/ts_utils.c11
-rw-r--r--src/include/tsearch/ts_locale.h18
6 files changed, 178 insertions, 97 deletions
diff --git a/src/backend/tsearch/dict_synonym.c b/src/backend/tsearch/dict_synonym.c
index 6f263603d7a..8558602ace2 100644
--- a/src/backend/tsearch/dict_synonym.c
+++ b/src/backend/tsearch/dict_synonym.c
@@ -7,14 +7,13 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tsearch/dict_synonym.c,v 1.8 2008/03/10 03:01:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tsearch/dict_synonym.c,v 1.9 2008/06/18 20:55:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "commands/defrem.h"
-#include "storage/fd.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_public.h"
#include "tsearch/ts_utils.h"
@@ -79,7 +78,7 @@ dsynonym_init(PG_FUNCTION_ARGS)
ListCell *l;
char *filename = NULL;
bool case_sensitive = false;
- FILE *fin;
+ tsearch_readline_state trst;
char *starti,
*starto,
*end = NULL;
@@ -108,7 +107,7 @@ dsynonym_init(PG_FUNCTION_ARGS)
filename = get_tsearch_config_filename(filename, "syn");
- if ((fin = AllocateFile(filename, "r")) == NULL)
+ if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open synonym file \"%s\": %m",
@@ -116,7 +115,7 @@ dsynonym_init(PG_FUNCTION_ARGS)
d = (DictSyn *) palloc0(sizeof(DictSyn));
- while ((line = t_readline(fin)) != NULL)
+ while ((line = tsearch_readline(&trst)) != NULL)
{
starti = findwrd(line, &end);
if (!starti)
@@ -175,7 +174,7 @@ skipline:
pfree(line);
}
- FreeFile(fin);
+ tsearch_readline_end(&trst);
d->len = cur;
qsort(d->syn, d->len, sizeof(Syn), compareSyn);
diff --git a/src/backend/tsearch/dict_thesaurus.c b/src/backend/tsearch/dict_thesaurus.c
index 6fcffa74573..0f9c133f2e5 100644
--- a/src/backend/tsearch/dict_thesaurus.c
+++ b/src/backend/tsearch/dict_thesaurus.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tsearch/dict_thesaurus.c,v 1.11 2008/01/01 19:45:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/tsearch/dict_thesaurus.c,v 1.12 2008/06/18 20:55:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,7 +15,6 @@
#include "catalog/namespace.h"
#include "commands/defrem.h"
-#include "storage/fd.h"
#include "tsearch/ts_cache.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_public.h"
@@ -169,21 +168,19 @@ addWrd(DictThesaurus *d, char *b, char *e, uint16 idsubst, uint16 nwrd, uint16 p
static void
thesaurusRead(char *filename, DictThesaurus *d)
{
- FILE *fh;
- int lineno = 0;
+ tsearch_readline_state trst;
uint16 idsubst = 0;
bool useasis = false;
char *line;
filename = get_tsearch_config_filename(filename, "ths");
- fh = AllocateFile(filename, "r");
- if (!fh)
+ if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open thesaurus file \"%s\": %m",
filename)));
- while ((line = t_readline(fh)) != NULL)
+ while ((line = tsearch_readline(&trst)) != NULL)
{
char *ptr;
int state = TR_WAITLEX;
@@ -191,8 +188,6 @@ thesaurusRead(char *filename, DictThesaurus *d)
uint16 posinsubst = 0;
uint16 nwrd = 0;
- lineno++;
-
ptr = line;
/* is it a comment? */
@@ -213,13 +208,9 @@ thesaurusRead(char *filename, DictThesaurus *d)
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)));
- }
+ errmsg("unexpected delimiter")));
state = TR_WAITSUBS;
}
else if (!t_isspace(ptr))
@@ -269,8 +260,7 @@ thesaurusRead(char *filename, DictThesaurus *d)
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)));
+ errmsg("unexpected end of line or lexeme")));
addWrd(d, beginwrd, ptr, idsubst, nwrd++, posinsubst, useasis);
state = TR_WAITSUBS;
}
@@ -286,28 +276,23 @@ thesaurusRead(char *filename, DictThesaurus *d)
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)));
+ errmsg("unexpected end of line or lexeme")));
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)));
- }
+ errmsg("unexpected end of line")));
pfree(line);
}
d->nsubst = idsubst;
- FreeFile(fh);
+ tsearch_readline_end(&trst);
}
static TheLexeme *
diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c
index a2837d16831..d6e3a081b89 100644
--- a/src/backend/tsearch/spell.c
+++ b/src/backend/tsearch/spell.c
@@ -7,14 +7,13 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.11 2008/01/21 02:46:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tsearch/spell.c,v 1.12 2008/06/18 20:55:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "storage/fd.h"
#include "tsearch/dicts/spell.h"
#include "tsearch/ts_locale.h"
#include "utils/memutils.h"
@@ -194,18 +193,18 @@ NIAddSpell(IspellDict *Conf, const char *word, const char *flag)
void
NIImportDictionary(IspellDict *Conf, const char *filename)
{
- FILE *dict;
+ tsearch_readline_state trst;
char *line;
checkTmpCtx();
- if (!(dict = AllocateFile(filename, "r")))
+ if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open dictionary file \"%s\": %m",
filename)));
- while ((line = t_readline(dict)) != NULL)
+ while ((line = tsearch_readline(&trst)) != NULL)
{
char *s,
*pstr;
@@ -250,7 +249,7 @@ NIImportDictionary(IspellDict *Conf, const char *filename)
pfree(line);
}
- FreeFile(dict);
+ tsearch_readline_end(&trst);
}
@@ -392,8 +391,7 @@ NIAddAffix(IspellDict *Conf, int flag, char flagflags, const char *mask, const c
#define PAE_INREPL 5
static bool
-parse_affentry(char *str, char *mask, char *find, char *repl,
- const char *filename, int lineno)
+parse_affentry(char *str, char *mask, char *find, char *repl)
{
int state = PAE_WAIT_MASK;
char *pmask = mask,
@@ -443,8 +441,7 @@ parse_affentry(char *str, char *mask, char *find, char *repl,
else if (!t_isspace(str))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("syntax error at line %d of affix file \"%s\"",
- lineno, filename)));
+ errmsg("syntax error")));
}
else if (state == PAE_INFIND)
{
@@ -461,8 +458,7 @@ parse_affentry(char *str, char *mask, char *find, char *repl,
else if (!t_isspace(str))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("syntax error at line %d of affix file \"%s\"",
- lineno, filename)));
+ errmsg("syntax error")));
}
else if (state == PAE_WAIT_REPL)
{
@@ -479,8 +475,7 @@ parse_affentry(char *str, char *mask, char *find, char *repl,
else if (!t_isspace(str))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("syntax error at line %d of affix file \"%s\"",
- lineno, filename)));
+ errmsg("syntax error")));
}
else if (state == PAE_INREPL)
{
@@ -497,8 +492,7 @@ parse_affentry(char *str, char *mask, char *find, char *repl,
else if (!t_isspace(str))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("syntax error at line %d of affix file \"%s\"",
- lineno, filename)));
+ errmsg("syntax error")));
}
else
elog(ERROR, "unrecognized state in parse_affentry: %d", state);
@@ -512,8 +506,7 @@ parse_affentry(char *str, char *mask, char *find, char *repl,
}
static void
-addFlagValue(IspellDict *Conf, char *s, uint32 val,
- const char *filename, int lineno)
+addFlagValue(IspellDict *Conf, char *s, uint32 val)
{
while (*s && t_isspace(s))
s++;
@@ -521,14 +514,12 @@ addFlagValue(IspellDict *Conf, char *s, uint32 val,
if (!*s)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("syntax error at line %d of affix file \"%s\"",
- lineno, filename)));
+ errmsg("syntax error")));
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\"",
- lineno, filename)));
+ errmsg("multibyte flag character is not allowed")));
Conf->flagval[(unsigned int) *s] = (unsigned char) val;
Conf->usecompound = true;
@@ -549,8 +540,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
bool isSuffix = false;
int flag = 0;
char flagflags = 0;
- FILE *affix;
- int lineno = 0;
+ tsearch_readline_state trst;
int scanread = 0;
char scanbuf[BUFSIZ];
char *recoded;
@@ -561,16 +551,14 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
memset(Conf->flagval, 0, sizeof(Conf->flagval));
Conf->usecompound = false;
- if (!(affix = AllocateFile(filename, "r")))
+ if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open affix file \"%s\": %m",
filename)));
- while ((recoded = t_readline(affix)) != NULL)
+ while ((recoded = tsearch_readline(&trst)) != NULL)
{
- lineno++;
-
if (*recoded == '\0' || t_isspace(recoded) || t_iseq(recoded, '#'))
{
pfree(recoded);
@@ -579,29 +567,29 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
if (STRNCMP(recoded, "COMPOUNDFLAG") == 0)
addFlagValue(Conf, recoded + strlen("COMPOUNDFLAG"),
- FF_COMPOUNDFLAG, filename, lineno);
+ FF_COMPOUNDFLAG);
else if (STRNCMP(recoded, "COMPOUNDBEGIN") == 0)
addFlagValue(Conf, recoded + strlen("COMPOUNDBEGIN"),
- FF_COMPOUNDBEGIN, filename, lineno);
+ FF_COMPOUNDBEGIN);
else if (STRNCMP(recoded, "COMPOUNDLAST") == 0)
addFlagValue(Conf, recoded + strlen("COMPOUNDLAST"),
- FF_COMPOUNDLAST, filename, lineno);
+ FF_COMPOUNDLAST);
/* COMPOUNDLAST and COMPOUNDEND are synonyms */
else if (STRNCMP(recoded, "COMPOUNDEND") == 0)
addFlagValue(Conf, recoded + strlen("COMPOUNDEND"),
- FF_COMPOUNDLAST, filename, lineno);
+ FF_COMPOUNDLAST);
else if (STRNCMP(recoded, "COMPOUNDMIDDLE") == 0)
addFlagValue(Conf, recoded + strlen("COMPOUNDMIDDLE"),
- FF_COMPOUNDMIDDLE, filename, lineno);
+ FF_COMPOUNDMIDDLE);
else if (STRNCMP(recoded, "ONLYINCOMPOUND") == 0)
addFlagValue(Conf, recoded + strlen("ONLYINCOMPOUND"),
- FF_COMPOUNDONLY, filename, lineno);
+ FF_COMPOUNDONLY);
else if (STRNCMP(recoded, "COMPOUNDPERMITFLAG") == 0)
addFlagValue(Conf, recoded + strlen("COMPOUNDPERMITFLAG"),
- FF_COMPOUNDPERMITFLAG, filename, lineno);
+ FF_COMPOUNDPERMITFLAG);
else if (STRNCMP(recoded, "COMPOUNDFORBIDFLAG") == 0)
addFlagValue(Conf, recoded + strlen("COMPOUNDFORBIDFLAG"),
- FF_COMPOUNDFORBIDFLAG, filename, lineno);
+ FF_COMPOUNDFORBIDFLAG);
else if (STRNCMP(recoded, "FLAG") == 0)
{
char *s = recoded + strlen("FLAG");
@@ -612,26 +600,23 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename)
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\"",
- lineno, filename)));
+ errmsg("Ispell dictionary supports only default flag value")));
}
pfree(recoded);
}
- FreeFile(affix);
- lineno = 0;
+ tsearch_readline_end(&trst);
sprintf(scanbuf, "%%6s %%%ds %%%ds %%%ds %%%ds", BUFSIZ / 5, BUFSIZ / 5, BUFSIZ / 5, BUFSIZ / 5);
- if (!(affix = AllocateFile(filename, "r")))
+ if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open affix file \"%s\": %m",
filename)));
- while ((recoded = t_readline(affix)) != NULL)
+ while ((recoded = tsearch_readline(&trst)) != NULL)
{
- lineno++;
if (*recoded == '\0' || t_isspace(recoded) || t_iseq(recoded, '#'))
goto nextline;
@@ -691,9 +676,9 @@ nextline:
pfree(recoded);
}
+ tsearch_readline_end(&trst);
if (ptype)
pfree(ptype);
- FreeFile(affix);
}
/*
@@ -713,14 +698,13 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
bool prefixes = false;
int flag = 0;
char flagflags = 0;
- FILE *affix;
- int lineno = 0;
+ tsearch_readline_state trst;
bool oldformat = false;
char *recoded = NULL;
checkTmpCtx();
- if (!(affix = AllocateFile(filename, "r")))
+ if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open affix file \"%s\": %m",
@@ -729,12 +713,10 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
memset(Conf->flagval, 0, sizeof(Conf->flagval));
Conf->usecompound = false;
- while ((recoded = t_readline(affix)) != NULL)
+ while ((recoded = tsearch_readline(&trst)) != NULL)
{
pstr = lowerstr(recoded);
- lineno++;
-
/* Skip comments and empty lines */
if (*pstr == '#' || *pstr == '\n')
goto nextline;
@@ -787,8 +769,7 @@ NIImportAffixes(IspellDict *Conf, const char *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\"",
- lineno, filename)));
+ errmsg("multibyte flag character is not allowed")));
if (*s == '*')
{
@@ -808,8 +789,7 @@ NIImportAffixes(IspellDict *Conf, const char *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\"",
- lineno, filename)));
+ errmsg("multibyte flag character is not allowed")));
flag = (unsigned char) *s;
goto nextline;
@@ -820,16 +800,15 @@ NIImportAffixes(IspellDict *Conf, const char *filename)
if (oldformat)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("wrong affix file format for flag at line %d of affix file \"%s\"",
- lineno, filename)));
- FreeFile(affix);
+ errmsg("wrong affix file format for flag")));
+ tsearch_readline_end(&trst);
NIImportOOAffixes(Conf, filename);
return;
}
if ((!suffixes) && (!prefixes))
goto nextline;
- if (!parse_affentry(pstr, mask, find, repl, filename, lineno))
+ if (!parse_affentry(pstr, mask, find, repl))
goto nextline;
NIAddAffix(Conf, flag, flagflags, mask, find, repl, suffixes ? FF_SUFFIX : FF_PREFIX);
@@ -838,7 +817,7 @@ nextline:
pfree(recoded);
pfree(pstr);
}
- FreeFile(affix);
+ tsearch_readline_end(&trst);
}
static int
diff --git a/src/backend/tsearch/ts_locale.c b/src/backend/tsearch/ts_locale.c
index 5ce367a497e..53349d7fc08 100644
--- a/src/backend/tsearch/ts_locale.c
+++ b/src/backend/tsearch/ts_locale.c
@@ -7,15 +7,19 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tsearch/ts_locale.c,v 1.9 2008/06/18 18:42:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/tsearch/ts_locale.c,v 1.10 2008/06/18 20:55:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include "storage/fd.h"
#include "tsearch/ts_locale.h"
#include "tsearch/ts_public.h"
+static void tsearch_readline_callback(void *arg);
+
+
#ifdef USE_WIDE_UPPER_LOWER
int
@@ -77,11 +81,110 @@ t_isprint(const char *ptr)
/*
+ * Set up to read a file using tsearch_readline(). This facility is
+ * better than just reading the file directly because it provides error
+ * context pointing to the specific line where a problem is detected.
+ *
+ * Expected usage is:
+ *
+ * tsearch_readline_state trst;
+ *
+ * if (!tsearch_readline_begin(&trst, filename))
+ * ereport(ERROR,
+ * (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ * errmsg("could not open stop-word file \"%s\": %m",
+ * filename)));
+ * while ((line = tsearch_readline(&trst)) != NULL)
+ * process line;
+ * tsearch_readline_end(&trst);
+ *
+ * Note that the caller supplies the ereport() for file open failure;
+ * this is so that a custom message can be provided. The filename string
+ * passed to tsearch_readline_begin() must remain valid through
+ * tsearch_readline_end().
+ */
+bool
+tsearch_readline_begin(tsearch_readline_state *stp,
+ const char *filename)
+{
+ if ((stp->fp = AllocateFile(filename, "r")) == NULL)
+ return false;
+ stp->filename = filename;
+ stp->lineno = 0;
+ stp->curline = NULL;
+ /* Setup error traceback support for ereport() */
+ stp->cb.callback = tsearch_readline_callback;
+ stp->cb.arg = (void *) stp;
+ stp->cb.previous = error_context_stack;
+ error_context_stack = &stp->cb;
+ return true;
+}
+
+/*
* Read the next line from a tsearch data file (expected to be in UTF-8), and
* convert it to database encoding if needed. The returned string is palloc'd.
* NULL return means EOF.
*/
char *
+tsearch_readline(tsearch_readline_state *stp)
+{
+ char *result;
+
+ stp->lineno++;
+ stp->curline = NULL;
+ result = t_readline(stp->fp);
+ stp->curline = result;
+ return result;
+}
+
+/*
+ * Close down after reading a file with tsearch_readline()
+ */
+void
+tsearch_readline_end(tsearch_readline_state *stp)
+{
+ FreeFile(stp->fp);
+ /* Pop the error context stack */
+ error_context_stack = stp->cb.previous;
+}
+
+/*
+ * Error context callback for errors occurring while reading a tsearch
+ * configuration file.
+ */
+static void
+tsearch_readline_callback(void *arg)
+{
+ tsearch_readline_state *stp = (tsearch_readline_state *) arg;
+
+ /*
+ * We can't include the text of the config line for errors that occur
+ * during t_readline() itself. This is only partly a consequence of
+ * our arms-length use of that routine: the major cause of such
+ * errors is encoding violations, and we daren't try to print error
+ * messages containing badly-encoded data.
+ */
+ if (stp->curline)
+ errcontext("line %d of configuration file \"%s\": \"%s\"",
+ stp->lineno,
+ stp->filename,
+ stp->curline);
+ else
+ errcontext("line %d of configuration file \"%s\"",
+ stp->lineno,
+ stp->filename);
+}
+
+
+/*
+ * Read the next line from a tsearch data file (expected to be in UTF-8), and
+ * convert it to database encoding if needed. The returned string is palloc'd.
+ * NULL return means EOF.
+ *
+ * Note: direct use of this function is now deprecated. Go through
+ * tsearch_readline() to provide better error reporting.
+ */
+char *
t_readline(FILE *fp)
{
int len;
diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c
index 3708d02689f..04586647890 100644
--- a/src/backend/tsearch/ts_utils.c
+++ b/src/backend/tsearch/ts_utils.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tsearch/ts_utils.c,v 1.10 2008/06/18 18:42:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/tsearch/ts_utils.c,v 1.11 2008/06/18 20:55:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,6 @@
#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"
@@ -82,17 +81,17 @@ readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *))
if (fname && *fname)
{
char *filename = get_tsearch_config_filename(fname, "stop");
- FILE *hin;
+ tsearch_readline_state trst;
char *line;
int reallen = 0;
- if ((hin = AllocateFile(filename, "r")) == NULL)
+ if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open stop-word file \"%s\": %m",
filename)));
- while ((line = t_readline(hin)) != NULL)
+ while ((line = tsearch_readline(&trst)) != NULL)
{
char *pbuf = line;
@@ -135,7 +134,7 @@ readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *))
(s->len)++;
}
- FreeFile(hin);
+ tsearch_readline_end(&trst);
pfree(filename);
}
diff --git a/src/include/tsearch/ts_locale.h b/src/include/tsearch/ts_locale.h
index 110efb191c1..b05ab7f1b0b 100644
--- a/src/include/tsearch/ts_locale.h
+++ b/src/include/tsearch/ts_locale.h
@@ -5,7 +5,7 @@
*
* Copyright (c) 1998-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/include/tsearch/ts_locale.h,v 1.7 2008/06/18 18:42:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/tsearch/ts_locale.h,v 1.8 2008/06/18 20:55:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,6 +29,16 @@
#include <wctype.h>
#endif
+/* working state for tsearch_readline (should be a local var in caller) */
+typedef struct
+{
+ FILE *fp;
+ const char *filename;
+ int lineno;
+ char *curline;
+ ErrorContextCallback cb;
+} tsearch_readline_state;
+
#define TOUCHAR(x) (*((const unsigned char *) (x)))
#ifdef USE_WIDE_UPPER_LOWER
@@ -55,6 +65,12 @@ extern int t_isprint(const char *ptr);
extern char *lowerstr(const char *str);
extern char *lowerstr_with_len(const char *str, int len);
+
+extern bool tsearch_readline_begin(tsearch_readline_state *stp,
+ const char *filename);
+extern char *tsearch_readline(tsearch_readline_state *stp);
+extern void tsearch_readline_end(tsearch_readline_state *stp);
+
extern char *t_readline(FILE *fp);
#endif /* __TSLOCALE_H__ */