PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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

#define ANHRDSZ   (offsetof(AffixNode, data))

Definition at line 140 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
Value:
#define FF_COMPOUNDLAST
Definition: spell.h:45
#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().

#define FF_COMPOUNDFLAGMASK   0x0f

Definition at line 48 of file spell.h.

Referenced by FindWord(), and makeCompoundFlags().

#define FF_COMPOUNDFORBIDFLAG   0x20

Definition at line 109 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(), NINormalizeWord(), and SplitToVariants().

#define FF_COMPOUNDMIDDLE   0x04

Definition at line 44 of file spell.h.

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

#define FF_COMPOUNDONLY   0x01

Definition at line 42 of file spell.h.

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

#define FF_COMPOUNDPERMITFLAG   0x10

Definition at line 108 of file spell.h.

Referenced by NIAddAffix(), and NIImportOOAffixes().

#define FF_CROSSPRODUCT   0x40

Definition at line 110 of file spell.h.

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

#define FF_PREFIX   0
#define FF_SUFFIX   1
#define FLAGNUM_MAXSIZE   (1 << 16)

Definition at line 177 of file spell.h.

Referenced by getNextFlagFromString(), and setCompoundAffixFlagValue().

#define SPELLHDRSZ   (offsetof(SPELL, word))

Definition at line 82 of file spell.h.

Referenced by NIAddSpell().

#define SPNHDRSZ   (offsetof(SPNode,data))

Definition at line 56 of file spell.h.

Referenced by mkSPNode().

Typedef Documentation

Enumeration Type Documentation

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

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:200
CompoundAffixFlag * CompoundAffixFlags
Definition: spell.h:205
char * firstfree
Definition: spell.h:223
SPELL ** Spell
Definition: spell.h:218
void NIImportAffixes ( IspellDict Conf,
const char *  filename 
)

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

1409 {
1410  char *pstr = NULL;
1411  char flag[BUFSIZ];
1412  char mask[BUFSIZ];
1413  char find[BUFSIZ];
1414  char repl[BUFSIZ];
1415  char *s;
1416  bool suffixes = false;
1417  bool prefixes = false;
1418  char flagflags = 0;
1420  bool oldformat = false;
1421  char *recoded = NULL;
1422 
1423  if (!tsearch_readline_begin(&trst, filename))
1424  ereport(ERROR,
1425  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1426  errmsg("could not open affix file \"%s\": %m",
1427  filename)));
1428 
1429  Conf->usecompound = false;
1430  Conf->useFlagAliases = false;
1431  Conf->flagMode = FM_CHAR;
1432 
1433  while ((recoded = tsearch_readline(&trst)) != NULL)
1434  {
1435  pstr = lowerstr(recoded);
1436 
1437  /* Skip comments and empty lines */
1438  if (*pstr == '#' || *pstr == '\n')
1439  goto nextline;
1440 
1441  if (STRNCMP(pstr, "compoundwords") == 0)
1442  {
1443  /* Find case-insensitive L flag in non-lowercased string */
1444  s = findchar2(recoded, 'l', 'L');
1445  if (s)
1446  {
1447  while (*s && !t_isspace(s))
1448  s += pg_mblen(s);
1449  while (*s && t_isspace(s))
1450  s += pg_mblen(s);
1451 
1452  if (*s && pg_mblen(s) == 1)
1453  {
1455  Conf->usecompound = true;
1456  }
1457  oldformat = true;
1458  goto nextline;
1459  }
1460  }
1461  if (STRNCMP(pstr, "suffixes") == 0)
1462  {
1463  suffixes = true;
1464  prefixes = false;
1465  oldformat = true;
1466  goto nextline;
1467  }
1468  if (STRNCMP(pstr, "prefixes") == 0)
1469  {
1470  suffixes = false;
1471  prefixes = true;
1472  oldformat = true;
1473  goto nextline;
1474  }
1475  if (STRNCMP(pstr, "flag") == 0)
1476  {
1477  s = recoded + 4; /* we need non-lowercased string */
1478  flagflags = 0;
1479 
1480  while (*s && t_isspace(s))
1481  s += pg_mblen(s);
1482 
1483  if (*s == '*')
1484  {
1485  flagflags |= FF_CROSSPRODUCT;
1486  s++;
1487  }
1488  else if (*s == '~')
1489  {
1490  flagflags |= FF_COMPOUNDONLY;
1491  s++;
1492  }
1493 
1494  if (*s == '\\')
1495  s++;
1496 
1497  /*
1498  * An old-format flag is a single ASCII character; we expect it to
1499  * be followed by EOL, whitespace, or ':'. Otherwise this is a
1500  * new-format flag command.
1501  */
1502  if (*s && pg_mblen(s) == 1)
1503  {
1504  COPYCHAR(flag, s);
1505  flag[1] = '\0';
1506 
1507  s++;
1508  if (*s == '\0' || *s == '#' || *s == '\n' || *s == ':' ||
1509  t_isspace(s))
1510  {
1511  oldformat = true;
1512  goto nextline;
1513  }
1514  }
1515  goto isnewformat;
1516  }
1517  if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 ||
1518  STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
1519  STRNCMP(recoded, "PFX") == 0 ||
1520  STRNCMP(recoded, "SFX") == 0)
1521  goto isnewformat;
1522 
1523  if ((!suffixes) && (!prefixes))
1524  goto nextline;
1525 
1526  if (!parse_affentry(pstr, mask, find, repl))
1527  goto nextline;
1528 
1529  NIAddAffix(Conf, flag, flagflags, mask, find, repl, suffixes ? FF_SUFFIX : FF_PREFIX);
1530 
1531 nextline:
1532  pfree(recoded);
1533  pfree(pstr);
1534  }
1535  tsearch_readline_end(&trst);
1536  return;
1537 
1538 isnewformat:
1539  if (oldformat)
1540  ereport(ERROR,
1541  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1542  errmsg("affix file contains both old-style and new-style commands")));
1543  tsearch_readline_end(&trst);
1544 
1545  NIImportOOAffixes(Conf, filename);
1546 }
#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:949
#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:771
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:90
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define FF_COMPOUNDFLAG
Definition: spell.h:46
FlagMode flagMode
Definition: spell.h:198
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:949
#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:771
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:90
int errmsg(const char *fmt,...)
Definition: elog.c:797
TSLexeme* NINormalizeWord ( IspellDict Conf,
char *  word 
)

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

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

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

