#include "regex/regex.h"#include "tsearch/dicts/regis.h"#include "tsearch/ts_public.h"

Go to the source code of this file.
Data Structures | |
| struct | SPNodeData |
| struct | SPNode |
| struct | spell_struct |
| struct | aff_struct |
| struct | AffixNodeData |
| struct | AffixNode |
| struct | CMPDAffix |
| struct | IspellDict |
Defines | |
| #define | MAXFLAGLEN 16 |
| #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 |
| #define | SPNHDRSZ (offsetof(SPNode,data)) |
| #define | SPELLHDRSZ (offsetof(SPELL, word)) |
| #define | FF_COMPOUNDPERMITFLAG 0x10 |
| #define | FF_COMPOUNDFORBIDFLAG 0x20 |
| #define | FF_CROSSPRODUCT 0x40 |
| #define | FF_SUFFIX 1 |
| #define | FF_PREFIX 0 |
| #define | ANHRDSZ (offsetof(AffixNode, data)) |
Typedefs | |
| typedef struct SPNode | SPNode |
| typedef struct spell_struct | SPELL |
| typedef struct aff_struct | AFFIX |
| typedef struct AffixNode | AffixNode |
Functions | |
| TSLexeme * | NINormalizeWord (IspellDict *Conf, char *word) |
| void | NIStartBuild (IspellDict *Conf) |
| void | NIImportAffixes (IspellDict *Conf, const char *filename) |
| void | NIImportDictionary (IspellDict *Conf, const char *filename) |
| void | NISortDictionary (IspellDict *Conf) |
| void | NISortAffixes (IspellDict *Conf) |
| void | NIFinishBuild (IspellDict *Conf) |
| #define ANHRDSZ (offsetof(AffixNode, data)) |
Definition at line 126 of file spell.h.
Referenced by mkANode(), and mkVoidAffix().
| #define FF_COMPOUNDBEGIN 0x02 |
Definition at line 43 of file spell.h.
Referenced by CheckAffix(), NIImportOOAffixes(), and SplitToVariants().
| #define FF_COMPOUNDFLAG ( FF_COMPOUNDBEGIN | FF_COMPOUNDMIDDLE | FF_COMPOUNDLAST ) |
Definition at line 46 of file spell.h.
Referenced by mkSPNode(), NIAddAffix(), NIImportAffixes(), NIImportOOAffixes(), and NISortAffixes().
| #define FF_COMPOUNDFORBIDFLAG 0x20 |
Definition at line 99 of file spell.h.
Referenced by CheckAffix(), and NIImportOOAffixes().
| #define FF_COMPOUNDLAST 0x08 |
Definition at line 45 of file spell.h.
Referenced by CheckAffix(), NIImportOOAffixes(), and NINormalizeWord().
| #define FF_COMPOUNDMIDDLE 0x04 |
Definition at line 44 of file spell.h.
Referenced by CheckAffix(), and NIImportOOAffixes().
| #define FF_COMPOUNDONLY 0x01 |
Definition at line 42 of file spell.h.
Referenced by CheckAffix(), FindWord(), mkSPNode(), NIAddAffix(), and NIImportOOAffixes().
| #define FF_COMPOUNDPERMITFLAG 0x10 |
Definition at line 98 of file spell.h.
Referenced by NIAddAffix(), and NIImportOOAffixes().
| #define FF_CROSSPRODUCT 0x40 |
Definition at line 100 of file spell.h.
Referenced by NIImportOOAffixes().
| #define FF_DICTFLAGMASK 0x0f |
Definition at line 47 of file spell.h.
Referenced by makeCompoundFlags().
| #define FF_PREFIX 0 |
Definition at line 107 of file spell.h.
Referenced by CheckAffix(), cmpaffix(), NIImportAffixes(), NIImportOOAffixes(), NISortAffixes(), and NormalizeSubWord().
| #define FF_SUFFIX 1 |
Definition at line 106 of file spell.h.
Referenced by CheckAffix(), NIAddAffix(), NIImportAffixes(), NIImportOOAffixes(), NISortAffixes(), and NormalizeSubWord().
| #define MAXFLAGLEN 16 |
Definition at line 25 of file spell.h.
Referenced by cmpspellaffix(), NIAddSpell(), and NISortDictionary().
| #define SPELLHDRSZ (offsetof(SPELL, word)) |
Definition at line 76 of file spell.h.
Referenced by NIAddSpell().
| #define SPNHDRSZ (offsetof(SPNode,data)) |
Definition at line 55 of file spell.h.
Referenced by mkSPNode().
| typedef struct aff_struct AFFIX |
| typedef struct spell_struct SPELL |
| void NIFinishBuild | ( | IspellDict * | Conf | ) |
Definition at line 56 of file spell.c.
References IspellDict::buildCxt, IspellDict::firstfree, MemoryContextDelete(), and IspellDict::Spell.
Referenced by dispell_init().
{
/* Release no-longer-needed temp memory */
MemoryContextDelete(Conf->buildCxt);
/* Just for cleanliness, zero the now-dangling pointers */
Conf->buildCxt = NULL;
Conf->Spell = NULL;
Conf->firstfree = NULL;
}
| void NIImportAffixes | ( | IspellDict * | Conf, | |
| const char * | filename | |||
| ) |
Definition at line 762 of file spell.c.
References ereport, errcode(), errmsg(), ERROR, FF_COMPOUNDFLAG, FF_PREFIX, FF_SUFFIX, find(), findchar(), flag(), IspellDict::flagval, lowerstr(), NIAddAffix(), NIImportOOAffixes(), NULL, parse_affentry(), pfree(), pg_mblen(), prefixes(), STRNCMP, t_isspace, tsearch_readline(), tsearch_readline_begin(), tsearch_readline_end(), and IspellDict::usecompound.
Referenced by dispell_init().
{
char *pstr = NULL;
char mask[BUFSIZ];
char find[BUFSIZ];
char repl[BUFSIZ];
char *s;
bool suffixes = false;
bool prefixes = false;
int flag = 0;
char flagflags = 0;
tsearch_readline_state trst;
bool oldformat = false;
char *recoded = NULL;
if (!tsearch_readline_begin(&trst, filename))
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 ((recoded = tsearch_readline(&trst)) != NULL)
{
pstr = lowerstr(recoded);
/* Skip comments and empty lines */
if (*pstr == '#' || *pstr == '\n')
goto nextline;
if (STRNCMP(pstr, "compoundwords") == 0)
{
s = findchar(pstr, 'l');
if (s)
{
s = recoded + (s - pstr); /* we need non-lowercased
* string */
while (*s && !t_isspace(s))
s += pg_mblen(s);
while (*s && t_isspace(s))
s += pg_mblen(s);
if (*s && pg_mblen(s) == 1)
{
Conf->flagval[*(unsigned char *) s] = FF_COMPOUNDFLAG;
Conf->usecompound = true;
}
oldformat = true;
goto nextline;
}
}
if (STRNCMP(pstr, "suffixes") == 0)
{
suffixes = true;
prefixes = false;
oldformat = true;
goto nextline;
}
if (STRNCMP(pstr, "prefixes") == 0)
{
suffixes = false;
prefixes = true;
oldformat = true;
goto nextline;
}
if (STRNCMP(pstr, "flag") == 0)
{
s = recoded + 4; /* we need non-lowercased string */
flagflags = 0;
while (*s && t_isspace(s))
s += pg_mblen(s);
oldformat = true;
/* allow only single-encoded flags */
if (pg_mblen(s) != 1)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("multibyte flag character is not allowed")));
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")));
flag = *(unsigned char *) s;
goto nextline;
}
if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 || STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
STRNCMP(recoded, "PFX") == 0 || STRNCMP(recoded, "SFX") == 0)
{
if (oldformat)
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
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))
goto nextline;
NIAddAffix(Conf, flag, flagflags, mask, find, repl, suffixes ? FF_SUFFIX : FF_PREFIX);
nextline:
pfree(recoded);
pfree(pstr);
}
tsearch_readline_end(&trst);
}
| void NIImportDictionary | ( | IspellDict * | Conf, | |
| const char * | filename | |||
| ) |
Definition at line 268 of file spell.c.
References ereport, errcode(), errmsg(), ERROR, findchar(), lowerstr_ctx(), NIAddSpell(), NULL, pfree(), pg_mblen(), t_isprint, t_isspace, tsearch_readline(), tsearch_readline_begin(), and tsearch_readline_end().
Referenced by dispell_init().
{
tsearch_readline_state trst;
char *line;
if (!tsearch_readline_begin(&trst, filename))
ereport(ERROR,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("could not open dictionary file \"%s\": %m",
filename)));
while ((line = tsearch_readline(&trst)) != NULL)
{
char *s,
*pstr;
const char *flag;
/* Extract flag from the line */
flag = NULL;
if ((s = findchar(line, '/')))
{
*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 = "";
/* Remove trailing spaces */
s = line;
while (*s)
{
if (t_isspace(s))
{
*s = '\0';
break;
}
s += pg_mblen(s);
}
pstr = lowerstr_ctx(Conf, line);
NIAddSpell(Conf, pstr, flag);
pfree(pstr);
pfree(line);
}
tsearch_readline_end(&trst);
}
| TSLexeme* NINormalizeWord | ( | IspellDict * | Conf, | |
| char * | word | |||
| ) |
Definition at line 1739 of file spell.c.
References addNorm(), FF_COMPOUNDLAST, i, MAX_NORM, SplitVar::next, NormalizeSubWord(), SplitVar::nstem, NULL, pfree(), pstrdup(), SplitToVariants(), SplitVar::stem, and IspellDict::usecompound.
Referenced by dispell_lexize().
{
char **res;
TSLexeme *lcur = NULL,
*lres = NULL;
uint16 NVariant = 1;
res = NormalizeSubWord(Conf, word, 0);
if (res)
{
char **ptr = res;
while (*ptr && (lcur - lres) < MAX_NORM)
{
addNorm(&lres, &lcur, *ptr, 0, NVariant++);
ptr++;
}
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;
while (*subptr)
{
for (i = 0; i < var->nstem - 1; i++)
{
addNorm(&lres, &lcur, (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]), 0, NVariant);
}
addNorm(&lres, &lcur, *subptr, 0, NVariant);
subptr++;
NVariant++;
}
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;
}
| void NISortAffixes | ( | IspellDict * | Conf | ) |
Definition at line 1186 of file spell.c.
References CMPDAffix::affix, IspellDict::Affix, cmpaffix(), IspellDict::CompoundAffix, FF_COMPOUNDFLAG, FF_PREFIX, FF_SUFFIX, aff_struct::flag, aff_struct::flagflags, i, isAffixInUse(), CMPDAffix::issuffix, CMPDAffix::len, mkANode(), mkVoidAffix(), IspellDict::naffixes, palloc(), IspellDict::Prefix, qsort, repalloc(), aff_struct::repl, aff_struct::replen, strbncmp(), IspellDict::Suffix, and aff_struct::type.
Referenced by dispell_init().
{
AFFIX *Affix;
size_t i;
CMPDAffix *ptr;
int firstsuffix = Conf->naffixes;
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 && i < firstsuffix)
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, true, firstsuffix);
mkVoidAffix(Conf, false, firstsuffix);
}
| void NISortDictionary | ( | IspellDict * | Conf | ) |
Definition at line 1013 of file spell.c.
References IspellDict::AffixData, Assert, cmpspell(), cmpspellaffix(), cpstrdup(), spell_struct::d, IspellDict::Dictionary, spell_struct::flag, i, IspellDict::lenAffixData, MAXFLAGLEN, mkSPNode(), IspellDict::nAffixData, IspellDict::nspell, spell_struct::p, palloc0(), qsort, IspellDict::Spell, and spell_struct::word.
Referenced by dispell_init().
{
int i;
int naffix = 0;
int curaffix;
/* compress affixes */
/* Count the number of different flags used in the dictionary */
qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspellaffix);
naffix = 0;
for (i = 0; i < Conf->nspell; i++)
{
if (i == 0 || strncmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag, MAXFLAGLEN))
naffix++;
}
/*
* Fill in Conf->AffixData with the affixes that were used in the
* dictionary. Replace textual flag-field of Conf->Spell entries with
* indexes into Conf->AffixData array.
*/
Conf->AffixData = (char **) palloc0(naffix * sizeof(char *));
curaffix = -1;
for (i = 0; i < Conf->nspell; i++)
{
if (i == 0 || strncmp(Conf->Spell[i]->p.flag, Conf->AffixData[curaffix], MAXFLAGLEN))
{
curaffix++;
Assert(curaffix < naffix);
Conf->AffixData[curaffix] = cpstrdup(Conf, Conf->Spell[i]->p.flag);
}
Conf->Spell[i]->p.d.affix = curaffix;
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);
}
| void NIStartBuild | ( | IspellDict * | Conf | ) |
Definition at line 39 of file spell.c.
References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), IspellDict::buildCxt, and CurTransactionContext.
Referenced by dispell_init().
{
/*
* The temp context is a child of CurTransactionContext, so that it will
* go away automatically on error.
*/
Conf->buildCxt = AllocSetContextCreate(CurTransactionContext,
"Ispell dictionary init context",
ALLOCSET_DEFAULT_MINSIZE,
ALLOCSET_DEFAULT_INITSIZE,
ALLOCSET_DEFAULT_MAXSIZE);
}
1.7.1