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 140 of file spell.h.

Referenced by mkANode(), and mkVoidAffix().

◆ FF_COMPOUNDBEGIN

#define FF_COMPOUNDBEGIN   0x02

Definition at line 43 of file spell.h.

Referenced by CheckAffix(), NIImportOOAffixes(), and SplitToVariants().

◆ FF_COMPOUNDFLAG

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

Definition at line 46 of file spell.h.

Referenced by mkSPNode(), NIAddAffix(), NIImportAffixes(), NIImportOOAffixes(), and NISortAffixes().

◆ FF_COMPOUNDFLAGMASK

#define FF_COMPOUNDFLAGMASK   0x0f

Definition at line 48 of file spell.h.

Referenced by FindWord(), and makeCompoundFlags().

◆ FF_COMPOUNDFORBIDFLAG

#define FF_COMPOUNDFORBIDFLAG   0x20

Definition at line 109 of file spell.h.

Referenced by CheckAffix(), and NIImportOOAffixes().

◆ FF_COMPOUNDLAST

#define FF_COMPOUNDLAST   0x08

Definition at line 45 of file spell.h.

Referenced by CheckAffix(), NIImportOOAffixes(), NINormalizeWord(), and SplitToVariants().

◆ FF_COMPOUNDMIDDLE

#define FF_COMPOUNDMIDDLE   0x04

Definition at line 44 of file spell.h.

Referenced by CheckAffix(), NIImportOOAffixes(), and SplitToVariants().

◆ FF_COMPOUNDONLY

#define FF_COMPOUNDONLY   0x01

Definition at line 42 of file spell.h.

Referenced by CheckAffix(), FindWord(), mkSPNode(), NIAddAffix(), NIImportAffixes(), and NIImportOOAffixes().

◆ FF_COMPOUNDPERMITFLAG

#define FF_COMPOUNDPERMITFLAG   0x10

Definition at line 108 of file spell.h.

Referenced by NIAddAffix(), and NIImportOOAffixes().

◆ FF_CROSSPRODUCT

#define FF_CROSSPRODUCT   0x40

Definition at line 110 of file spell.h.

Referenced by NIImportAffixes(), NIImportOOAffixes(), and NormalizeSubWord().

◆ FF_PREFIX

#define FF_PREFIX   0

◆ FF_SUFFIX

#define FF_SUFFIX   1

◆ FLAGNUM_MAXSIZE

#define FLAGNUM_MAXSIZE   (1 << 16)

Definition at line 177 of file spell.h.

Referenced by getNextFlagFromString(), and setCompoundAffixFlagValue().

◆ SPELLHDRSZ

#define SPELLHDRSZ   (offsetof(SPELL, word))

Definition at line 82 of file spell.h.

Referenced by NIAddSpell().

◆ SPNHDRSZ

#define SPNHDRSZ   (offsetof(SPNode,data))

Definition at line 56 of file spell.h.

Referenced by mkSPNode().

Typedef Documentation

◆ AFFIX

◆ AffixNode

◆ CompoundAffixFlag

◆ SPELL

◆ SPNode

Enumeration Type Documentation

◆ FlagMode

enum FlagMode
Enumerator
FM_CHAR 
FM_LONG 
FM_NUM 

Definition at line 152 of file spell.h.

153 {
154  FM_CHAR, /* one character (like ispell) */
155  FM_LONG, /* two characters */
156  FM_NUM /* number, >= 0 and < 65536 */
157 } FlagMode;
Definition: spell.h:154
Definition: spell.h:156
Definition: spell.h:155
FlagMode
Definition: spell.h:152

Function Documentation

◆ NIFinishBuild()

void NIFinishBuild ( IspellDict Conf)

Definition at line 102 of file spell.c.

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

Referenced by dispell_init().

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

◆ NIImportAffixes()

void NIImportAffixes ( IspellDict Conf,
const char *  filename 
)

Definition at line 1413 of file spell.c.

References addCompoundAffixFlagValue(), COPYCHAR, ereport, errcode(), errmsg(), ERROR, FF_COMPOUNDFLAG, FF_COMPOUNDONLY, FF_CROSSPRODUCT, FF_PREFIX, FF_SUFFIX, 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().

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

◆ NIImportDictionary()

void NIImportDictionary ( IspellDict Conf,
const char *  filename 
)

Definition at line 514 of file spell.c.

References ereport, errcode(), errmsg(), ERROR, 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().

