PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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, const 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 104 of file spell.c.

105{
106 /* Release no-longer-needed temp memory */
108 /* Just for cleanliness, zero the now-dangling pointers */
109 Conf->buildCxt = NULL;
110 Conf->Spell = NULL;
111 Conf->firstfree = NULL;
112 Conf->CompoundAffixFlags = NULL;
113}
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 1426 of file spell.c.

1427{
1428 char *pstr = NULL;
1429 char flag[BUFSIZ];
1430 char mask[BUFSIZ];
1431 char find[BUFSIZ];
1432 char repl[BUFSIZ];
1433 char *s;
1434 bool suffixes = false;
1435 bool prefixes = false;
1436 char flagflags = 0;
1438 bool oldformat = false;
1439 char *recoded = NULL;
1440
1441 if (!tsearch_readline_begin(&trst, filename))
1442 ereport(ERROR,
1443 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1444 errmsg("could not open affix file \"%s\": %m",
1445 filename)));
1446
1447 Conf->usecompound = false;
1448 Conf->useFlagAliases = false;
1449 Conf->flagMode = FM_CHAR;
1450
1451 while ((recoded = tsearch_readline(&trst)) != NULL)
1452 {
1453 pstr = str_tolower(recoded, strlen(recoded), DEFAULT_COLLATION_OID);
1454
1455 /* Skip comments and empty lines */
1456 if (*pstr == '#' || *pstr == '\n')
1457 goto nextline;
1458
1459 if (STRNCMP(pstr, "compoundwords") == 0)
1460 {
1461 /* Find case-insensitive L flag in non-lowercased string */
1462 s = findchar2(recoded, 'l', 'L');
1463 if (s)
1464 {
1465 while (*s && !isspace((unsigned char) *s))
1466 s += pg_mblen(s);
1467 while (*s && isspace((unsigned char) *s))
1468 s += pg_mblen(s);
1469
1470 if (*s && pg_mblen(s) == 1)
1471 {
1473 Conf->usecompound = true;
1474 }
1475 oldformat = true;
1476 goto nextline;
1477 }
1478 }
1479 if (STRNCMP(pstr, "suffixes") == 0)
1480 {
1481 suffixes = true;
1482 prefixes = false;
1483 oldformat = true;
1484 goto nextline;
1485 }
1486 if (STRNCMP(pstr, "prefixes") == 0)
1487 {
1488 suffixes = false;
1489 prefixes = true;
1490 oldformat = true;
1491 goto nextline;
1492 }
1493 if (STRNCMP(pstr, "flag") == 0)
1494 {
1495 s = recoded + 4; /* we need non-lowercased string */
1496 flagflags = 0;
1497
1498 while (*s && isspace((unsigned char) *s))
1499 s += pg_mblen(s);
1500
1501 if (*s == '*')
1502 {
1503 flagflags |= FF_CROSSPRODUCT;
1504 s++;
1505 }
1506 else if (*s == '~')
1507 {
1508 flagflags |= FF_COMPOUNDONLY;
1509 s++;
1510 }
1511
1512 if (*s == '\\')
1513 s++;
1514
1515 /*
1516 * An old-format flag is a single ASCII character; we expect it to
1517 * be followed by EOL, whitespace, or ':'. Otherwise this is a
1518 * new-format flag command.
1519 */
1520 if (*s && pg_mblen(s) == 1)
1521 {
1522 COPYCHAR(flag, s);
1523 flag[1] = '\0';
1524
1525 s++;
1526 if (*s == '\0' || *s == '#' || *s == '\n' || *s == ':' ||
1527 isspace((unsigned char) *s))
1528 {
1529 oldformat = true;
1530 goto nextline;
1531 }
1532 }
1533 goto isnewformat;
1534 }
1535 if (STRNCMP(recoded, "COMPOUNDFLAG") == 0 ||
1536 STRNCMP(recoded, "COMPOUNDMIN") == 0 ||
1537 STRNCMP(recoded, "PFX") == 0 ||
1538 STRNCMP(recoded, "SFX") == 0)
1539 goto isnewformat;
1540
1541 if ((!suffixes) && (!prefixes))
1542 goto nextline;
1543
1544 if (!parse_affentry(pstr, mask, find, repl))
1545 goto nextline;
1546
1547 NIAddAffix(Conf, flag, flagflags, mask, find, repl, suffixes ? FF_SUFFIX : FF_PREFIX);
1548
1549nextline:
1550 pfree(recoded);
1551 pfree(pstr);
1552 }
1553 tsearch_readline_end(&trst);
1554 return;
1555
1556isnewformat:
1557 if (oldformat)
1558 ereport(ERROR,
1559 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1560 errmsg("affix file contains both old-style and new-style commands")));
1561 tsearch_readline_end(&trst);
1562
1564}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
char * str_tolower(const char *buff, size_t nbytes, Oid collid)
Definition: formatting.c:1591
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023
void pfree(void *pointer)
Definition: mcxt.c:1521
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 void NIImportOOAffixes(IspellDict *Conf, const char *filename)
Definition: spell.c:1197
static void NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask, const char *find, const char *repl, int type)
Definition: spell.c:678
#define STRNCMP(s, p)
Definition: spell.c:191
static char * findchar2(char *str, int c1, int c2)
Definition: spell.c:243
static bool parse_affentry(char *str, char *mask, char *find, char *repl)
Definition: spell.c:914
static void addCompoundAffixFlagValue(IspellDict *Conf, char *s, uint32 val)
Definition: spell.c:1067
#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:89
char * tsearch_readline(tsearch_readline_state *stp)
Definition: ts_locale.c:112
void tsearch_readline_end(tsearch_readline_state *stp)
Definition: ts_locale.c:157
#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, NIAddAffix(), NIImportOOAffixes(), parse_affentry(), pfree(), pg_mblen(), prefixes(), str_tolower(), STRNCMP, 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 518 of file spell.c.

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

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

Referenced by dispell_init().

◆ NINormalizeWord()

TSLexeme * NINormalizeWord ( IspellDict Conf,
const char *  word 
)

Definition at line 2541 of file spell.c.

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

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 1977 of file spell.c.

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

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 1723 of file spell.c.

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

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

Referenced by dispell_init().

◆ NIStartBuild()

void NIStartBuild ( IspellDict Conf)

Definition at line 89 of file spell.c.

90{
91 /*
92 * The temp context is a child of CurTransactionContext, so that it will
93 * go away automatically on error.
94 */
96 "Ispell dictionary init context",
98}
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().