aboutsummaryrefslogtreecommitdiff
path: root/src/spell.c
diff options
context:
space:
mode:
authorEliseo Martínez <eliseomarmol@gmail.com>2014-05-12 02:25:17 +0200
committerEliseo Martínez <eliseomarmol@gmail.com>2014-05-15 20:46:01 +0200
commitda51dc9cf202772f60bd2da975dbef257bd9237c (patch)
tree5c16b93238a153f55634e9323077f30c8133970c /src/spell.c
parentffe61e5ba1721340ca51d56bae3ddaca415fb5bc (diff)
downloadrneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.gz
rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.tar.bz2
rneovim-da51dc9cf202772f60bd2da975dbef257bd9237c.zip
Introduce nvim namespace: Move files.
Move files from src/ to src/nvim/. - src/nvim/ becomes the new root dir for nvim executable sources. - src/libnvim/ is planned to become root dir of the neovim library.
Diffstat (limited to 'src/spell.c')
-rw-r--r--src/spell.c13611
1 files changed, 0 insertions, 13611 deletions
diff --git a/src/spell.c b/src/spell.c
deleted file mode 100644
index 5392fe4a70..0000000000
--- a/src/spell.c
+++ /dev/null
@@ -1,13611 +0,0 @@
-// VIM - Vi IMproved by Bram Moolenaar
-//
-// Do ":help uganda" in Vim to read copying and usage conditions.
-// Do ":help credits" in Vim to see a list of people who contributed.
-// See README.txt for an overview of the Vim source code.
-
-// spell.c: code for spell checking
-//
-// The spell checking mechanism uses a tree (aka trie). Each node in the tree
-// has a list of bytes that can appear (siblings). For each byte there is a
-// pointer to the node with the byte that follows in the word (child).
-//
-// A NUL byte is used where the word may end. The bytes are sorted, so that
-// binary searching can be used and the NUL bytes are at the start. The
-// number of possible bytes is stored before the list of bytes.
-//
-// The tree uses two arrays: "byts" stores the characters, "idxs" stores
-// either the next index or flags. The tree starts at index 0. For example,
-// to lookup "vi" this sequence is followed:
-// i = 0
-// len = byts[i]
-// n = where "v" appears in byts[i + 1] to byts[i + len]
-// i = idxs[n]
-// len = byts[i]
-// n = where "i" appears in byts[i + 1] to byts[i + len]
-// i = idxs[n]
-// len = byts[i]
-// find that byts[i + 1] is 0, idxs[i + 1] has flags for "vi".
-//
-// There are two word trees: one with case-folded words and one with words in
-// original case. The second one is only used for keep-case words and is
-// usually small.
-//
-// There is one additional tree for when not all prefixes are applied when
-// generating the .spl file. This tree stores all the possible prefixes, as
-// if they were words. At each word (prefix) end the prefix nr is stored, the
-// following word must support this prefix nr. And the condition nr is
-// stored, used to lookup the condition that the word must match with.
-//
-// Thanks to Olaf Seibert for providing an example implementation of this tree
-// and the compression mechanism.
-// LZ trie ideas:
-// http://www.irb.hr/hr/home/ristov/papers/RistovLZtrieRevision1.pdf
-// More papers: http://www-igm.univ-mlv.fr/~laporte/publi_en.html
-//
-// Matching involves checking the caps type: Onecap ALLCAP KeepCap.
-//
-// Why doesn't Vim use aspell/ispell/myspell/etc.?
-// See ":help develop-spell".
-
-// Use SPELL_PRINTTREE for debugging: dump the word tree after adding a word.
-// Only use it for small word lists!
-
-// Use DEBUG_TRIEWALK to print the changes made in suggest_trie_walk() for a
-// specific word.
-
-// Use this to adjust the score after finding suggestions, based on the
-// suggested word sounding like the bad word. This is much faster than doing
-// it for every possible suggestion.
-// Disadvantage: When "the" is typed as "hte" it sounds quite different ("@"
-// vs "ht") and goes down in the list.
-// Used when 'spellsuggest' is set to "best".
-#define RESCORE(word_score, sound_score) ((3 * word_score + sound_score) / 4)
-
-// Do the opposite: based on a maximum end score and a known sound score,
-// compute the maximum word score that can be used.
-#define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3)
-
-// Vim spell file format: <HEADER>
-// <SECTIONS>
-// <LWORDTREE>
-// <KWORDTREE>
-// <PREFIXTREE>
-//
-// <HEADER>: <fileID> <versionnr>
-//
-// <fileID> 8 bytes "VIMspell"
-// <versionnr> 1 byte VIMSPELLVERSION
-//
-//
-// Sections make it possible to add information to the .spl file without
-// making it incompatible with previous versions. There are two kinds of
-// sections:
-// 1. Not essential for correct spell checking. E.g. for making suggestions.
-// These are skipped when not supported.
-// 2. Optional information, but essential for spell checking when present.
-// E.g. conditions for affixes. When this section is present but not
-// supported an error message is given.
-//
-// <SECTIONS>: <section> ... <sectionend>
-//
-// <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
-//
-// <sectionID> 1 byte number from 0 to 254 identifying the section
-//
-// <sectionflags> 1 byte SNF_REQUIRED: this section is required for correct
-// spell checking
-//
-// <sectionlen> 4 bytes length of section contents, MSB first
-//
-// <sectionend> 1 byte SN_END
-//
-//
-// sectionID == SN_INFO: <infotext>
-// <infotext> N bytes free format text with spell file info (version,
-// website, etc)
-//
-// sectionID == SN_REGION: <regionname> ...
-// <regionname> 2 bytes Up to 8 region names: ca, au, etc. Lower case.
-// First <regionname> is region 1.
-//
-// sectionID == SN_CHARFLAGS: <charflagslen> <charflags>
-// <folcharslen> <folchars>
-// <charflagslen> 1 byte Number of bytes in <charflags> (should be 128).
-// <charflags> N bytes List of flags (first one is for character 128):
-// 0x01 word character CF_WORD
-// 0x02 upper-case character CF_UPPER
-// <folcharslen> 2 bytes Number of bytes in <folchars>.
-// <folchars> N bytes Folded characters, first one is for character 128.
-//
-// sectionID == SN_MIDWORD: <midword>
-// <midword> N bytes Characters that are word characters only when used
-// in the middle of a word.
-//
-// sectionID == SN_PREFCOND: <prefcondcnt> <prefcond> ...
-// <prefcondcnt> 2 bytes Number of <prefcond> items following.
-// <prefcond> : <condlen> <condstr>
-// <condlen> 1 byte Length of <condstr>.
-// <condstr> N bytes Condition for the prefix.
-//
-// sectionID == SN_REP: <repcount> <rep> ...
-// <repcount> 2 bytes number of <rep> items, MSB first.
-// <rep> : <repfromlen> <repfrom> <reptolen> <repto>
-// <repfromlen> 1 byte length of <repfrom>
-// <repfrom> N bytes "from" part of replacement
-// <reptolen> 1 byte length of <repto>
-// <repto> N bytes "to" part of replacement
-//
-// sectionID == SN_REPSAL: <repcount> <rep> ...
-// just like SN_REP but for soundfolded words
-//
-// sectionID == SN_SAL: <salflags> <salcount> <sal> ...
-// <salflags> 1 byte flags for soundsalike conversion:
-// SAL_F0LLOWUP
-// SAL_COLLAPSE
-// SAL_REM_ACCENTS
-// <salcount> 2 bytes number of <sal> items following
-// <sal> : <salfromlen> <salfrom> <saltolen> <salto>
-// <salfromlen> 1 byte length of <salfrom>
-// <salfrom> N bytes "from" part of soundsalike
-// <saltolen> 1 byte length of <salto>
-// <salto> N bytes "to" part of soundsalike
-//
-// sectionID == SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
-// <sofofromlen> 2 bytes length of <sofofrom>
-// <sofofrom> N bytes "from" part of soundfold
-// <sofotolen> 2 bytes length of <sofoto>
-// <sofoto> N bytes "to" part of soundfold
-//
-// sectionID == SN_SUGFILE: <timestamp>
-// <timestamp> 8 bytes time in seconds that must match with .sug file
-//
-// sectionID == SN_NOSPLITSUGS: nothing
-//
-// sectionID == SN_WORDS: <word> ...
-// <word> N bytes NUL terminated common word
-//
-// sectionID == SN_MAP: <mapstr>
-// <mapstr> N bytes String with sequences of similar characters,
-// separated by slashes.
-//
-// sectionID == SN_COMPOUND: <compmax> <compminlen> <compsylmax> <compoptions>
-// <comppatcount> <comppattern> ... <compflags>
-// <compmax> 1 byte Maximum nr of words in compound word.
-// <compminlen> 1 byte Minimal word length for compounding.
-// <compsylmax> 1 byte Maximum nr of syllables in compound word.
-// <compoptions> 2 bytes COMP_ flags.
-// <comppatcount> 2 bytes number of <comppattern> following
-// <compflags> N bytes Flags from COMPOUNDRULE items, separated by
-// slashes.
-//
-// <comppattern>: <comppatlen> <comppattext>
-// <comppatlen> 1 byte length of <comppattext>
-// <comppattext> N bytes end or begin chars from CHECKCOMPOUNDPATTERN
-//
-// sectionID == SN_NOBREAK: (empty, its presence is what matters)
-//
-// sectionID == SN_SYLLABLE: <syllable>
-// <syllable> N bytes String from SYLLABLE item.
-//
-// <LWORDTREE>: <wordtree>
-//
-// <KWORDTREE>: <wordtree>
-//
-// <PREFIXTREE>: <wordtree>
-//
-//
-// <wordtree>: <nodecount> <nodedata> ...
-//
-// <nodecount> 4 bytes Number of nodes following. MSB first.
-//
-// <nodedata>: <siblingcount> <sibling> ...
-//
-// <siblingcount> 1 byte Number of siblings in this node. The siblings
-// follow in sorted order.
-//
-// <sibling>: <byte> [ <nodeidx> <xbyte>
-// | <flags> [<flags2>] [<region>] [<affixID>]
-// | [<pflags>] <affixID> <prefcondnr> ]
-//
-// <byte> 1 byte Byte value of the sibling. Special cases:
-// BY_NOFLAGS: End of word without flags and for all
-// regions.
-// For PREFIXTREE <affixID> and
-// <prefcondnr> follow.
-// BY_FLAGS: End of word, <flags> follow.
-// For PREFIXTREE <pflags>, <affixID>
-// and <prefcondnr> follow.
-// BY_FLAGS2: End of word, <flags> and <flags2>
-// follow. Not used in PREFIXTREE.
-// BY_INDEX: Child of sibling is shared, <nodeidx>
-// and <xbyte> follow.
-//
-// <nodeidx> 3 bytes Index of child for this sibling, MSB first.
-//
-// <xbyte> 1 byte Byte value of the sibling.
-//
-// <flags> 1 byte Bitmask of:
-// WF_ALLCAP word must have only capitals
-// WF_ONECAP first char of word must be capital
-// WF_KEEPCAP keep-case word
-// WF_FIXCAP keep-case word, all caps not allowed
-// WF_RARE rare word
-// WF_BANNED bad word
-// WF_REGION <region> follows
-// WF_AFX <affixID> follows
-//
-// <flags2> 1 byte Bitmask of:
-// WF_HAS_AFF >> 8 word includes affix
-// WF_NEEDCOMP >> 8 word only valid in compound
-// WF_NOSUGGEST >> 8 word not used for suggestions
-// WF_COMPROOT >> 8 word already a compound
-// WF_NOCOMPBEF >> 8 no compounding before this word
-// WF_NOCOMPAFT >> 8 no compounding after this word
-//
-// <pflags> 1 byte Bitmask of:
-// WFP_RARE rare prefix
-// WFP_NC non-combining prefix
-// WFP_UP letter after prefix made upper case
-//
-// <region> 1 byte Bitmask for regions in which word is valid. When
-// omitted it's valid in all regions.
-// Lowest bit is for region 1.
-//
-// <affixID> 1 byte ID of affix that can be used with this word. In
-// PREFIXTREE used for the required prefix ID.
-//
-// <prefcondnr> 2 bytes Prefix condition number, index in <prefcond> list
-// from HEADER.
-//
-// All text characters are in 'encoding', but stored as single bytes.
-
-// Vim .sug file format: <SUGHEADER>
-// <SUGWORDTREE>
-// <SUGTABLE>
-//
-// <SUGHEADER>: <fileID> <versionnr> <timestamp>
-//
-// <fileID> 6 bytes "VIMsug"
-// <versionnr> 1 byte VIMSUGVERSION
-// <timestamp> 8 bytes timestamp that must match with .spl file
-//
-//
-// <SUGWORDTREE>: <wordtree> (see above, no flags or region used)
-//
-//
-// <SUGTABLE>: <sugwcount> <sugline> ...
-//
-// <sugwcount> 4 bytes number of <sugline> following
-//
-// <sugline>: <sugnr> ... NUL
-//
-// <sugnr>: X bytes word number that results in this soundfolded word,
-// stored as an offset to the previous number in as
-// few bytes as possible, see offset2bytes())
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "vim.h"
-#include "spell.h"
-#include "buffer.h"
-#include "charset.h"
-#include "edit.h"
-#include "eval.h"
-#include "ex_cmds.h"
-#include "ex_cmds2.h"
-#include "ex_docmd.h"
-#include "fileio.h"
-#include "getchar.h"
-#include "hashtab.h"
-#include "mbyte.h"
-#include "memline.h"
-#include "memory.h"
-#include "message.h"
-#include "misc1.h"
-#include "misc2.h"
-#include "garray.h"
-#include "normal.h"
-#include "option.h"
-#include "os_unix.h"
-#include "path.h"
-#include "regexp.h"
-#include "screen.h"
-#include "search.h"
-#include "syntax.h"
-#include "term.h"
-#include "ui.h"
-#include "undo.h"
-#include "os/os.h"
-
-#ifndef UNIX // it's in os_unix_defs.h for Unix
-# include <time.h> // for time_t
-#endif
-
-#define MAXWLEN 250 // Assume max. word len is this many bytes.
- // Some places assume a word length fits in a
- // byte, thus it can't be above 255.
-
-// Type used for indexes in the word tree need to be at least 4 bytes. If int
-// is 8 bytes we could use something smaller, but what?
-typedef int idx_T;
-
-# define SPL_FNAME_TMPL "%s.%s.spl"
-# define SPL_FNAME_ADD ".add."
-# define SPL_FNAME_ASCII ".ascii."
-
-// Flags used for a word. Only the lowest byte can be used, the region byte
-// comes above it.
-#define WF_REGION 0x01 // region byte follows
-#define WF_ONECAP 0x02 // word with one capital (or all capitals)
-#define WF_ALLCAP 0x04 // word must be all capitals
-#define WF_RARE 0x08 // rare word
-#define WF_BANNED 0x10 // bad word
-#define WF_AFX 0x20 // affix ID follows
-#define WF_FIXCAP 0x40 // keep-case word, allcap not allowed
-#define WF_KEEPCAP 0x80 // keep-case word
-
-// for <flags2>, shifted up one byte to be used in wn_flags
-#define WF_HAS_AFF 0x0100 // word includes affix
-#define WF_NEEDCOMP 0x0200 // word only valid in compound
-#define WF_NOSUGGEST 0x0400 // word not to be suggested
-#define WF_COMPROOT 0x0800 // already compounded word, COMPOUNDROOT
-#define WF_NOCOMPBEF 0x1000 // no compounding before this word
-#define WF_NOCOMPAFT 0x2000 // no compounding after this word
-
-// only used for su_badflags
-#define WF_MIXCAP 0x20 // mix of upper and lower case: macaRONI
-
-#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP)
-
-// flags for <pflags>
-#define WFP_RARE 0x01 // rare prefix
-#define WFP_NC 0x02 // prefix is not combining
-#define WFP_UP 0x04 // to-upper prefix
-#define WFP_COMPPERMIT 0x08 // prefix with COMPOUNDPERMITFLAG
-#define WFP_COMPFORBID 0x10 // prefix with COMPOUNDFORBIDFLAG
-
-// Flags for postponed prefixes in "sl_pidxs". Must be above affixID (one
-// byte) and prefcondnr (two bytes).
-#define WF_RAREPFX (WFP_RARE << 24) // rare postponed prefix
-#define WF_PFX_NC (WFP_NC << 24) // non-combining postponed prefix
-#define WF_PFX_UP (WFP_UP << 24) // to-upper postponed prefix
-#define WF_PFX_COMPPERMIT (WFP_COMPPERMIT << 24) // postponed prefix with
- // COMPOUNDPERMITFLAG
-#define WF_PFX_COMPFORBID (WFP_COMPFORBID << 24) // postponed prefix with
- // COMPOUNDFORBIDFLAG
-
-
-// flags for <compoptions>
-#define COMP_CHECKDUP 1 // CHECKCOMPOUNDDUP
-#define COMP_CHECKREP 2 // CHECKCOMPOUNDREP
-#define COMP_CHECKCASE 4 // CHECKCOMPOUNDCASE
-#define COMP_CHECKTRIPLE 8 // CHECKCOMPOUNDTRIPLE
-
-// Special byte values for <byte>. Some are only used in the tree for
-// postponed prefixes, some only in the other trees. This is a bit messy...
-#define BY_NOFLAGS 0 // end of word without flags or region; for
- // postponed prefix: no <pflags>
-#define BY_INDEX 1 // child is shared, index follows
-#define BY_FLAGS 2 // end of word, <flags> byte follows; for
- // postponed prefix: <pflags> follows
-#define BY_FLAGS2 3 // end of word, <flags> and <flags2> bytes
- // follow; never used in prefix tree
-#define BY_SPECIAL BY_FLAGS2 // highest special byte value
-
-// Info from "REP", "REPSAL" and "SAL" entries in ".aff" file used in si_rep,
-// si_repsal, sl_rep, and si_sal. Not for sl_sal!
-// One replacement: from "ft_from" to "ft_to".
-typedef struct fromto_S {
- char_u *ft_from;
- char_u *ft_to;
-} fromto_T;
-
-// Info from "SAL" entries in ".aff" file used in sl_sal.
-// The info is split for quick processing by spell_soundfold().
-// Note that "sm_oneof" and "sm_rules" point into sm_lead.
-typedef struct salitem_S {
- char_u *sm_lead; // leading letters
- int sm_leadlen; // length of "sm_lead"
- char_u *sm_oneof; // letters from () or NULL
- char_u *sm_rules; // rules like ^, $, priority
- char_u *sm_to; // replacement.
- int *sm_lead_w; // wide character copy of "sm_lead"
- int *sm_oneof_w; // wide character copy of "sm_oneof"
- int *sm_to_w; // wide character copy of "sm_to"
-} salitem_T;
-
-typedef int salfirst_T;
-
-// Values for SP_*ERROR are negative, positive values are used by
-// read_cnt_string().
-#define SP_TRUNCERROR -1 // spell file truncated error
-#define SP_FORMERROR -2 // format error in spell file
-#define SP_OTHERERROR -3 // other error while reading spell file
-
-// Structure used to store words and other info for one language, loaded from
-// a .spl file.
-// The main access is through the tree in "sl_fbyts/sl_fidxs", storing the
-// case-folded words. "sl_kbyts/sl_kidxs" is for keep-case words.
-//
-// The "byts" array stores the possible bytes in each tree node, preceded by
-// the number of possible bytes, sorted on byte value:
-// <len> <byte1> <byte2> ...
-// The "idxs" array stores the index of the child node corresponding to the
-// byte in "byts".
-// Exception: when the byte is zero, the word may end here and "idxs" holds
-// the flags, region mask and affixID for the word. There may be several
-// zeros in sequence for alternative flag/region/affixID combinations.
-typedef struct slang_S slang_T;
-struct slang_S {
- slang_T *sl_next; // next language
- char_u *sl_name; // language name "en", "en.rare", "nl", etc.
- char_u *sl_fname; // name of .spl file
- int sl_add; // TRUE if it's a .add file.
-
- char_u *sl_fbyts; // case-folded word bytes
- idx_T *sl_fidxs; // case-folded word indexes
- char_u *sl_kbyts; // keep-case word bytes
- idx_T *sl_kidxs; // keep-case word indexes
- char_u *sl_pbyts; // prefix tree word bytes
- idx_T *sl_pidxs; // prefix tree word indexes
-
- char_u *sl_info; // infotext string or NULL
-
- char_u sl_regions[17]; // table with up to 8 region names plus NUL
-
- char_u *sl_midword; // MIDWORD string or NULL
-
- hashtab_T sl_wordcount; // hashtable with word count, wordcount_T
-
- int sl_compmax; // COMPOUNDWORDMAX (default: MAXWLEN)
- int sl_compminlen; // COMPOUNDMIN (default: 0)
- int sl_compsylmax; // COMPOUNDSYLMAX (default: MAXWLEN)
- int sl_compoptions; // COMP_* flags
- garray_T sl_comppat; // CHECKCOMPOUNDPATTERN items
- regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm
- // (NULL when no compounding)
- char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL)
- char_u *sl_compstartflags; // flags for first compound word
- char_u *sl_compallflags; // all flags for compound words
- char_u sl_nobreak; // When TRUE: no spaces between words
- char_u *sl_syllable; // SYLLABLE repeatable chars or NULL
- garray_T sl_syl_items; // syllable items
-
- int sl_prefixcnt; // number of items in "sl_prefprog"
- regprog_T **sl_prefprog; // table with regprogs for prefixes
-
- garray_T sl_rep; // list of fromto_T entries from REP lines
- short sl_rep_first[256]; // indexes where byte first appears, -1 if
- // there is none
- garray_T sl_sal; // list of salitem_T entries from SAL lines
- salfirst_T sl_sal_first[256]; // indexes where byte first appears, -1 if
- // there is none
- int sl_followup; // SAL followup
- int sl_collapse; // SAL collapse_result
- int sl_rem_accents; // SAL remove_accents
- int sl_sofo; // SOFOFROM and SOFOTO instead of SAL items:
- // "sl_sal_first" maps chars, when has_mbyte
- // "sl_sal" is a list of wide char lists.
- garray_T sl_repsal; // list of fromto_T entries from REPSAL lines
- short sl_repsal_first[256]; // sl_rep_first for REPSAL lines
- int sl_nosplitsugs; // don't suggest splitting a word
-
- // Info from the .sug file. Loaded on demand.
- time_t sl_sugtime; // timestamp for .sug file
- char_u *sl_sbyts; // soundfolded word bytes
- idx_T *sl_sidxs; // soundfolded word indexes
- buf_T *sl_sugbuf; // buffer with word number table
- int sl_sugloaded; // TRUE when .sug file was loaded or failed to
- // load
-
- int sl_has_map; // TRUE if there is a MAP line
- hashtab_T sl_map_hash; // MAP for multi-byte chars
- int sl_map_array[256]; // MAP for first 256 chars
- hashtab_T sl_sounddone; // table with soundfolded words that have
- // handled, see add_sound_suggest()
-};
-
-// First language that is loaded, start of the linked list of loaded
-// languages.
-static slang_T *first_lang = NULL;
-
-// Flags used in .spl file for soundsalike flags.
-#define SAL_F0LLOWUP 1
-#define SAL_COLLAPSE 2
-#define SAL_REM_ACCENTS 4
-
-// Structure used in "b_langp", filled from 'spelllang'.
-typedef struct langp_S {
- slang_T *lp_slang; // info for this language
- slang_T *lp_sallang; // language used for sound folding or NULL
- slang_T *lp_replang; // language used for REP items or NULL
- int lp_region; // bitmask for region or REGION_ALL
-} langp_T;
-
-#define LANGP_ENTRY(ga, i) (((langp_T *)(ga).ga_data) + (i))
-
-#define REGION_ALL 0xff // word valid in all regions
-
-#define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file
-#define VIMSPELLMAGICL 8
-#define VIMSPELLVERSION 50
-
-#define VIMSUGMAGIC "VIMsug" // string at start of Vim .sug file
-#define VIMSUGMAGICL 6
-#define VIMSUGVERSION 1
-
-// Section IDs. Only renumber them when VIMSPELLVERSION changes!
-#define SN_REGION 0 // <regionname> section
-#define SN_CHARFLAGS 1 // charflags section
-#define SN_MIDWORD 2 // <midword> section
-#define SN_PREFCOND 3 // <prefcond> section
-#define SN_REP 4 // REP items section
-#define SN_SAL 5 // SAL items section
-#define SN_SOFO 6 // soundfolding section
-#define SN_MAP 7 // MAP items section
-#define SN_COMPOUND 8 // compound words section
-#define SN_SYLLABLE 9 // syllable section
-#define SN_NOBREAK 10 // NOBREAK section
-#define SN_SUGFILE 11 // timestamp for .sug file
-#define SN_REPSAL 12 // REPSAL items section
-#define SN_WORDS 13 // common words
-#define SN_NOSPLITSUGS 14 // don't split word for suggestions
-#define SN_INFO 15 // info section
-#define SN_END 255 // end of sections
-
-#define SNF_REQUIRED 1 // <sectionflags>: required section
-
-// Result values. Lower number is accepted over higher one.
-#define SP_BANNED -1
-#define SP_OK 0
-#define SP_RARE 1
-#define SP_LOCAL 2
-#define SP_BAD 3
-
-// file used for "zG" and "zW"
-static char_u *int_wordlist = NULL;
-
-typedef struct wordcount_S {
- uint16_t wc_count; // nr of times word was seen
- char_u wc_word[1]; // word, actually longer
-} wordcount_T;
-
-static wordcount_T dumwc;
-#define WC_KEY_OFF (unsigned)(dumwc.wc_word - (char_u *)&dumwc)
-#define HI2WC(hi) ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF))
-#define MAXWORDCOUNT 0xffff
-
-// Information used when looking for suggestions.
-typedef struct suginfo_S {
- garray_T su_ga; // suggestions, contains "suggest_T"
- int su_maxcount; // max. number of suggestions displayed
- int su_maxscore; // maximum score for adding to su_ga
- int su_sfmaxscore; // idem, for when doing soundfold words
- garray_T su_sga; // like su_ga, sound-folded scoring
- char_u *su_badptr; // start of bad word in line
- int su_badlen; // length of detected bad word in line
- int su_badflags; // caps flags for bad word
- char_u su_badword[MAXWLEN]; // bad word truncated at su_badlen
- char_u su_fbadword[MAXWLEN]; // su_badword case-folded
- char_u su_sal_badword[MAXWLEN]; // su_badword soundfolded
- hashtab_T su_banned; // table with banned words
- slang_T *su_sallang; // default language for sound folding
-} suginfo_T;
-
-// One word suggestion. Used in "si_ga".
-typedef struct suggest_S {
- char_u *st_word; // suggested word, allocated string
- int st_wordlen; // STRLEN(st_word)
- int st_orglen; // length of replaced text
- int st_score; // lower is better
- int st_altscore; // used when st_score compares equal
- int st_salscore; // st_score is for soundalike
- int st_had_bonus; // bonus already included in score
- slang_T *st_slang; // language used for sound folding
-} suggest_T;
-
-#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i])
-
-// TRUE if a word appears in the list of banned words.
-#define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&su->su_banned, word)))
-
-// Number of suggestions kept when cleaning up. We need to keep more than
-// what is displayed, because when rescore_suggestions() is called the score
-// may change and wrong suggestions may be removed later.
-#define SUG_CLEAN_COUNT(su) ((su)->su_maxcount < \
- 130 ? 150 : (su)->su_maxcount + 20)
-
-// Threshold for sorting and cleaning up suggestions. Don't want to keep lots
-// of suggestions that are not going to be displayed.
-#define SUG_MAX_COUNT(su) (SUG_CLEAN_COUNT(su) + 50)
-
-// score for various changes
-#define SCORE_SPLIT 149 // split bad word
-#define SCORE_SPLIT_NO 249 // split bad word with NOSPLITSUGS
-#define SCORE_ICASE 52 // slightly different case
-#define SCORE_REGION 200 // word is for different region
-#define SCORE_RARE 180 // rare word
-#define SCORE_SWAP 75 // swap two characters
-#define SCORE_SWAP3 110 // swap two characters in three
-#define SCORE_REP 65 // REP replacement
-#define SCORE_SUBST 93 // substitute a character
-#define SCORE_SIMILAR 33 // substitute a similar character
-#define SCORE_SUBCOMP 33 // substitute a composing character
-#define SCORE_DEL 94 // delete a character
-#define SCORE_DELDUP 66 // delete a duplicated character
-#define SCORE_DELCOMP 28 // delete a composing character
-#define SCORE_INS 96 // insert a character
-#define SCORE_INSDUP 67 // insert a duplicate character
-#define SCORE_INSCOMP 30 // insert a composing character
-#define SCORE_NONWORD 103 // change non-word to word char
-
-#define SCORE_FILE 30 // suggestion from a file
-#define SCORE_MAXINIT 350 // Initial maximum score: higher == slower.
- // 350 allows for about three changes.
-
-#define SCORE_COMMON1 30 // subtracted for words seen before
-#define SCORE_COMMON2 40 // subtracted for words often seen
-#define SCORE_COMMON3 50 // subtracted for words very often seen
-#define SCORE_THRES2 10 // word count threshold for COMMON2
-#define SCORE_THRES3 100 // word count threshold for COMMON3
-
-// When trying changed soundfold words it becomes slow when trying more than
-// two changes. With less then two changes it's slightly faster but we miss a
-// few good suggestions. In rare cases we need to try three of four changes.
-#define SCORE_SFMAX1 200 // maximum score for first try
-#define SCORE_SFMAX2 300 // maximum score for second try
-#define SCORE_SFMAX3 400 // maximum score for third try
-
-#define SCORE_BIG SCORE_INS * 3 // big difference
-#define SCORE_MAXMAX 999999 // accept any score
-#define SCORE_LIMITMAX 350 // for spell_edit_score_limit()
-
-// for spell_edit_score_limit() we need to know the minimum value of
-// SCORE_ICASE, SCORE_SWAP, SCORE_DEL, SCORE_SIMILAR and SCORE_INS
-#define SCORE_EDIT_MIN SCORE_SIMILAR
-
-// Structure to store info for word matching.
-typedef struct matchinf_S {
- langp_T *mi_lp; // info for language and region
-
- // pointers to original text to be checked
- char_u *mi_word; // start of word being checked
- char_u *mi_end; // end of matching word so far
- char_u *mi_fend; // next char to be added to mi_fword
- char_u *mi_cend; // char after what was used for
- // mi_capflags
-
- // case-folded text
- char_u mi_fword[MAXWLEN + 1]; // mi_word case-folded
- int mi_fwordlen; // nr of valid bytes in mi_fword
-
- // for when checking word after a prefix
- int mi_prefarridx; // index in sl_pidxs with list of
- // affixID/condition
- int mi_prefcnt; // number of entries at mi_prefarridx
- int mi_prefixlen; // byte length of prefix
- int mi_cprefixlen; // byte length of prefix in original
- // case
-
- // for when checking a compound word
- int mi_compoff; // start of following word offset
- char_u mi_compflags[MAXWLEN]; // flags for compound words used
- int mi_complen; // nr of compound words used
- int mi_compextra; // nr of COMPOUNDROOT words
-
- // others
- int mi_result; // result so far: SP_BAD, SP_OK, etc.
- int mi_capflags; // WF_ONECAP WF_ALLCAP WF_KEEPCAP
- win_T *mi_win; // buffer being checked
-
- // for NOBREAK
- int mi_result2; // "mi_resul" without following word
- char_u *mi_end2; // "mi_end" without following word
-} matchinf_T;
-
-// The tables used for recognizing word characters according to spelling.
-// These are only used for the first 256 characters of 'encoding'.
-typedef struct spelltab_S {
- char_u st_isw[256]; // flags: is word char
- char_u st_isu[256]; // flags: is uppercase char
- char_u st_fold[256]; // chars: folded case
- char_u st_upper[256]; // chars: upper case
-} spelltab_T;
-
-static spelltab_T spelltab;
-static int did_set_spelltab;
-
-#define CF_WORD 0x01
-#define CF_UPPER 0x02
-
-static void clear_spell_chartab(spelltab_T *sp);
-static int set_spell_finish(spelltab_T *new_st);
-static int spell_iswordp(char_u *p, win_T *wp);
-static int spell_iswordp_nmw(char_u *p, win_T *wp);
-static int spell_mb_isword_class(int cl, win_T *wp);
-static int spell_iswordp_w(int *p, win_T *wp);
-static int write_spell_prefcond(FILE *fd, garray_T *gap);
-
-// For finding suggestions: At each node in the tree these states are tried:
-typedef enum {
- STATE_START = 0, // At start of node check for NUL bytes (goodword
- // ends); if badword ends there is a match, otherwise
- // try splitting word.
- STATE_NOPREFIX, // try without prefix
- STATE_SPLITUNDO, // Undo splitting.
- STATE_ENDNUL, // Past NUL bytes at start of the node.
- STATE_PLAIN, // Use each byte of the node.
- STATE_DEL, // Delete a byte from the bad word.
- STATE_INS_PREP, // Prepare for inserting bytes.
- STATE_INS, // Insert a byte in the bad word.
- STATE_SWAP, // Swap two bytes.
- STATE_UNSWAP, // Undo swap two characters.
- STATE_SWAP3, // Swap two characters over three.
- STATE_UNSWAP3, // Undo Swap two characters over three.
- STATE_UNROT3L, // Undo rotate three characters left
- STATE_UNROT3R, // Undo rotate three characters right
- STATE_REP_INI, // Prepare for using REP items.
- STATE_REP, // Use matching REP items from the .aff file.
- STATE_REP_UNDO, // Undo a REP item replacement.
- STATE_FINAL // End of this node.
-} state_T;
-
-// Struct to keep the state at each level in suggest_try_change().
-typedef struct trystate_S {
- state_T ts_state; // state at this level, STATE_
- int ts_score; // score
- idx_T ts_arridx; // index in tree array, start of node
- short ts_curi; // index in list of child nodes
- char_u ts_fidx; // index in fword[], case-folded bad word
- char_u ts_fidxtry; // ts_fidx at which bytes may be changed
- char_u ts_twordlen; // valid length of tword[]
- char_u ts_prefixdepth; // stack depth for end of prefix or
- // PFD_PREFIXTREE or PFD_NOPREFIX
- char_u ts_flags; // TSF_ flags
- char_u ts_tcharlen; // number of bytes in tword character
- char_u ts_tcharidx; // current byte index in tword character
- char_u ts_isdiff; // DIFF_ values
- char_u ts_fcharstart; // index in fword where badword char started
- char_u ts_prewordlen; // length of word in "preword[]"
- char_u ts_splitoff; // index in "tword" after last split
- char_u ts_splitfidx; // "ts_fidx" at word split
- char_u ts_complen; // nr of compound words used
- char_u ts_compsplit; // index for "compflags" where word was spit
- char_u ts_save_badflags; // su_badflags saved here
- char_u ts_delidx; // index in fword for char that was deleted,
- // valid when "ts_flags" has TSF_DIDDEL
-} trystate_T;
-
-// values for ts_isdiff
-#define DIFF_NONE 0 // no different byte (yet)
-#define DIFF_YES 1 // different byte found
-#define DIFF_INSERT 2 // inserting character
-
-// values for ts_flags
-#define TSF_PREFIXOK 1 // already checked that prefix is OK
-#define TSF_DIDSPLIT 2 // tried split at this point
-#define TSF_DIDDEL 4 // did a delete, "ts_delidx" has index
-
-// special values ts_prefixdepth
-#define PFD_NOPREFIX 0xff // not using prefixes
-#define PFD_PREFIXTREE 0xfe // walking through the prefix tree
-#define PFD_NOTSPECIAL 0xfd // highest value that's not special
-
-// mode values for find_word
-#define FIND_FOLDWORD 0 // find word case-folded
-#define FIND_KEEPWORD 1 // find keep-case word
-#define FIND_PREFIX 2 // find word after prefix
-#define FIND_COMPOUND 3 // find case-folded compound word
-#define FIND_KEEPCOMPOUND 4 // find keep-case compound word
-
-static slang_T *slang_alloc(char_u *lang);
-static void slang_free(slang_T *lp);
-static void slang_clear(slang_T *lp);
-static void slang_clear_sug(slang_T *lp);
-static void find_word(matchinf_T *mip, int mode);
-static int match_checkcompoundpattern(char_u *ptr, int wlen,
- garray_T *gap);
-static int can_compound(slang_T *slang, char_u *word, char_u *flags);
-static int can_be_compound(trystate_T *sp, slang_T *slang, char_u *compflags,
- int flag);
-static int match_compoundrule(slang_T *slang, char_u *compflags);
-static int valid_word_prefix(int totprefcnt, int arridx, int flags,
- char_u *word, slang_T *slang,
- int cond_req);
-static void find_prefix(matchinf_T *mip, int mode);
-static int fold_more(matchinf_T *mip);
-static int spell_valid_case(int wordflags, int treeflags);
-static int no_spell_checking(win_T *wp);
-static void spell_load_