1942 {
1943  AFFIX *Affix;
1944  size_t i;
1945  CMPDAffix *ptr;
1946  int firstsuffix = Conf->naffixes;
1947 
1948  if (Conf->naffixes == 0)
1949  return;
1950 
1951  /* Store compound affixes in the Conf->CompoundAffix array */
1952  if (Conf->naffixes > 1)
1953  qsort((void *) Conf->Affix, Conf->naffixes, sizeof(AFFIX), cmpaffix);
1954  Conf->CompoundAffix = ptr = (CMPDAffix *) palloc(sizeof(CMPDAffix) * Conf->naffixes);
1955  ptr->affix = NULL;
1956 
1957  for (i = 0; i < Conf->naffixes; i++)
1958  {
1959  Affix = &(((AFFIX *) Conf->Affix)[i]);
1960  if (Affix->type == FF_SUFFIX && i < firstsuffix)
1961  firstsuffix = i;
1962 
1963  if ((Affix->flagflags & FF_COMPOUNDFLAG) && Affix->replen > 0 &&
1964  isAffixInUse(Conf, Affix->flag))
1965  {
1966  if (ptr == Conf->CompoundAffix ||
1967  ptr->issuffix != (ptr - 1)->issuffix ||
1968  strbncmp((const unsigned char *) (ptr - 1)->affix,
1969  (const unsigned char *) Affix->repl,
1970  (ptr - 1)->len))
1971  {
1972  /* leave only unique and minimals suffixes */
1973  ptr->affix = Affix->repl;
1974  ptr->len = Affix->replen;
1975  ptr->issuffix = (Affix->type == FF_SUFFIX);
1976  ptr++;
1977  }
1978  }
1979  }
1980  ptr->affix = NULL;
1981  Conf->CompoundAffix = (CMPDAffix *) repalloc(Conf->CompoundAffix, sizeof(CMPDAffix) * (ptr - Conf->CompoundAffix + 1));
1982 
1983  /* Start build a prefix tree */
1984  Conf->Prefix = mkANode(Conf, 0, firstsuffix, 0, FF_PREFIX);
1985  Conf->Suffix = mkANode(Conf, firstsuffix, Conf->naffixes, 0, FF_SUFFIX);
1986  mkVoidAffix(Conf, true, firstsuffix);
1987  mkVoidAffix(Conf, false, firstsuffix);
1988 }
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:1926
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:1872
AFFIX * Affix
Definition: spell.h:183
static AffixNode * mkANode(IspellDict *Conf, int low, int high, int level, int type)
Definition: spell.c:1795
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:962
CMPDAffix * CompoundAffix
Definition: spell.h:195
void * palloc(Size size)
Definition: mcxt.c:848
int i
char * repl
Definition: spell.h:97
#define FF_COMPOUNDFLAG
Definition: spell.h:46
#define qsort(a, b, c, d)
Definition: port.h:443
uint32 replen
Definition: spell.h:91
static int cmpaffix(const void *s1, const void *s2)
Definition: spell.c:310
void NISortDictionary ( IspellDict Conf)

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

