codekingpro/portable-devtools
114k
1/*-------------------------------------------------------------------------2 *3 * spell.h4 *5 * Declarations for ISpell dictionary6 *7 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group8 *9 * src/include/tsearch/dicts/spell.h10 *11 *-------------------------------------------------------------------------12 */13 14#ifndef __SPELL_H__15#define __SPELL_H__16 17#include "regex/regex.h"18#include "tsearch/dicts/regis.h"19#include "tsearch/ts_public.h"20 21/*22 * SPNode and SPNodeData are used to represent prefix tree (Trie) to store23 * a words list.24 */25struct SPNode;26 27typedef struct28{29 uint32 val:8,30 isword:1,31 /* Stores compound flags listed below */32 compoundflag:4,33 /* Reference to an entry of the AffixData field */34 affix:19;35 struct SPNode *node;36} SPNodeData;37 38/*39 * Names of FF_ are correlated with Hunspell options in affix file40 * https://hunspell.github.io/41 */42#define FF_COMPOUNDONLY 0x0143#define FF_COMPOUNDBEGIN 0x0244#define FF_COMPOUNDMIDDLE 0x0445#define FF_COMPOUNDLAST 0x0846#define FF_COMPOUNDFLAG ( FF_COMPOUNDBEGIN | FF_COMPOUNDMIDDLE | \47 FF_COMPOUNDLAST )48#define FF_COMPOUNDFLAGMASK 0x0f49 50typedef struct SPNode51{52 uint32 length;53 SPNodeData data[FLEXIBLE_ARRAY_MEMBER];54} SPNode;55 56#define SPNHDRSZ (offsetof(SPNode,data))57 58/*59 * Represents an entry in a words list.60 */61typedef struct spell_struct62{63 union64 {65 /*66 * flag is filled in by NIImportDictionary(). After67 * NISortDictionary(), d is used instead of flag.68 */69 char *flag;70 /* d is used in mkSPNode() */71 struct72 {73 /* Reference to an entry of the AffixData field */74 int affix;75 /* Length of the word */76 int len;77 } d;78 } p;79 char word[FLEXIBLE_ARRAY_MEMBER];80} SPELL;81 82#define SPELLHDRSZ (offsetof(SPELL, word))83 84/*85 * Represents an entry in an affix list.86 */87typedef struct aff_struct88{89 char *flag;90 /* FF_SUFFIX or FF_PREFIX */91 uint32 type:1,92 flagflags:7,93 issimple:1,94 isregis:1,95 replen:14;96 char *find;97 char *repl;98 union99 {100 /*101 * Arrays of AFFIX are moved and sorted. We'll use a pointer to102 * regex_t to keep this struct small, and avoid assuming that regex_t103 * is movable.104 */105 regex_t *pregex;106 Regis regis;107 } reg;108} AFFIX;109 110/*111 * affixes use dictionary flags too112 */113#define FF_COMPOUNDPERMITFLAG 0x10114#define FF_COMPOUNDFORBIDFLAG 0x20115#define FF_CROSSPRODUCT 0x40116 117/*118 * Don't change the order of these. Initialization sorts by these,119 * and expects prefixes to come first after sorting.120 */121#define FF_SUFFIX 1122#define FF_PREFIX 0123 124/*125 * AffixNode and AffixNodeData are used to represent prefix tree (Trie) to store126 * an affix list.127 */128struct AffixNode;129 130typedef struct131{132 uint32 val:8,133 naff:24;134 AFFIX **aff;135 struct AffixNode *node;136} AffixNodeData;137 138typedef struct AffixNode139{140 uint32 isvoid:1,141 length:31;142 AffixNodeData data[FLEXIBLE_ARRAY_MEMBER];143} AffixNode;144 145#define ANHRDSZ (offsetof(AffixNode, data))146 147typedef struct148{149 char *affix;150 int len;151 bool issuffix;152} CMPDAffix;153 154/*155 * Type of encoding affix flags in Hunspell dictionaries156 */157typedef enum158{159 FM_CHAR, /* one character (like ispell) */160 FM_LONG, /* two characters */161 FM_NUM /* number, >= 0 and < 65536 */162} FlagMode;163 164/*165 * Structure to store Hunspell options. Flag representation depends on flag166 * type. These flags are about support of compound words.167 */168typedef struct CompoundAffixFlag169{170 union171 {172 /* Flag name if flagMode is FM_CHAR or FM_LONG */173 char *s;174 /* Flag name if flagMode is FM_NUM */175 uint32 i;176 } flag;177 /* we don't have a bsearch_arg version, so, copy FlagMode */178 FlagMode flagMode;179 uint32 value;180} CompoundAffixFlag;181 182#define FLAGNUM_MAXSIZE (1 << 16)183 184typedef struct185{186 int maffixes;187 int naffixes;188 AFFIX *Affix;189 190 AffixNode *Suffix;191 AffixNode *Prefix;192 193 SPNode *Dictionary;194 /* Array of sets of affixes */195 char **AffixData;196 int lenAffixData;197 int nAffixData;198 bool useFlagAliases;199 200 CMPDAffix *CompoundAffix;201 202 bool usecompound;203 FlagMode flagMode;204 205 /*206 * All follow fields are actually needed only for initialization207 */208 209 /* Array of Hunspell options in affix file */210 CompoundAffixFlag *CompoundAffixFlags;211 /* number of entries in CompoundAffixFlags array */212 int nCompoundAffixFlag;213 /* allocated length of CompoundAffixFlags array */214 int mCompoundAffixFlag;215 216 /*217 * Remaining fields are only used during dictionary construction; they are218 * set up by NIStartBuild and cleared by NIFinishBuild.219 */220 MemoryContext buildCxt; /* temp context for construction */221 222 /* Temporary array of all words in the dict file */223 SPELL **Spell;224 int nspell; /* number of valid entries in Spell array */225 int mspell; /* allocated length of Spell array */226 227 /* These are used to allocate "compact" data without palloc overhead */228 char *firstfree; /* first free address (always maxaligned) */229 size_t avail; /* free space remaining at firstfree */230} IspellDict;231 232extern TSLexeme *NINormalizeWord(IspellDict *Conf, char *word);233 234extern void NIStartBuild(IspellDict *Conf);235extern void NIImportAffixes(IspellDict *Conf, const char *filename);236extern void NIImportDictionary(IspellDict *Conf, const char *filename);237extern void NISortDictionary(IspellDict *Conf);238extern void NISortAffixes(IspellDict *Conf);239extern void NIFinishBuild(IspellDict *Conf);240 241#endif242 