PostgreSQL Source Code  git master
spell.h File Reference
#include "regex/regex.h"
#include "tsearch/dicts/regis.h"
#include "tsearch/ts_public.h"
Include dependency graph for spell.h:
This graph shows which files directly or indirectly include this file:

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  CompoundAffixFlag
 
struct  IspellDict
 

Macros

#define FF_COMPOUNDONLY   0x01
 
#define FF_COMPOUNDBEGIN   0x02
 
#define FF_COMPOUNDMIDDLE   0x04
 
#define FF_COMPOUNDLAST   0x08
 
#define FF_COMPOUNDFLAG
 
#define FF_COMPOUNDFLAGMASK   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))
 
#define FLAGNUM_MAXSIZE   (1 << 16)
 

Typedefs

typedef struct SPNode SPNode
 
typedef struct spell_struct SPELL
 
typedef struct aff_struct AFFIX
 
typedef struct AffixNode AffixNode
 
typedef struct CompoundAffixFlag CompoundAffixFlag
 

Enumerations

enum  FlagMode { FM_CHAR , FM_LONG , FM_NUM }
 

Functions

TSLexemeNINormalizeWord (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)
 

Macro Definition Documentation

◆ ANHRDSZ

#define ANHRDSZ   (offsetof(AffixNode, data))

Definition at line 145 of file spell.h.

◆ FF_COMPOUNDBEGIN

#define FF_COMPOUNDBEGIN   0x02

Definition at line 43 of file spell.h.

◆ FF_COMPOUNDFLAG

#define FF_COMPOUNDFLAG
Value:
FF_COMPOUNDLAST )
#define FF_COMPOUNDBEGIN
Definition: spell.h:43
#define FF_COMPOUNDMIDDLE
Definition: spell.h:44

Definition at line 46 of file spell.h.

◆ FF_COMPOUNDFLAGMASK

#define FF_COMPOUNDFLAGMASK   0x0f

Definition at line 48 of file spell.h.

◆ FF_COMPOUNDFORBIDFLAG

#define FF_COMPOUNDFORBIDFLAG   0x20

Definition at line 114 of file spell.h.

◆ FF_COMPOUNDLAST

#define FF_COMPOUNDLAST   0x08

Definition at line 45 of file spell.h.

◆ FF_COMPOUNDMIDDLE

#define FF_COMPOUNDMIDDLE   0x04

Definition at line 44 of file spell.h.

◆ FF_COMPOUNDONLY

#define FF_COMPOUNDONLY   0x01

Definition at line 42 of file spell.h.

◆ FF_COMPOUNDPERMITFLAG

#define FF_COMPOUNDPERMITFLAG   0x10

Definition at line 113 of file spell.h.

◆ FF_CROSSPRODUCT

#define FF_CROSSPRODUCT   0x40

Definition at line 115 of file spell.h.

◆ FF_PREFIX

#define FF_PREFIX   0

Definition at line 122 of file spell.h.

◆ FF_SUFFIX

#define FF_SUFFIX   1

Definition at line 121 of file spell.h.

◆ FLAGNUM_MAXSIZE

#define FLAGNUM_MAXSIZE   (1 << 16)

Definition at line 182 of file spell.h.

◆ SPELLHDRSZ

#define SPELLHDRSZ   (offsetof(SPELL, word))

Definition at line 82 of file spell.h.

◆ SPNHDRSZ

#define SPNHDRSZ   (offsetof(SPNode,data))

Definition at line 56 of file spell.h.

Typedef Documentation

◆ AFFIX

typedef struct aff_struct AFFIX

◆ AffixNode

typedef struct AffixNode AffixNode

◆ CompoundAffixFlag

◆ SPELL

typedef struct spell_struct SPELL

◆ SPNode

typedef struct SPNode SPNode

Enumeration Type Documentation

◆ FlagMode

enum FlagMode
Enumerator
FM_CHAR 
FM_LONG 
FM_NUM 

Definition at line 157 of file spell.h.

158 {
159  FM_CHAR, /* one character (like ispell) */
160  FM_LONG, /* two characters */
161  FM_NUM, /* number, >= 0 and < 65536 */
162 } FlagMode;
FlagMode
Definition: spell.h:158
@ FM_LONG
Definition: spell.h:160
@ FM_CHAR
Definition: spell.h:159
@ FM_NUM
Definition: spell.h:161

Function Documentation

◆ NIFinishBuild()

void NIFinishBuild ( IspellDict Conf)