1698 {
1699  int i;
1700  int naffix = 0;
1701  int curaffix;
1702 
1703  /* compress affixes */
1704 
1705  /*
1706  * If we use flag aliases then we need to use Conf->AffixData filled in
1707  * the NIImportOOAffixes().
1708  */
1709  if (Conf->useFlagAliases)
1710  {
1711  for (i = 0; i < Conf->nspell; i++)
1712  {
1713  char *end;
1714 
1715  if (*Conf->Spell[i]->p.flag != '\0')
1716  {
1717  curaffix = strtol(Conf->Spell[i]->p.flag, &end, 10);
1718  if (Conf->Spell[i]->p.flag == end || errno == ERANGE)
1719  ereport(ERROR,
1720  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1721  errmsg("invalid affix alias \"%s\"",
1722  Conf->Spell[i]->p.flag)));
1723  }
1724  else
1725  {
1726  /*
1727  * If Conf->Spell[i]->p.flag is empty, then get empty value of
1728  * Conf->AffixData (0 index).
1729  */
1730  curaffix = 0;
1731  }
1732 
1733  Conf->Spell[i]->p.d.affix = curaffix;
1734  Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
1735  }
1736  }
1737  /* Otherwise fill Conf->AffixData here */
1738  else
1739  {
1740  /* Count the number of different flags used in the dictionary */
1741  qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *),
1742  cmpspellaffix);
1743 
1744  naffix = 0;
1745  for (i = 0; i < Conf->nspell; i++)
1746  {
1747  if (i == 0
1748  || strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag))
1749  naffix++;
1750  }
1751 
1752  /*
1753  * Fill in Conf->AffixData with the affixes that were used in the
1754  * dictionary. Replace textual flag-field of Conf->Spell entries with
1755  * indexes into Conf->AffixData array.
1756  */
1757  Conf->AffixData = (char **) palloc0(naffix * sizeof(char *));
1758 
1759  curaffix = -1;
1760  for (i = 0; i < Conf->nspell; i++)
1761  {
1762  if (i == 0
1763  || strcmp(Conf->Spell[i]->p.flag, Conf->AffixData[curaffix]))
1764  {
1765  curaffix++;
1766  Assert(curaffix < naffix);
1767  Conf->AffixData[curaffix] = cpstrdup(Conf,
1768  Conf->Spell[i]->p.flag);
1769  }
1770 
1771  Conf->Spell[i]->p.d.affix = curaffix;
1772  Conf->Spell[i]->p.d.len = strlen(Conf->Spell[i]->word);
1773  }
1774 
1775  Conf->lenAffixData = Conf->nAffixData = naffix;
1776  }
1777 
1778  /* Start build a prefix tree */
1779  qsort((void *) Conf->Spell, Conf->nspell, sizeof(SPELL *), cmpspell);
1780  Conf->Dictionary = mkSPNode(Conf, 0, Conf->nspell, 0);
1781 }
int nAffixData
Definition: spell.h:192
struct spell_struct::@110::@111 d
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:1615
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
void * palloc0(Size size)
Definition: mcxt.c:877
char * flag
Definition: spell.h:69
#define Assert(condition)
Definition: c.h:664
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:443
union spell_struct::@110 p
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:49
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322