forked from aniani/vim
updated for version 7.0102
This commit is contained in:
223
src/spell.c
223
src/spell.c
@@ -192,7 +192,10 @@
|
||||
* <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_PFX <prefixID> follows
|
||||
*
|
||||
@@ -241,9 +244,10 @@ typedef long idx_T;
|
||||
#define WF_RARE 0x08 /* rare word */
|
||||
#define WF_BANNED 0x10 /* bad word */
|
||||
#define WF_PFX 0x20 /* prefix ID list follows */
|
||||
#define WF_FIXCAP 0x40 /* keep-case word, allcap not allowed */
|
||||
#define WF_KEEPCAP 0x80 /* keep-case word */
|
||||
|
||||
#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP)
|
||||
#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP)
|
||||
|
||||
#define WF_RAREPFX 0x1000000 /* in sl_pidxs: flag for rare postponed
|
||||
prefix; must be above prefixID (one byte)
|
||||
@@ -584,14 +588,14 @@ static void find_word __ARGS((matchinf_T *mip, int mode));
|
||||
static int valid_word_prefix __ARGS((int totprefcnt, int arridx, int prefid, char_u *word, slang_T *slang));
|
||||
static void find_prefix __ARGS((matchinf_T *mip));
|
||||
static int fold_more __ARGS((matchinf_T *mip));
|
||||
static int spell_valid_case __ARGS((int origflags, int treeflags));
|
||||
static int spell_valid_case __ARGS((int wordflags, int treeflags));
|
||||
static int no_spell_checking __ARGS((void));
|
||||
static void spell_load_lang __ARGS((char_u *lang));
|
||||
static char_u *spell_enc __ARGS((void));
|
||||
static void int_wordlist_spl __ARGS((char_u *fname));
|
||||
static void spell_load_cb __ARGS((char_u *fname, void *cookie));
|
||||
static slang_T *spell_load_file __ARGS((char_u *fname, char_u *lang, slang_T *old_lp, int silent));
|
||||
static char_u *read_cnt_string __ARGS((FILE *fd, int cnt_bytes, int *errp));
|
||||
static char_u *read_cnt_string __ARGS((FILE *fd, int cnt_bytes, int *lenp));
|
||||
static int set_sofo __ARGS((slang_T *lp, char_u *from, char_u *to));
|
||||
static void set_sal_first __ARGS((slang_T *lp));
|
||||
#ifdef FEAT_MBYTE
|
||||
@@ -603,7 +607,7 @@ static void use_midword __ARGS((slang_T *lp, buf_T *buf));
|
||||
static int find_region __ARGS((char_u *rp, char_u *region));
|
||||
static int captype __ARGS((char_u *word, char_u *end));
|
||||
static void spell_reload_one __ARGS((char_u *fname, int added_word));
|
||||
static int set_spell_charflags __ARGS((char_u *flags, char_u *upp));
|
||||
static int set_spell_charflags __ARGS((char_u *flags, int cnt, char_u *upp));
|
||||
static int set_spell_chartab __ARGS((char_u *fol, char_u *low, char_u *upp));
|
||||
static void write_spell_chartab __ARGS((FILE *fd));
|
||||
static int spell_casefold __ARGS((char_u *p, int len, char_u *buf, int buflen));
|
||||
@@ -1293,13 +1297,13 @@ fold_more(mip)
|
||||
* case.
|
||||
*/
|
||||
static int
|
||||
spell_valid_case(origflags, treeflags)
|
||||
int origflags; /* flags for the checked word. */
|
||||
spell_valid_case(wordflags, treeflags)
|
||||
int wordflags; /* flags for the checked word. */
|
||||
int treeflags; /* flags for the word in the spell tree */
|
||||
{
|
||||
return (origflags == WF_ALLCAP
|
||||
return ((wordflags == WF_ALLCAP && (treeflags & WF_FIXCAP) == 0)
|
||||
|| ((treeflags & (WF_ALLCAP | WF_KEEPCAP)) == 0
|
||||
&& ((treeflags & WF_ONECAP) == 0 || origflags == WF_ONECAP)));
|
||||
&& ((treeflags & WF_ONECAP) == 0 || wordflags == WF_ONECAP)));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1837,12 +1841,12 @@ formerr:
|
||||
|
||||
/* <charflagslen> <charflags> */
|
||||
p = read_cnt_string(fd, 1, &cnt);
|
||||
if (cnt == FAIL)
|
||||
if (cnt < 0)
|
||||
goto endFAIL;
|
||||
|
||||
/* <fcharslen> <fchars> */
|
||||
fol = read_cnt_string(fd, 2, &cnt);
|
||||
if (cnt == FAIL)
|
||||
fol = read_cnt_string(fd, 2, &ccnt);
|
||||
if (ccnt < 0)
|
||||
{
|
||||
vim_free(p);
|
||||
goto endFAIL;
|
||||
@@ -1850,7 +1854,7 @@ formerr:
|
||||
|
||||
/* Set the word-char flags and fill SPELL_ISUPPER() table. */
|
||||
if (p != NULL && fol != NULL)
|
||||
i = set_spell_charflags(p, fol);
|
||||
i = set_spell_charflags(p, cnt, fol);
|
||||
|
||||
vim_free(p);
|
||||
vim_free(fol);
|
||||
@@ -1861,7 +1865,7 @@ formerr:
|
||||
|
||||
/* <midwordlen> <midword> */
|
||||
lp->sl_midword = read_cnt_string(fd, 2, &cnt);
|
||||
if (cnt == FAIL)
|
||||
if (cnt < 0)
|
||||
goto endFAIL;
|
||||
|
||||
/* <prefcondcnt> <prefcond> ... */
|
||||
@@ -1912,10 +1916,10 @@ formerr:
|
||||
{
|
||||
ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
|
||||
ftp->ft_from = read_cnt_string(fd, 1, &i);
|
||||
if (i == FAIL)
|
||||
if (i <= 0)
|
||||
goto endFAIL;
|
||||
ftp->ft_to = read_cnt_string(fd, 1, &i);
|
||||
if (i == FAIL)
|
||||
if (i <= 0)
|
||||
{
|
||||
vim_free(ftp->ft_from);
|
||||
goto endFAIL;
|
||||
@@ -1942,6 +1946,8 @@ formerr:
|
||||
lp->sl_rem_accents = TRUE;
|
||||
if (i & SAL_SOFO)
|
||||
lp->sl_sofo = TRUE;
|
||||
else
|
||||
lp->sl_sofo = FALSE;
|
||||
|
||||
cnt = (getc(fd) << 8) + getc(fd); /* <salcount> */
|
||||
if (cnt < 0)
|
||||
@@ -1957,19 +1963,24 @@ formerr:
|
||||
|
||||
/* <salfromlen> <salfrom> */
|
||||
bp = read_cnt_string(fd, 2, &cnt);
|
||||
if (cnt == FAIL)
|
||||
if (cnt < 0)
|
||||
goto endFAIL;
|
||||
|
||||
/* <saltolen> <salto> */
|
||||
fol = read_cnt_string(fd, 2, &cnt);
|
||||
if (cnt == FAIL)
|
||||
if (cnt < 0)
|
||||
{
|
||||
vim_free(bp);
|
||||
goto endFAIL;
|
||||
}
|
||||
|
||||
/* Store the info in lp->sl_sal and/or lp->sl_sal_first. */
|
||||
i = set_sofo(lp, bp, fol);
|
||||
if (bp != NULL && fol != NULL)
|
||||
i = set_sofo(lp, bp, fol);
|
||||
else if (bp != NULL || fol != NULL)
|
||||
i = FAIL; /* only one of two strings is an error */
|
||||
else
|
||||
i = OK;
|
||||
|
||||
vim_free(bp);
|
||||
vim_free(fol);
|
||||
@@ -2036,7 +2047,7 @@ formerr:
|
||||
|
||||
/* <saltolen> <salto> */
|
||||
smp->sm_to = read_cnt_string(fd, 1, &ccnt);
|
||||
if (ccnt == FAIL)
|
||||
if (ccnt < 0)
|
||||
{
|
||||
vim_free(smp->sm_lead);
|
||||
goto formerr;
|
||||
@@ -2052,10 +2063,13 @@ formerr:
|
||||
smp->sm_oneof_w = NULL;
|
||||
else
|
||||
smp->sm_oneof_w = mb_str2wide(smp->sm_oneof);
|
||||
smp->sm_to_w = mb_str2wide(smp->sm_to);
|
||||
if (smp->sm_to == NULL)
|
||||
smp->sm_to_w = NULL;
|
||||
else
|
||||
smp->sm_to_w = mb_str2wide(smp->sm_to);
|
||||
if (smp->sm_lead_w == NULL
|
||||
|| (smp->sm_oneof_w == NULL && smp->sm_oneof != NULL)
|
||||
|| smp->sm_to_w == NULL)
|
||||
|| (smp->sm_to_w == NULL && smp->sm_to != NULL))
|
||||
{
|
||||
vim_free(smp->sm_lead);
|
||||
vim_free(smp->sm_to);
|
||||
@@ -2074,11 +2088,13 @@ formerr:
|
||||
|
||||
/* <maplen> <mapstr> */
|
||||
p = read_cnt_string(fd, 2, &cnt);
|
||||
if (cnt == FAIL)
|
||||
if (cnt < 0)
|
||||
goto endFAIL;
|
||||
set_map_str(lp, p);
|
||||
vim_free(p);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
set_map_str(lp, p);
|
||||
vim_free(p);
|
||||
}
|
||||
|
||||
/* round 1: <LWORDTREE>
|
||||
* round 2: <KWORDTREE>
|
||||
@@ -2155,13 +2171,13 @@ endOK:
|
||||
* Read a length field from "fd" in "cnt_bytes" bytes.
|
||||
* Allocate memory, read the string into it and add a NUL at the end.
|
||||
* Returns NULL when the count is zero.
|
||||
* Sets "*errp" to FAIL when there is an error, OK otherwise.
|
||||
* Sets "*cntp" to -1 when there is an error, length of the result otherwise.
|
||||
*/
|
||||
static char_u *
|
||||
read_cnt_string(fd, cnt_bytes, errp)
|
||||
read_cnt_string(fd, cnt_bytes, cntp)
|
||||
FILE *fd;
|
||||
int cnt_bytes;
|
||||
int *errp;
|
||||
int *cntp;
|
||||
{
|
||||
int cnt = 0;
|
||||
int i;
|
||||
@@ -2173,18 +2189,20 @@ read_cnt_string(fd, cnt_bytes, errp)
|
||||
if (cnt < 0)
|
||||
{
|
||||
EMSG(_(e_spell_trunc));
|
||||
*errp = FAIL;
|
||||
*cntp = -1;
|
||||
return NULL;
|
||||
}
|
||||
*cntp = cnt;
|
||||
if (cnt == 0)
|
||||
return NULL; /* nothing to read, return NULL */
|
||||
|
||||
/* allocate memory */
|
||||
str = alloc((unsigned)cnt + 1);
|
||||
if (str == NULL)
|
||||
{
|
||||
*errp = FAIL;
|
||||
*cntp = -1;
|
||||
return NULL;
|
||||
}
|
||||
*errp = OK;
|
||||
|
||||
/* Read the string. Doesn't check for truncated file. */
|
||||
for (i = 0; i < cnt; ++i)
|
||||
@@ -2512,6 +2530,8 @@ did_set_spelllang(buf)
|
||||
char_u *p;
|
||||
int round;
|
||||
char_u *spf;
|
||||
char_u *use_region = NULL;
|
||||
int dont_use_region = FALSE;
|
||||
|
||||
ga_init2(&ga, sizeof(langp_T), 2);
|
||||
clear_midword(buf);
|
||||
@@ -2545,7 +2565,15 @@ did_set_spelllang(buf)
|
||||
region = lang + len - 2;
|
||||
len -= 3;
|
||||
lang[len] = NUL;
|
||||
|
||||
/* If the region differs from what was used before then don't
|
||||
* use it for 'spellfile'. */
|
||||
if (use_region != NULL && STRCMP(region, use_region) != 0)
|
||||
dont_use_region = TRUE;
|
||||
use_region = region;
|
||||
}
|
||||
else
|
||||
dont_use_region = TRUE;
|
||||
|
||||
/* Check if we loaded this language before. */
|
||||
for (lp = first_lang; lp != NULL; lp = lp->sl_next)
|
||||
@@ -2576,7 +2604,15 @@ did_set_spelllang(buf)
|
||||
c = find_region(lp->sl_regions, region);
|
||||
if (c == REGION_ALL)
|
||||
{
|
||||
if (!lp->sl_add)
|
||||
if (lp->sl_add)
|
||||
{
|
||||
if (*lp->sl_regions != NUL)
|
||||
/* This addition file is for other regions. */
|
||||
region_mask = 0;
|
||||
}
|
||||
else
|
||||
/* This is probably an error. Give a warning and
|
||||
* accept the words anyway. */
|
||||
smsg((char_u *)
|
||||
_("Warning: region %s not supported"),
|
||||
region);
|
||||
@@ -2585,15 +2621,18 @@ did_set_spelllang(buf)
|
||||
region_mask = 1 << c;
|
||||
}
|
||||
|
||||
if (ga_grow(&ga, 1) == FAIL)
|
||||
if (region_mask != 0)
|
||||
{
|
||||
ga_clear(&ga);
|
||||
return e_outofmem;
|
||||
if (ga_grow(&ga, 1) == FAIL)
|
||||
{
|
||||
ga_clear(&ga);
|
||||
return e_outofmem;
|
||||
}
|
||||
LANGP_ENTRY(ga, ga.ga_len)->lp_slang = lp;
|
||||
LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
|
||||
++ga.ga_len;
|
||||
use_midword(lp, buf);
|
||||
}
|
||||
LANGP_ENTRY(ga, ga.ga_len)->lp_slang = lp;
|
||||
LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
|
||||
++ga.ga_len;
|
||||
use_midword(lp, buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2649,10 +2688,25 @@ did_set_spelllang(buf)
|
||||
}
|
||||
if (lp != NULL && ga_grow(&ga, 1) == OK)
|
||||
{
|
||||
LANGP_ENTRY(ga, ga.ga_len)->lp_slang = lp;
|
||||
LANGP_ENTRY(ga, ga.ga_len)->lp_region = REGION_ALL;
|
||||
++ga.ga_len;
|
||||
use_midword(lp, buf);
|
||||
region_mask = REGION_ALL;
|
||||
if (use_region != NULL && !dont_use_region)
|
||||
{
|
||||
/* find region in sl_regions */
|
||||
c = find_region(lp->sl_regions, use_region);
|
||||
if (c != REGION_ALL)
|
||||
region_mask = 1 << c;
|
||||
else if (*lp->sl_regions != NUL)
|
||||
/* This spell file is for other regions. */
|
||||
region_mask = 0;
|
||||
}
|
||||
|
||||
if (region_mask != 0)
|
||||
{
|
||||
LANGP_ENTRY(ga, ga.ga_len)->lp_slang = lp;
|
||||
LANGP_ENTRY(ga, ga.ga_len)->lp_region = region_mask;
|
||||
++ga.ga_len;
|
||||
use_midword(lp, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2697,6 +2751,9 @@ use_midword(lp, buf)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
if (lp->sl_midword == NULL) /* there aren't any */
|
||||
return;
|
||||
|
||||
for (p = lp->sl_midword; *p != NUL; )
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
@@ -3799,7 +3856,7 @@ spell_read_dic(fname, spin, affile)
|
||||
* for rare word (if defined). */
|
||||
if (affile->af_kep != NUL
|
||||
&& vim_strchr(afflist, affile->af_kep) != NULL)
|
||||
flags |= WF_KEEPCAP;
|
||||
flags |= WF_KEEPCAP | WF_FIXCAP;
|
||||
if (affile->af_rar != NUL
|
||||
&& vim_strchr(afflist, affile->af_rar) != NULL)
|
||||
flags |= WF_RARE;
|
||||
@@ -4150,6 +4207,9 @@ spell_read_wordfile(fname, spin)
|
||||
{
|
||||
spin->si_region_count = STRLEN(line) / 2;
|
||||
STRCPY(spin->si_region_name, line);
|
||||
|
||||
/* Adjust the mask for a word valid in all regions. */
|
||||
spin->si_region = (1 << spin->si_region_count) - 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
@@ -4171,7 +4231,7 @@ spell_read_wordfile(fname, spin)
|
||||
while (*p != NUL)
|
||||
{
|
||||
if (*p == '=') /* keep-case word */
|
||||
flags |= WF_KEEPCAP;
|
||||
flags |= WF_KEEPCAP | WF_FIXCAP;
|
||||
else if (*p == '!') /* Bad, bad, wicked word. */
|
||||
flags |= WF_BANNED;
|
||||
else if (*p == '?') /* Rare word. */
|
||||
@@ -5604,34 +5664,39 @@ set_spell_chartab(fol, low, upp)
|
||||
* Set the spell character tables from strings in the .spl file.
|
||||
*/
|
||||
static int
|
||||
set_spell_charflags(flags, upp)
|
||||
set_spell_charflags(flags, cnt, fol)
|
||||
char_u *flags;
|
||||
char_u *upp;
|
||||
int cnt; /* length of "flags" */
|
||||
char_u *fol;
|
||||
{
|
||||
/* We build the new tables here first, so that we can compare with the
|
||||
* previous one. */
|
||||
spelltab_T new_st;
|
||||
int i;
|
||||
char_u *p = upp;
|
||||
char_u *p = fol;
|
||||
int c;
|
||||
|
||||
clear_spell_chartab(&new_st);
|
||||
|
||||
for (i = 0; flags[i] != NUL; ++i)
|
||||
for (i = 0; i < 128; ++i)
|
||||
{
|
||||
new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0;
|
||||
new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0;
|
||||
if (i < cnt)
|
||||
{
|
||||
new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0;
|
||||
new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0;
|
||||
}
|
||||
|
||||
if (*p == NUL)
|
||||
return FAIL;
|
||||
if (*p != NUL)
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
c = mb_ptr2char_adv(&p);
|
||||
c = mb_ptr2char_adv(&p);
|
||||
#else
|
||||
c = *p++;
|
||||
c = *p++;
|
||||
#endif
|
||||
new_st.st_fold[i + 128] = c;
|
||||
if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
|
||||
new_st.st_upper[c] = i + 128;
|
||||
new_st.st_fold[i + 128] = c;
|
||||
if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
|
||||
new_st.st_upper[c] = i + 128;
|
||||
}
|
||||
}
|
||||
|
||||
return set_spell_finish(&new_st);
|
||||
@@ -7992,6 +8057,8 @@ suggest_try_soundalike(su)
|
||||
{
|
||||
byts = lp->lp_slang->sl_kbyts;
|
||||
idxs = lp->lp_slang->sl_kidxs;
|
||||
if (byts == NULL) /* no keep-case words */
|
||||
continue;
|
||||
}
|
||||
|
||||
depth = 0;
|
||||
@@ -8836,6 +8903,8 @@ spell_soundfold_sal(slang, inword, res)
|
||||
|
||||
/* replace string */
|
||||
s = smp[n].sm_to;
|
||||
if (s == NULL)
|
||||
s = (char_u *)"";
|
||||
pf = smp[n].sm_rules;
|
||||
p0 = (vim_strchr(pf, '<') != NULL) ? 1 : 0;
|
||||
if (p0 == 1 && z == 0)
|
||||
@@ -9138,18 +9207,20 @@ spell_soundfold_wsal(slang, inword, res)
|
||||
if (p0 == 1 && z == 0)
|
||||
{
|
||||
/* rule with '<' is used */
|
||||
if (reslen > 0 && *ws != NUL && (wres[reslen - 1] == c
|
||||
if (reslen > 0 && ws != NULL && *ws != NUL
|
||||
&& (wres[reslen - 1] == c
|
||||
|| wres[reslen - 1] == *ws))
|
||||
reslen--;
|
||||
z0 = 1;
|
||||
z = 1;
|
||||
k0 = 0;
|
||||
while (*ws != NUL && word[i + k0] != NUL)
|
||||
{
|
||||
word[i + k0] = *ws;
|
||||
k0++;
|
||||
ws++;
|
||||
}
|
||||
if (ws != NULL)
|
||||
while (*ws != NUL && word[i + k0] != NUL)
|
||||
{
|
||||
word[i + k0] = *ws;
|
||||
k0++;
|
||||
ws++;
|
||||
}
|
||||
if (k > k0)
|
||||
mch_memmove(word + i + k0, word + i + k,
|
||||
sizeof(int) * (STRLEN(word + i + k) + 1));
|
||||
@@ -9162,14 +9233,19 @@ spell_soundfold_wsal(slang, inword, res)
|
||||
/* no '<' rule used */
|
||||
i += k - 1;
|
||||
z = 0;
|
||||
while (*ws != NUL && ws[1] != NUL && reslen < MAXWLEN)
|
||||
{
|
||||
if (reslen == 0 || wres[reslen - 1] != *ws)
|
||||
wres[reslen++] = *ws;
|
||||
ws++;
|
||||
}
|
||||
if (ws != NULL)
|
||||
while (*ws != NUL && ws[1] != NUL
|
||||
&& reslen < MAXWLEN)
|
||||
{
|
||||
if (reslen == 0 || wres[reslen - 1] != *ws)
|
||||
wres[reslen++] = *ws;
|
||||
ws++;
|
||||
}
|
||||
/* new "actual letter" */
|
||||
c = *ws;
|
||||
if (ws == NULL)
|
||||
c = NUL;
|
||||
else
|
||||
c = *ws;
|
||||
if (strstr((char *)s, "^^") != NULL)
|
||||
{
|
||||
if (c != NUL)
|
||||
@@ -9722,7 +9798,8 @@ dump_word(word, round, flags, lnum)
|
||||
else
|
||||
{
|
||||
p = word;
|
||||
if (round == 2 && (captype(word, NULL) & WF_KEEPCAP) == 0)
|
||||
if (round == 2 && ((captype(word, NULL) & WF_KEEPCAP) == 0
|
||||
|| (flags & WF_FIXCAP) != 0))
|
||||
keepcap = TRUE;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user