Definition at line 103 of file spell.c.

104 {
105  /* Release no-longer-needed temp memory */
107  /* Just for cleanliness, zero the now-dangling pointers */
108  Conf->buildCxt = NULL;
109  Conf->Spell = NULL;
110  Conf->firstfree = NULL;
111  Conf->CompoundAffixFlags = NULL;
112 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454
MemoryContext buildCxt
Definition: spell.h:220
CompoundAffixFlag * CompoundAffixFlags
Definition: spell.h:210
char * firstfree
Definition: spell.h:228
SPELL ** Spell
Definition: spell.h:223

References IspellDict::buildCxt, IspellDict::CompoundAffixFlags, IspellDict::firstfree, MemoryContextDelete(), and IspellDict::Spell.

Referenced by dispell_init().

◆ NIImportAffixes()

void NIImportAffixes ( IspellDict Conf,
const char *  filename 
)

Definition at line 1425 of file spell.c.

1426 {
1427  char *pstr = NULL;
1428  char flag[BUFSIZ];
1429  char mask[BUFSIZ];
1430  char find[BUFSIZ];
1431  char repl[BUFSIZ];
1432  char *s;
1433  bool suffixes = false;
1434  bool prefixes = false;
1435  char flagflags = 0;
1437  bool oldformat = false;
1438  char *recoded = NULL;
1439 
1440  if (!tsearch_readline_begin(&trst, filename))
1441  ereport(ERROR,
1442  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1443  errmsg("could not open affix file \"%s\": %m",
1444  filename)));
1445 
1446  Conf->usecompound = false;
1447  Conf->useFlagAliases = false;
1448  Conf->flagMode = FM_CHAR;
1449 
1450  while ((recoded = tsearch_readline(&trst)) != NULL)
1451  {
1452  pstr = lowerstr(recoded);
1453 
1454  /* Skip comments and empty lines */
1455  if (*pstr == '#' || *pstr == '\n')
1456  goto nextline;
1457 
1458  if (STRNCMP(pstr, "compoundwords") == 0)
1459  {
1460  /* Find case-insensitive L flag in non-lowercased string */
1461  s = findchar2(recoded, 'l', 'L');
1462  if (s)
1463  {
1464  while (*s && !t_isspace(s))
1465  s += pg_mblen(s);
1466  while (*s && t_isspace(s))
1467  s += pg_mblen(s);
1468 
1469  if (*s && pg_mblen(s) == 1)
1470  {
1472  Conf->usecompound = true;
1473  }
1474  oldformat = true;
1475  goto nextline;
1476  }
1477  }
1478  if (STRNCMP(pstr, "suffixes") == 0)
1479  {
1480  suffixes = true;
1481  prefixes = false;
1482  oldformat = true;
1483  goto nextline;
1484  }
1485  if (STRNCMP(pstr, "prefixes") == 0)
1486  {
1487  suffixes = false;
1488  prefixes = true;
1489  oldformat = true;
1490  goto nextline;
1491  }
1492  if (STRNCMP(pstr, "flag") == 0)
1493  {
1494  s = recoded + 4; /* we need non-lowercased string */
1495  flagflags = 0;
1496 
1497  while (*s && t_isspace(s))
1498  s += pg_mblen(s);
1499 
1500  if (*s == '*')
1501  {
1502  flagflags |= FF_CROSSPRODUCT;
1503  s++;
1504  }
1505  else if (*s == '~')
1506  {
1507  flagflags |= FF_COMPOUNDONLY;
1508  s++;
1509  }
1510 
1511  if (*s == '\\')
1512  s++;
1513 
1514  /*
1515  * An old-format flag is a single ASCII character; we expect it to
1516  * be followed by EOL, whitespace, or ':'. Otherwise this is a
1517  * new-format flag command.
1518  */
1519  if (*s && pg_mblen(s) == 1)
1520  {
1521  COPYCHAR(flag, s);
1522  flag[1] = '\0';
1523 
1524  s++;
1525  if (*s == '\0' || *s == '#' || *s == '\n' || *s == ':' ||
1526  t_isspace(s))
1527  {
1528  oldformat = true;
1529  goto nextline;
1530  }
1531  }
1532  goto isnewformat;
1533  }
1534  if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 ||
1535  STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
1536  STRNCMP(recoded, "PFX") == 0 ||
1537  STRNCMP(recoded, "SFX") == 0)
1538  goto isnewformat;
1539 
1540  if ((!suffixes) && (!prefixes))
1541  goto nextline;
1542 
1543  if (!parse_affentry(pstr, mask, find, repl))
1544  goto nextline;
1545 
1546  NIAddAffix(Conf, flag, flagflags, mask, find, repl, suffixes ? FF_SUFFIX : FF_PREFIX);
1547 
1548 nextline:
1549  pfree(recoded);
1550  pfree(pstr);
1551  }
1552  tsearch_readline_end(&trst);
1553  return;
1554 
1555 isnewformat:
1556  if (oldformat)
1557  ereport(ERROR,
1558  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1559  errmsg("affix file contains both old-style and new-style commands")));
1560  tsearch_readline_end(&trst);
1561 
1562  NIImportOOAffixes(Conf, filename);
1563 }
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023
void pfree(void *pointer)
Definition: mcxt.c:1520
static char * filename
Definition: pg_dumpall.c:119
static void prefixes(struct vars *v)
Definition: regc_lex.c:99
static int find(struct vars *v, struct cnfa *cnfa, struct colormap *cm)
Definition: regexec.c:419
static char * findchar2(char *str, int c1, int c2)
Definition: spell.c:242
static void NIImportOOAffixes(IspellDict *Conf, const char *filename)
Definition: spell.c:1196
static void NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask, const char *find, const char *repl, int type)
Definition: spell.c:677
#define STRNCMP(s, p)
Definition: spell.c:190
static bool parse_affentry(char *str, char *mask, char *find, char *repl)
Definition: spell.c:913
static void addCompoundAffixFlagValue(IspellDict *Conf, char *s, uint32 val)
Definition: spell.c:1066
#define FF_SUFFIX
Definition: spell.h:121
#define FF_COMPOUNDFLAG
Definition: spell.h:46
#define FF_PREFIX
Definition: spell.h:122
#define FF_CROSSPRODUCT
Definition: spell.h:115
#define FF_COMPOUNDONLY
Definition: spell.h:42
bool usecompound
Definition: spell.h:202
bool useFlagAliases
Definition: spell.h:198
FlagMode flagMode
Definition: spell.h:203
char * flag(int b)
Definition: test-ctype.c:33
bool tsearch_readline_begin(tsearch_readline_state *stp, const char *filename)
Definition: ts_locale.c:134
char * tsearch_readline(tsearch_readline_state *stp)
Definition: ts_locale.c:157
int t_isspace(const char *ptr)
Definition: ts_locale.c:50
void tsearch_readline_end(tsearch_readline_state *stp)
Definition: ts_locale.c:202
char * lowerstr(const char *str)
Definition: ts_locale.c:253
#define COPYCHAR(d, s)
Definition: ts_locale.h:40

