summaryrefslogtreecommitdiff
path: root/src/spell.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2006-04-06 20:18:50 +0000
committerBram Moolenaar <Bram@vim.org>2006-04-06 20:18:50 +0000
commit8dff818edfb61658b94128111234c3c074c1cadc (patch)
treeed09901efe925ec1b065c8dbd4cd94165b01cf6f /src/spell.c
parent910f66f90c928da8b607ccfdc12fc33d9cb8d4a9 (diff)
downloadvim-git-8dff818edfb61658b94128111234c3c074c1cadc.tar.gz
updated for version 7.0c11
Diffstat (limited to 'src/spell.c')
-rw-r--r--src/spell.c226
1 files changed, 177 insertions, 49 deletions
diff --git a/src/spell.c b/src/spell.c
index a11372ab3..f74757002 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -4655,6 +4655,7 @@ typedef struct afffile_S
unsigned af_keepcase; /* KEEPCASE ID for keep-case word */
unsigned af_bad; /* BAD ID for banned word */
unsigned af_needaffix; /* NEEDAFFIX ID */
+ unsigned af_circumfix; /* CIRCUMFIX ID */
unsigned af_needcomp; /* NEEDCOMPOUND ID */
unsigned af_comproot; /* COMPOUNDROOT ID */
unsigned af_compforbid; /* COMPOUNDFORBIDFLAG ID */
@@ -4855,9 +4856,10 @@ static int sal_to_bool __ARGS((char_u *s));
static int has_non_ascii __ARGS((char_u *s));
static void spell_free_aff __ARGS((afffile_T *aff));
static int spell_read_dic __ARGS((spellinfo_T *spin, char_u *fname, afffile_T *affile));
+static int get_affix_flags __ARGS((afffile_T *affile, char_u *afflist));
static int get_pfxlist __ARGS((afffile_T *affile, char_u *afflist, char_u *store_afflist));
static void get_compflags __ARGS((afffile_T *affile, char_u *afflist, char_u *store_afflist));
-static int store_aff_word __ARGS((spellinfo_T *spin, char_u *word, char_u *afflist, afffile_T *affile, hashtab_T *ht, hashtab_T *xht, int comb, int flags, char_u *pfxlist, int pfxlen));
+static int store_aff_word __ARGS((spellinfo_T *spin, char_u *word, char_u *afflist, afffile_T *affile, hashtab_T *ht, hashtab_T *xht, int condit, int flags, char_u *pfxlist, int pfxlen));
static int spell_read_wordfile __ARGS((spellinfo_T *spin, char_u *fname));
static void *getroom __ARGS((spellinfo_T *spin, size_t len, int align));
static char_u *getroom_save __ARGS((spellinfo_T *spin, char_u *s));
@@ -4891,6 +4893,12 @@ static void init_spellfile __ARGS((void));
* Use a negative number with the lower 8 bits zero. */
#define PFX_FLAGS -256
+/* flags for "condit" argument of store_aff_word() */
+#define CONDIT_COMB 1 /* affix must combine */
+#define CONDIT_CFIX 2 /* affix must have CIRCUMFIX flag */
+#define CONDIT_SUF 4 /* add a suffix for matching flags */
+#define CONDIT_AFF 8 /* word already has an affix */
+
/*
* Tunable parameters for when the tree is compressed. See 'mkspellmem'.
*/
@@ -5170,6 +5178,7 @@ spell_read_aff(spin, fname)
|| aff->af_keepcase != 0
|| aff->af_bad != 0
|| aff->af_needaffix != 0
+ || aff->af_circumfix != 0
|| aff->af_needcomp != 0
|| aff->af_comproot != 0
|| aff->af_nosuggest != 0
@@ -5235,6 +5244,12 @@ spell_read_aff(spin, fname)
aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
fname, lnum);
}
+ else if (STRCMP(items[0], "CIRCUMFIX") == 0 && itemcnt == 2
+ && aff->af_circumfix == 0)
+ {
+ aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ }
else if (STRCMP(items[0], "NOSUGGEST") == 0 && itemcnt == 2
&& aff->af_nosuggest == 0)
{
@@ -5430,6 +5445,7 @@ spell_read_aff(spin, fname)
|| cur_aff->ah_flag == aff->af_rare
|| cur_aff->ah_flag == aff->af_keepcase
|| cur_aff->ah_flag == aff->af_needaffix
+ || cur_aff->ah_flag == aff->af_circumfix
|| cur_aff->ah_flag == aff->af_nosuggest
|| cur_aff->ah_flag == aff->af_needcomp
|| cur_aff->ah_flag == aff->af_comproot)
@@ -6449,29 +6465,12 @@ spell_read_dic(spin, fname, affile)
need_affix = FALSE;
if (afflist != NULL)
{
- /* Check for affix name that stands for keep-case word and stands
- * for rare word (if defined). */
- if (affile->af_keepcase != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_keepcase))
- flags |= WF_KEEPCAP | WF_FIXCAP;
- if (affile->af_rare != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_rare))
- flags |= WF_RARE;
- if (affile->af_bad != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_bad))
- flags |= WF_BANNED;
+ /* Extract flags from the affix list. */
+ flags |= get_affix_flags(affile, afflist);
+
if (affile->af_needaffix != 0 && flag_in_afflist(
affile->af_flagtype, afflist, affile->af_needaffix))
need_affix = TRUE;
- if (affile->af_needcomp != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needcomp))
- flags |= WF_NEEDCOMP;
- if (affile->af_comproot != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_comproot))
- flags |= WF_COMPROOT;
- if (affile->af_nosuggest != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_nosuggest))
- flags |= WF_NOSUGGEST;
if (affile->af_pfxpostpone)
/* Need to store the list of prefix IDs with the word. */
@@ -6494,13 +6493,13 @@ spell_read_dic(spin, fname, affile)
* Additionally do matching prefixes that combine. */
if (store_aff_word(spin, dw, afflist, affile,
&affile->af_suff, &affile->af_pref,
- FALSE, flags, store_afflist, pfxlen) == FAIL)
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
retval = FAIL;
/* Find all matching prefixes and add the resulting words. */
if (store_aff_word(spin, dw, afflist, affile,
&affile->af_pref, NULL,
- FALSE, flags, store_afflist, pfxlen) == FAIL)
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
retval = FAIL;
}
}
@@ -6517,6 +6516,38 @@ spell_read_dic(spin, fname, affile)
}
/*
+ * Check for affix flags in "afflist" that are turned into word flags.
+ * Return WF_ flags.
+ */
+ static int
+get_affix_flags(affile, afflist)
+ afffile_T *affile;
+ char_u *afflist;
+{
+ int flags = 0;
+
+ if (affile->af_keepcase != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_keepcase))
+ flags |= WF_KEEPCAP | WF_FIXCAP;
+ if (affile->af_rare != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_rare))
+ flags |= WF_RARE;
+ if (affile->af_bad != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_bad))
+ flags |= WF_BANNED;
+ if (affile->af_needcomp != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_needcomp))
+ flags |= WF_NEEDCOMP;
+ if (affile->af_comproot != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_comproot))
+ flags |= WF_COMPROOT;
+ if (affile->af_nosuggest != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_nosuggest))
+ flags |= WF_NOSUGGEST;
+ return flags;
+}
+
+/*
* Get the list of prefix IDs from the affix list "afflist".
* Used for PFXPOSTPONE.
* Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL
@@ -6604,7 +6635,7 @@ get_compflags(affile, afflist, store_afflist)
* Returns FAIL when out of memory.
*/
static int
-store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
+store_aff_word(spin, word, afflist, affile, ht, xht, condit, flags,
pfxlist, pfxlen)
spellinfo_T *spin; /* spell info */
char_u *word; /* basic word start */
@@ -6612,7 +6643,7 @@ store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
afffile_T *affile;
hashtab_T *ht;
hashtab_T *xht;
- int comb; /* only use affixes that combine */
+ int condit; /* CONDIT_SUF et al. */
int flags; /* flags for the word */
char_u *pfxlist; /* list of prefix IDs */
int pfxlen; /* nr of flags in "pfxlist" for prefixes, rest
@@ -6625,12 +6656,16 @@ store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
regmatch_T regmatch;
char_u newword[MAXWLEN];
int retval = OK;
- int i;
+ int i, j;
char_u *p;
int use_flags;
char_u *use_pfxlist;
+ int use_pfxlen;
+ int need_affix;
+ char_u store_afflist[MAXWLEN];
char_u pfx_pfxlist[MAXWLEN];
size_t wordlen = STRLEN(word);
+ int use_condit;
todo = ht->ht_used;
for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi)
@@ -6642,8 +6677,9 @@ store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
/* Check that the affix combines, if required, and that the word
* supports this affix. */
- if ((!comb || ah->ah_combine) && flag_in_afflist(
- affile->af_flagtype, afflist, ah->ah_flag))
+ if (((condit & CONDIT_COMB) == 0 || ah->ah_combine)
+ && flag_in_afflist(affile->af_flagtype, afflist,
+ ah->ah_flag))
{
/* Loop over all affix entries with this name. */
for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
@@ -6654,7 +6690,10 @@ store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
* Another requirement from Myspell is that the chop
* string is shorter than the word itself.
* For prefixes, when "PFXPOSTPONE" was used, only do
- * prefixes with a chop string and/or flags. */
+ * prefixes with a chop string and/or flags.
+ * When a previously added affix had CIRCUMFIX this one
+ * must have it too, if it had not then this one must not
+ * have one either. */
regmatch.regprog = ae->ae_prog;
regmatch.rm_ic = FALSE;
if ((xht != NULL || !affile->af_pfxpostpone
@@ -6663,7 +6702,12 @@ store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
&& (ae->ae_chop == NULL
|| STRLEN(ae->ae_chop) < wordlen)
&& (ae->ae_prog == NULL
- || vim_regexec(&regmatch, word, (colnr_T)0)))
+ || vim_regexec(&regmatch, word, (colnr_T)0))
+ && (((condit & CONDIT_CFIX) == 0)
+ == ((condit & CONDIT_AFF) == 0
+ || ae->ae_flags == NULL
+ || !flag_in_afflist(affile->af_flagtype,
+ ae->ae_flags, affile->af_circumfix))))
{
/* Match. Remove the chop and add the affix. */
if (xht == NULL)
@@ -6707,27 +6751,88 @@ store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
STRCAT(newword, ae->ae_add);
}
- /* Obey the "rare" flag of the affix. */
- if (affile->af_rare != 0
- && ae->ae_flags != NULL
- && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_rare))
- use_flags = flags | WF_RARE;
- else
- use_flags = flags;
+ use_flags = flags;
+ use_pfxlist = pfxlist;
+ use_pfxlen = pfxlen;
+ need_affix = FALSE;
+ use_condit = condit | CONDIT_COMB | CONDIT_AFF;
+ if (ae->ae_flags != NULL)
+ {
+ /* Extract flags from the affix list. */
+ use_flags |= get_affix_flags(affile, ae->ae_flags);
+
+ if (affile->af_needaffix != 0 && flag_in_afflist(
+ affile->af_flagtype, ae->ae_flags,
+ affile->af_needaffix))
+ need_affix = TRUE;
+
+ /* When there is a CIRCUMFIX flag the other affix
+ * must also have it and we don't add the word
+ * with one affix. */
+ if (affile->af_circumfix != 0 && flag_in_afflist(
+ affile->af_flagtype, ae->ae_flags,
+ affile->af_circumfix))
+ {
+ use_condit |= CONDIT_CFIX;
+ if ((condit & CONDIT_CFIX) == 0)
+ need_affix = TRUE;
+ }
+
+ if (affile->af_pfxpostpone
+ || spin->si_compflags != NULL)
+ {
+ if (affile->af_pfxpostpone)
+ /* Get prefix IDS from the affix list. */
+ use_pfxlen = get_pfxlist(affile,
+ ae->ae_flags, store_afflist);
+ else
+ use_pfxlen = 0;
+ use_pfxlist = store_afflist;
+
+ /* Combine the prefix IDs. Avoid adding the
+ * same ID twice. */
+ for (i = 0; i < pfxlen; ++i)
+ {
+ for (j = 0; j < use_pfxlen; ++j)
+ if (pfxlist[i] == use_pfxlist[j])
+ break;
+ if (j == use_pfxlen)
+ use_pfxlist[use_pfxlen++] = pfxlist[i];
+ }
+
+ if (spin->si_compflags != NULL)
+ /* Get compound IDS from the affix list. */
+ get_compflags(affile, ae->ae_flags,
+ use_pfxlist + use_pfxlen);
+
+ /* Combine the list of compound flags.
+ * Concatenate them to the prefix IDs list.
+ * Avoid adding the same ID twice. */
+ for (i = pfxlen; pfxlist[i] != NUL; ++i)
+ {
+ for (j = use_pfxlen;
+ use_pfxlist[j] != NUL; ++j)
+ if (pfxlist[i] == use_pfxlist[j])
+ break;
+ if (use_pfxlist[j] == NUL)
+ {
+ use_pfxlist[j++] = pfxlist[i];
+ use_pfxlist[j] = NUL;
+ }
+ }
+ }
+ }
/* Obey a "COMPOUNDFORBIDFLAG" of the affix: don't
* use the compound flags. */
- use_pfxlist = pfxlist;
- if (pfxlist != NULL
+ if (use_pfxlist != NULL
&& affile->af_compforbid != 0
&& ae->ae_flags != NULL
&& flag_in_afflist(
affile->af_flagtype, ae->ae_flags,
affile->af_compforbid))
{
- vim_strncpy(pfx_pfxlist, pfxlist, pfxlen);
+ vim_strncpy(pfx_pfxlist, use_pfxlist, use_pfxlen);
use_pfxlist = pfx_pfxlist;
}
@@ -6741,8 +6846,9 @@ store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
/* ... don't use a prefix list if combining
* affixes is not allowed. But do use the
* compound flags after them. */
- if ((!ah->ah_combine || comb) && pfxlist != NULL)
- use_pfxlist += pfxlen;
+ if ((!ah->ah_combine || (condit & CONDIT_COMB))
+ && use_pfxlist != NULL)
+ use_pfxlist += use_pfxlen;
}
/* When compounding is supported and there is no
@@ -6763,16 +6869,38 @@ store_aff_word(spin, word, afflist, affile, ht, xht, comb, flags,
/* Store the modified word. */
if (store_word(spin, newword, use_flags,
- spin->si_region, use_pfxlist, FALSE) == FAIL)
+ spin->si_region, use_pfxlist,
+ need_affix) == FAIL)
retval = FAIL;
+ /* When added a prefix or a first suffix and the affix
+ * has flags may add a(nother) suffix. RECURSIVE! */
+ if ((condit & CONDIT_SUF) && ae->ae_flags != NULL)
+ if (store_aff_word(spin, newword, ae->ae_flags,
+ affile, &affile->af_suff, xht,
+ use_condit & (xht == NULL
+ ? ~0 : ~CONDIT_SUF),
+ use_flags, use_pfxlist, pfxlen) == FAIL)
+ retval = FAIL;
+
/* When added a suffix and combining is allowed also
- * try adding prefixes additionally. RECURSIVE! */
+ * try adding a prefix additionally. Both for the
+ * word flags and for the affix flags. RECURSIVE! */
if (xht != NULL && ah->ah_combine)
- if (store_aff_word(spin, newword, afflist, affile,
- xht, NULL, TRUE,
- use_flags, use_pfxlist, pfxlen) == FAIL)
+ {
+ if (store_aff_word(spin, newword,
+ afflist, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL
+ || (ae->ae_flags != NULL
+ && store_aff_word(spin, newword,
+ ae->ae_flags, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL))
retval = FAIL;
+ }
}
}
}