515 {
517  char *line;
518 
519  if (!tsearch_readline_begin(&trst, filename))
520  ereport(ERROR,
521  (errcode(ERRCODE_CONFIG_FILE_ERROR),
522  errmsg("could not open dictionary file \"%s\": %m",
523  filename)));
524 
525  while ((line = tsearch_readline(&trst)) != NULL)
526  {
527  char *s,
528  *pstr;
529 
530  /* Set of affix flags */
531  const char *flag;
532 
533  /* Extract flag from the line */
534  flag = NULL;
535  if ((s = findchar(line, '/')))
536  {
537  *s++ = '\0';
538  flag = s;
539  while (*s)
540  {
541  /* we allow only single encoded flags for faster works */
542  if (pg_mblen(s) == 1 && t_isprint(s) && !t_isspace(s))
543  s++;
544  else
545  {
546  *s = '\0';
547  break;
548  }
549  }
550  }
551  else
552  flag = "";
553 
554  /* Remove trailing spaces */
555  s = line;
556  while (*s)
557  {
558  if (t_isspace(s))
559  {
560  *s = '\0';
561  break;
562  }
563  s += pg_mblen(s);
564  }
565  pstr = lowerstr_ctx(Conf, line);
566 
567  NIAddSpell(Conf, pstr, flag);
568  pfree(pstr);
569 
570  pfree(line);
571  }
572  tsearch_readline_end(&trst);
573 }
int t_isprint(const char *ptr)
Definition: ts_locale.c:73
static char * findchar(char *str, int c)
Definition: spell.c:228
int errcode(int sqlerrcode)
Definition: elog.c:575
static void NIAddSpell(IspellDict *Conf, const char *word, const char *flag)
Definition: spell.c:483
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ERROR
Definition: elog.h:43
int t_isspace(const char *ptr)
Definition: ts_locale.c:41
char * flag(int b)
Definition: test-ctype.c:33
#define ereport(elevel, rest)
Definition: elog.h:122
static char * lowerstr_ctx(IspellDict *Conf, const char *src)
Definition: spell.c:174
int pg_mblen(const char *mbstr)
Definition: mbutils.c:760
void tsearch_readline_end(tsearch_readline_state *stp)
Definition: ts_locale.c:150
char * tsearch_readline(tsearch_readline_state *stp)
Definition: ts_locale.c:135
bool tsearch_readline_begin(tsearch_readline_state *stp, const char *filename)
Definition: ts_locale.c:113
static char * filename
Definition: pg_dumpall.c:87
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ NINormalizeWord()

TSLexeme* NINormalizeWord ( IspellDict Conf,
char *  word 
)

Definition at line 2507 of file spell.c.

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

Referenced by dispell_lexize().

2508 {
2509  char **res;
2510  TSLexeme *lcur = NULL,
2511  *lres = NULL;
2512  uint16 NVariant = 1;
2513 
2514  res = NormalizeSubWord(Conf, word, 0);
2515 
2516  if (res)
2517  {
2518  char **ptr = res;
2519 
2520  while (*ptr && (lcur - lres) < MAX_NORM)
2521  {
2522  addNorm(&lres, &lcur, *ptr, 0, NVariant++);
2523  ptr++;
2524  }
2525  pfree(res);
2526  }
2527 
2528  if (Conf->usecompound)
2529  {
2530  int wordlen = strlen(word);
2531  SplitVar *ptr,
2532  *var = SplitToVariants(Conf, NULL, NULL, word, wordlen, 0, -1);
2533  int i;
2534 
2535  while (var)
2536  {
2537  if (var->nstem > 1)
2538  {
2539  char **subres = NormalizeSubWord(Conf, var->stem[var->nstem - 1], FF_COMPOUNDLAST);
2540 
2541  if (subres)
2542  {
2543  char **subptr = subres;
2544 
2545  while (*subptr)
2546  {
2547  for (i = 0; i < var->nstem - 1; i++)
2548  {
2549  addNorm(&lres, &lcur, (subptr == subres) ? var->stem[i] : pstrdup(var->stem[i]), 0, NVariant);
2550  }
2551 
2552  addNorm(&lres, &lcur, *subptr, 0, NVariant);
2553  subptr++;
2554  NVariant++;
2555  }
2556 
2557  pfree(subres);
2558  var->stem[0] = NULL;
2559  pfree(var->stem[var->nstem - 1]);
2560  }
2561  }
2562 
2563  for (i = 0; i < var->nstem && var->stem[i]; i++)
2564  pfree(var->stem[i]);
2565  ptr = var->next;
2566  pfree(var->stem);
2567  pfree(var);
2568  var = ptr;
2569  }
2570  }
2571 
2572  return lres;
2573 }
static char ** NormalizeSubWord(IspellDict *Conf, char *word, int flag)
Definition: spell.c:2146
bool usecompound
Definition: spell.h:197
char * pstrdup(const char *in)
Definition: mcxt.c:1161
#define FF_COMPOUNDLAST
Definition: spell.h:45
static void addNorm(TSLexeme **lres, TSLexeme **lcur, char *word, int flags, uint16 NVariant)
Definition: spell.c:2491
#define MAX_NORM
Definition: spell.c:186
unsigned short uint16
Definition: c.h:324
void pfree(void *pointer)
Definition: mcxt.c:1031
int nstem
Definition: spell.c:2257
static SplitVar * SplitToVariants(IspellDict *Conf, SPNode *snode, SplitVar *orig, char *word, int wordlen, int startpos, int minpos)
Definition: spell.c:2344
char ** stem
Definition: spell.c:2259
static void word(struct vars *, int, struct state *, struct state *)
Definition: regcomp.c:1244
int i
struct SplitVar * next
Definition: spell.c:2260