References addCompoundAffixFlagValue(), COPYCHAR, ereport, errcode(), errmsg(), ERROR, FF_COMPOUNDFLAG, FF_COMPOUNDONLY, FF_CROSSPRODUCT, FF_PREFIX, FF_SUFFIX, filename, find(), findchar2(), flag(), IspellDict::flagMode, FM_CHAR, lowerstr(), NIAddAffix(), NIImportOOAffixes(), parse_affentry(), pfree(), pg_mblen(), prefixes(), STRNCMP, t_isspace(), tsearch_readline(), tsearch_readline_begin(), tsearch_readline_end(), IspellDict::usecompound, and IspellDict::useFlagAliases.

Referenced by dispell_init().

◆ NIImportDictionary()

void NIImportDictionary ( IspellDict Conf,
const char *  filename 
)

Definition at line 517 of file spell.c.

518 {
520  char *line;
521 
522  if (!tsearch_readline_begin(&trst, filename))
523  ereport(ERROR,
524  (errcode(ERRCODE_CONFIG_FILE_ERROR),
525  errmsg("could not open dictionary file \"%s\": %m",
526  filename)));
527 
528  while ((line = tsearch_readline(&trst)) != NULL)
529  {
530  char *s,
531  *pstr;
532 
533  /* Set of affix flags */
534  const char *flag;
535 
536  /* Extract flag from the line */
537  flag = NULL;
538  if ((s = findchar(line, '/')))
539  {
540  *s++ = '\0';
541  flag = s;
542  while (*s)
543  {
544  /* we allow only single encoded flags for faster works */
545  if (pg_mblen(s) == 1 && t_isprint(s) && !t_isspace(s))
546  s++;
547  else
548  {
549  *s = '\0';
550  break;
551  }
552  }
553  }
554  else
555  flag = "";
556 
557  /* Remove trailing spaces */
558  s = line;
559  while (*s)
560  {
561  if (t_isspace(s))
562  {
563  *s = '\0';
564  break;
565  }
566  s += pg_mblen(s);
567  }
568  pstr = lowerstr_ctx(Conf, line);
569 
570  NIAddSpell(Conf, pstr, flag);
571  pfree(pstr);
572 
573  pfree(line);
574  }
575  tsearch_readline_end(&trst);
576 }
static void NIAddSpell(IspellDict *Conf, const char *word, const char *flag)
Definition: spell.c:486
static char * lowerstr_ctx(IspellDict *Conf, const char *src)
Definition: spell.c:175
static char * findchar(char *str, int c)
Definition: spell.c:229
int t_isprint(const char *ptr)
Definition: ts_locale.c:95

References ereport, errcode(), errmsg(), ERROR, filename, findchar(), flag(), lowerstr_ctx(), NIAddSpell(), pfree(), pg_mblen(), t_isprint(), t_isspace(), tsearch_readline(), tsearch_readline_begin(), and tsearch_readline_end().

Referenced by dispell_init().

◆ NINormalizeWord()

TSLexeme* NINormalizeWord ( IspellDict Conf,
char *  word 
)

Definition at line 2536 of file spell.c.

2537 {
2538  char **res;
2539  TSLexeme *lcur = NULL,
2540  *lres = NULL;
2541  uint16 NVariant = 1;
2542 
2543  res = NormalizeSubWord(Conf, word, 0);
2544 
2545  if (res)
2546  {
2547  char **ptr = res;
2548 
2549  while (*ptr && (lcur - lres) < MAX_NORM)
2550  {
2551  addNorm(&lres, &lcur, *ptr, 0, NVariant++);
2552  ptr++;
2553  }
2554  pfree(res);
2555  }
2556 
2557  if (Conf->usecompound)
2558  {
2559  int wordlen = strlen(word);
2560  SplitVar *ptr,
2561  *var = SplitToVariants(Conf, NULL, NULL, word, wordlen, 0, -1);
2562  int i;
2563 
2564  while (var)
2565  {
2566  if (var->nstem > 1)
2567  {
2568  char **subres = NormalizeSubWord(Conf, var->stem[var->nstem - 1], FF_COMPOUNDLAST);
2569 
2570  if (subres)
2571  {
2572  char **subptr = subres;
2573 
2574  while (*subptr)
2575  {
2576  for (i = 0; i < var->nstem - 1; i++)
2577  {
2578  addNorm(&lres, &lcur, (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]), 0, NVariant);
2579  }
2580 
2581  addNorm(&lres, &lcur, *subptr, 0, NVariant);
2582  subptr++;
2583  NVariant++;
2584  }
2585 
2586  pfree(subres);
2587  var->stem[0] = NULL;
2588  pfree(var->stem[var->nstem - 1]);
2589  }
2590  }
2591 
2592  for (i = 0; i < var->nstem && var->stem[i]; i++)
2593  pfree(var->stem[i]);
2594  ptr = var->next;
2595  pfree(var->stem);
2596  pfree(var);
2597  var = ptr;
2598  }
2599  }
2600 
2601  return lres;
2602 }
unsigned short uint16
Definition: c.h:505
int i
Definition: isn.c:73
char * pstrdup(const char *in)
Definition: mcxt.c:1695
static void word(struct vars *v, int dir, struct state *lp, struct state *rp)
Definition: regcomp.c:1474
static SplitVar * SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int wordlen, int startpos, int minpos)
Definition: spell.c:2370
#define MAX_NORM
Definition: spell.c:187
static void addNorm(TSLexeme **lres, TSLexeme **lcur, char *word, int flags, uint16 NVariant)
Definition: spell.c:2520
static char ** NormalizeSubWord(IspellDict *Conf, char *word, int flag)
Definition: spell.c:2172
#define FF_COMPOUNDLAST
Definition: spell.h:45
int nstem
Definition: spell.c:2283
struct SplitVar * next
Definition: spell.c:2286
char ** stem
Definition: spell.c:2285

References addNorm(), FF_COMPOUNDLAST, i, MAX_NORM, SplitVar::next, NormalizeSubWord(), SplitVar::nstem, pfree(), pstrdup(), res, SplitToVariants(), SplitVar::stem, IspellDict::usecompound, and word().

Referenced by dispell_lexize().

◆ NISortAffixes()

void NISortAffixes ( IspellDict Conf)

Definition at line 1972 of file spell.c.