◆ NISortAffixes()

void NISortAffixes ( IspellDict Conf)

Definition at line 1946 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().

1947 {
1948  AFFIX *Affix;
1949  size_t i;
1950  CMPDAffix *ptr;
1951  int firstsuffix = Conf->naffixes;
1952 
1953  if (Conf->naffixes == 0)
1954  return;
1955 
1956  /* Store compound affixes in the Conf->CompoundAffix array */
1957  if (Conf->naffixes > 1)
1958  qsort((void *) Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
1959  Conf->CompoundAffix = ptr = (CMPDAffix *) palloc(sizeof(CMPDAffix) * Conf->naffixes);
1960  ptr->affix = NULL;
1961 
1962  for (i = 0; i < Conf->naffixes; i++)
1963  {
1964  Affix = &(((AFFIX *) Conf->Affix)[i]);
1965  if (Affix->type == FF_SUFFIX && i < firstsuffix)
1966  firstsuffix = i;
1967 
1968  if ((Affix->flagflags & FF_COMPOUNDFLAG) && Affix->replen > 0 &&
1969  isAffixInUse(Conf, Affix->flag))
1970  {
1971  bool issuffix = (Affix->type == FF_SUFFIX);
1972 
1973  if (ptr == Conf->CompoundAffix ||
1974  issuffix != (ptr - 1)->issuffix ||
1975  strbncmp((const unsigned char *) (ptr - 1)->affix,
1976  (const unsigned char *) Affix->repl,
1977  (ptr - 1)->len))
1978  {
1979  /* leave only unique and minimals suffixes */
1980  ptr->affix = Affix->repl;
1981  ptr->len = Affix->replen;
1982  ptr->issuffix = issuffix;
1983  ptr++;
1984  }
1985  }
1986  }
1987  ptr->affix = NULL;
1988  Conf->CompoundAffix = (CMPDAffix *) repalloc(Conf->CompoundAffix, sizeof(CMPDAffix) * (ptr - Conf->CompoundAffix + 1));
1989 
1990  /* Start build a prefix tree */
1991  Conf->Prefix = mkANode(Conf, 0, firstsuffix, 0, FF_PREFIX);
1992  Conf->Suffix = mkANode(Conf, firstsuffix, Conf->naffixes, 0, FF_SUFFIX);
1993  mkVoidAffix(Conf, true, firstsuffix);
1994  mkVoidAffix(Conf, false, firstsuffix);
1995 }
char * flag
Definition: spell.h:89
int naffixes
Definition: spell.h:182
uint32 flagflags
Definition: spell.h:91
AffixNode * Prefix
Definition: spell.h:186
AffixNode * Suffix
Definition: spell.h:185
uint32 type
Definition: spell.h:91
static int strbncmp(const unsigned char *s1, const unsigned char *s2, size_t count)
Definition: spell.c:279
static bool isAffixInUse(IspellDict *Conf, char *affixflag)
Definition: spell.c:1931
int len
Definition: spell.h:145
#define FF_SUFFIX
Definition: spell.h:116
static void mkVoidAffix(IspellDict *Conf, bool issuffix, int startsuffix)
Definition: spell.c:1877
AFFIX * Affix
Definition: spell.h:183
static AffixNode * mkANode(IspellDict *Conf, int low, int high, int level, int type)
Definition: spell.c:1800
char * affix
Definition: spell.h:144
bool issuffix
Definition: spell.h:146
#define FF_PREFIX
Definition: spell.h:117
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1044
CMPDAffix * CompoundAffix
Definition: spell.h:195
void * palloc(Size size)
Definition: mcxt.c:924
int i
char * repl
Definition: spell.h:97
#define FF_COMPOUNDFLAG
Definition: spell.h:46
#define qsort(a, b, c, d)
Definition: port.h:421
uint32 replen
Definition: spell.h:91
static int cmpaffix(const void *s1, const void *s2)
Definition: spell.c:310

◆ NISortDictionary()

void NISortDictionary ( IspellDict Conf)

Definition at line 1702 of file spell.c.

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, IspellDict::useFlagAliases, and spell_struct::word.

Referenced by dispell_init().

1703 {
1704  int i;
1705  int naffix = 0;
1706  int curaffix;
1707 
1708  /* compress affixes */
1709 
1710  /*
1711  * If we use flag aliases then we need to use Conf->AffixData filled in
1712  * the NIImportOOAffixes().
1713  */
1714  if (Conf->useFlagAliases)
1715  {
1716  for (i = 0; i < Conf->nspell; i++)
1717  {
1718  char *end;
1719 
1720  if (*Conf->Spell[i]->p.flag != '\0')
1721  {
1722  curaffix = strtol(Conf->Spell[i]->p.flag, &end, 10);
1723  if (Conf->Spell[i]->p.flag == end || errno == ERANGE)
1724  ereport(ERROR,
1725  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1726  errmsg("invalid affix alias \"%s\"",
1727  Conf->Spell[i]->p.flag)));
1728  }
1729  else
1730  {
1731  /*
1732  * If Conf->Spell[i]->p.flag is empty, then get empty value of
1733  * Conf->AffixData (0 index).
1734  */
1735  curaffix = 0;
1736  }
1737 
1738  Conf->Spell[i]->p.d.affix = curaffix;
1739  Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
1740  }
1741  }
1742  /* Otherwise fill Conf->AffixData here */
1743  else
1744  {
1745  /* Count the number of different flags used in the dictionary */
1746  qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *),
1747  cmpspellaffix);
1748 
1749  naffix = 0;
1750  for (i = 0; i < Conf->nspell; i++)
1751  {
1752  if (i == 0
1753  || strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag))
1754  naffix++;
1755  }
1756 
1757  /*
1758  * Fill in Conf->AffixData with the affixes that were used in the
1759  * dictionary. Replace textual flag-field of Conf->Spell entries with
1760  * indexes into Conf->AffixData array.
1761  */
1762  Conf->AffixData = (char **) palloc0(naffix * sizeof(char *));
1763 
1764  curaffix = -1;
1765  for (i = 0; i < Conf->nspell; i++)
1766  {
1767  if (i == 0
1768  || strcmp(Conf->Spell[i]->p.flag, Conf->AffixData[curaffix]))
1769  {
1770  curaffix++;
1771  Assert(curaffix < naffix);
1772  Conf->AffixData[curaffix] = cpstrdup(Conf,
1773  Conf->Spell[i]->p.flag);
1774  }
1775 
1776  Conf->Spell[i]->p.d.affix = curaffix;
1777  Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
1778  }
1779 
1780  Conf->lenAffixData = Conf->nAffixData = naffix;
1781  }
1782 
1783  /* Start build a prefix tree */
1784  qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
1785  Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
1786 }
int nAffixData
Definition: spell.h:192
static int cmpspell(const void *s1, const void *s2)
Definition: spell.c:196
int lenAffixData
Definition: spell.h:191
bool useFlagAliases
Definition: spell.h:193
static SPNode * mkSPNode(IspellDict *Conf, int low, int high, int level)
Definition: spell.c:1620
int errcode(int sqlerrcode)
Definition: elog.c:575
SPNode * Dictionary
Definition: spell.h:188
int nspell
Definition: spell.h:219
#define ERROR
Definition: elog.h:43
char ** AffixData
Definition: spell.h:190
#define ereport(elevel, rest)
Definition: elog.h:122
char word[FLEXIBLE_ARRAY_MEMBER]
Definition: spell.h:79
struct spell_struct::@120::@121 d
void * palloc0(Size size)
Definition: mcxt.c:955
char * flag
Definition: spell.h:69
union spell_struct::@120 p
#define Assert(condition)
Definition: c.h:699
SPELL ** Spell
Definition: spell.h:218
int errmsg(const char *fmt,...)
Definition: elog.c:797
static char * cpstrdup(IspellDict *Conf, const char *str)
Definition: spell.c:161
static int cmpspellaffix(const void *s1, const void *s2)
Definition: spell.c:202
int i
#define qsort(a, b, c, d)
Definition: port.h:421

◆ NIStartBuild()

void NIStartBuild ( IspellDict Conf)

Definition at line 87 of file spell.c.

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

Referenced by dispell_init().

88 {
89  /*
90  * The temp context is a child of CurTransactionContext, so that it will
91  * go away automatically on error.
92  */
94  "Ispell dictionary init context",
96 }
MemoryContext buildCxt
Definition: spell.h:215
MemoryContext CurTransactionContext
Definition: mcxt.c:50
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
#define AllocSetContextCreate(parent, name, allocparams)
Definition: memutils.h:170