1973 {
1974  AFFIX *Affix;
1975  size_t i;
1976  CMPDAffix *ptr;
1977  int firstsuffix = Conf->naffixes;
1978 
1979  if (Conf->naffixes == 0)
1980  return;
1981 
1982  /* Store compound affixes in the Conf->CompoundAffix array */
1983  if (Conf->naffixes > 1)
1984  qsort(Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
1985  Conf->CompoundAffix = ptr = (CMPDAffix *) palloc(sizeof(CMPDAffix) * Conf->naffixes);
1986  ptr->affix = NULL;
1987 
1988  for (i = 0; i < Conf->naffixes; i++)
1989  {
1990  Affix = &(((AFFIX *) Conf->Affix)[i]);
1991  if (Affix->type == FF_SUFFIX && i < firstsuffix)
1992  firstsuffix = i;
1993 
1994  if ((Affix->flagflags & FF_COMPOUNDFLAG) && Affix->replen > 0 &&
1995  isAffixInUse(Conf, Affix->flag))
1996  {
1997  bool issuffix = (Affix->type == FF_SUFFIX);
1998 
1999  if (ptr == Conf->CompoundAffix ||
2000  issuffix != (ptr - 1)->issuffix ||
2001  strbncmp((const unsigned char *) (ptr - 1)->affix,
2002  (const unsigned char *) Affix->repl,
2003  (ptr - 1)->len))
2004  {
2005  /* leave only unique and minimal suffixes */
2006  ptr->affix = Affix->repl;
2007  ptr->len = Affix->replen;
2008  ptr->issuffix = issuffix;
2009  ptr++;
2010  }
2011  }
2012  }
2013  ptr->affix = NULL;
2014  Conf->CompoundAffix = (CMPDAffix *) repalloc(Conf->CompoundAffix, sizeof(CMPDAffix) * (ptr - Conf->CompoundAffix + 1));
2015 
2016  /* Start build a prefix tree */
2017  Conf->Prefix = mkANode(Conf, 0, firstsuffix, 0, FF_PREFIX);
2018  Conf->Suffix = mkANode(Conf, firstsuffix, Conf->naffixes, 0, FF_SUFFIX);
2019  mkVoidAffix(Conf, true, firstsuffix);
2020  mkVoidAffix(Conf, false, firstsuffix);
2021 }
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1540
void * palloc(Size size)
Definition: mcxt.c:1316
#define qsort(a, b, c, d)
Definition: port.h:449
static AffixNode * mkANode(IspellDict *Conf, int low, int high, int level, int type)
Definition: spell.c:1826
static bool isAffixInUse(IspellDict *Conf, char *affixflag)
Definition: spell.c:1957
static int strbncmp(const unsigned char *s1, const unsigned char *s2, size_t count)
Definition: spell.c:280
static void mkVoidAffix(IspellDict *Conf, bool issuffix, int startsuffix)
Definition: spell.c:1903
static int cmpaffix(const void *s1, const void *s2)
Definition: spell.c:311
int len
Definition: spell.h:150
bool issuffix
Definition: spell.h:151
char * affix
Definition: spell.h:149
AffixNode * Suffix
Definition: spell.h:190
int naffixes
Definition: spell.h:187
AFFIX * Affix
Definition: spell.h:188
CMPDAffix * CompoundAffix
Definition: spell.h:200
AffixNode * Prefix
Definition: spell.h:191
char * flag
Definition: spell.h:89
uint32 type
Definition: spell.h:91
uint32 replen
Definition: spell.h:95
char * repl
Definition: spell.h:97
uint32 flagflags
Definition: spell.h:92

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().

◆ NISortDictionary()

void NISortDictionary ( IspellDict Conf)

Definition at line 1718 of file spell.c.

1719 {
1720  int i;
1721  int naffix;
1722  int curaffix;
1723 
1724  /* compress affixes */
1725 
1726  /*
1727  * If we use flag aliases then we need to use Conf->AffixData filled in
1728  * the NIImportOOAffixes().
1729  */
1730  if (Conf->useFlagAliases)
1731  {
1732  for (i = 0; i < Conf->nspell; i++)
1733  {
1734  char *end;
1735 
1736  if (*Conf->Spell[i]->p.flag != '\0')
1737  {
1738  curaffix = strtol(Conf->Spell[i]->p.flag, &end, 10);
1739  if (Conf->Spell[i]->p.flag == end || errno == ERANGE)
1740  ereport(ERROR,
1741  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1742  errmsg("invalid affix alias \"%s\"",
1743  Conf->Spell[i]->p.flag)));
1744  if (curaffix < 0 || curaffix >= Conf->nAffixData)
1745  ereport(ERROR,
1746  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1747  errmsg("invalid affix alias \"%s\"",
1748  Conf->Spell[i]->p.flag)));
1749  if (*end != '\0' && !t_isdigit(end) && !t_isspace(end))
1750  ereport(ERROR,
1751  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1752  errmsg("invalid affix alias \"%s\"",
1753  Conf->Spell[i]->p.flag)));
1754  }
1755  else
1756  {
1757  /*
1758  * If Conf->Spell[i]->p.flag is empty, then get empty value of
1759  * Conf->AffixData (0 index).
1760  */
1761  curaffix = 0;
1762  }
1763 
1764  Conf->Spell[i]->p.d.affix = curaffix;
1765  Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
1766  }
1767  }
1768  /* Otherwise fill Conf->AffixData here */
1769  else
1770  {
1771  /* Count the number of different flags used in the dictionary */
1772  qsort(Conf->Spell, Conf->nspell, sizeof(SPELL *),
1773  cmpspellaffix);
1774 
1775  naffix = 0;
1776  for (i = 0; i < Conf->nspell; i++)
1777  {
1778  if (i == 0 ||
1779  strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag) != 0)
1780  naffix++;
1781  }
1782 
1783  /*
1784  * Fill in Conf->AffixData with the affixes that were used in the
1785  * dictionary. Replace textual flag-field of Conf->Spell entries with
1786  * indexes into Conf->AffixData array.
1787  */
1788  Conf->AffixData = (char **) palloc0(naffix * sizeof(char *));
1789 
1790  curaffix = -1;
1791  for (i = 0; i < Conf->nspell; i++)
1792  {
1793  if (i == 0 ||
1794  strcmp(Conf->Spell[i]->p.flag, Conf->AffixData[curaffix]) != 0)
1795  {
1796  curaffix++;
1797  Assert(curaffix < naffix);
1798  Conf->AffixData[curaffix] = cpstrdup(Conf,
1799  Conf->Spell[i]->p.flag);
1800  }
1801 
1802  Conf->Spell[i]->p.d.affix = curaffix;
1803  Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
1804  }
1805 
1806  Conf->lenAffixData = Conf->nAffixData = naffix;
1807  }
1808 
1809  /* Start build a prefix tree */
1810  qsort(Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
1811  Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
1812 }
#define Assert(condition)
Definition: c.h:858
void * palloc0(Size size)
Definition: mcxt.c:1346
static int cmpspell(const void *s1, const void *s2)
Definition: spell.c:197
static char * cpstrdup(IspellDict *Conf, const char *str)
Definition: spell.c:162
static SPNode * mkSPNode(IspellDict *Conf, int low, int high, int level)
Definition: spell.c:1636
static int cmpspellaffix(const void *s1, const void *s2)
Definition: spell.c:203
int lenAffixData
Definition: spell.h:196
char ** AffixData
Definition: spell.h:195
int nAffixData
Definition: spell.h:197
SPNode * Dictionary
Definition: spell.h:193
int nspell
Definition: spell.h:224
char * flag
Definition: spell.h:69
union spell_struct::@126 p
char word[FLEXIBLE_ARRAY_MEMBER]
Definition: spell.h:79
struct spell_struct::@126::@127 d
int t_isdigit(const char *ptr)
Definition: ts_locale.c:35

References IspellDict::AffixData, Assert, cmpspell(), cmpspellaffix(), cpstrdup(), spell_struct::d, IspellDict::Dictionary, ereport, errcode(), errmsg(), ERROR, spell_struct::flag, i, IspellDict::lenAffixData, mkSPNode(), IspellDict::nAffixData, IspellDict::nspell, spell_struct::p, palloc0(), qsort, IspellDict::Spell, t_isdigit(), t_isspace(), IspellDict::useFlagAliases, and spell_struct::word.

Referenced by dispell_init().

◆ NIStartBuild()

void NIStartBuild ( IspellDict Conf)

Definition at line 88 of file spell.c.

89 {
90  /*
91  * The temp context is a child of CurTransactionContext, so that it will
92  * go away automatically on error.
93  */
95  "Ispell dictionary init context",
97 }
MemoryContext CurTransactionContext
Definition: mcxt.c:155
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, IspellDict::buildCxt, and CurTransactionContext.

Referenced by dispell_init().