diff options
Diffstat (limited to 'src/nvim/spell.c')
-rw-r--r-- | src/nvim/spell.c | 365 |
1 files changed, 186 insertions, 179 deletions
diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 1296d410f6..2aadc2258e 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -62,11 +62,11 @@ // 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) +#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) +#define MAXSCORE(word_score, sound_score) ((4 * (word_score) - (sound_score)) / 3) #include <assert.h> #include <inttypes.h> @@ -122,7 +122,7 @@ #define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP) // Result values. Lower number is accepted over higher one. -#define SP_BANNED -1 +#define SP_BANNED (-1) #define SP_RARE 0 #define SP_OK 1 #define SP_LOCAL 2 @@ -176,7 +176,7 @@ typedef struct { #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))) +#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 @@ -225,7 +225,7 @@ typedef struct { #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_BIG (SCORE_INS * 3) // big difference #define SCORE_MAXMAX 999999 // accept any score #define SCORE_LIMITMAX 350 // for spell_edit_score_limit() @@ -301,7 +301,6 @@ typedef struct { int score; } limitscore_T; - #ifdef INCLUDE_GENERATED_DECLARATIONS # include "spell.c.generated.h" #endif @@ -385,7 +384,7 @@ size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docou } else if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X')) { mi.mi_end = skiphex(ptr + 2); } else { - mi.mi_end = skipdigits(ptr); + mi.mi_end = (char_u *)skipdigits((char *)ptr); } nrlen = (size_t)(mi.mi_end - ptr); } @@ -397,7 +396,7 @@ size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docou bool this_upper = false; // init for gcc if (use_camel_case) { - c = utf_ptr2char(mi.mi_fend); + c = utf_ptr2char((char *)mi.mi_fend); this_upper = SPELL_ISUPPER(c); } @@ -405,7 +404,7 @@ size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docou MB_PTR_ADV(mi.mi_fend); if (use_camel_case) { const bool prev_upper = this_upper; - c = utf_ptr2char(mi.mi_fend); + c = utf_ptr2char((char *)mi.mi_fend); this_upper = SPELL_ISUPPER(c); camel_case = !prev_upper && this_upper; } @@ -414,7 +413,7 @@ size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docou if (capcol != NULL && *capcol == 0 && wp->w_s->b_cap_prog != NULL) { // Check word starting with capital letter. - c = utf_ptr2char(ptr); + c = utf_ptr2char((char *)ptr); if (!SPELL_ISUPPER(c)) { wrongcaplen = (size_t)(mi.mi_fend - ptr); } @@ -443,7 +442,7 @@ size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docou MAXWLEN + 1); mi.mi_fwordlen = (int)STRLEN(mi.mi_fword); - if (camel_case) { + if (camel_case && mi.mi_fwordlen > 0) { // introduce a fake word end space into the folded word. mi.mi_fword[mi.mi_fwordlen - 1] = ' '; } @@ -505,14 +504,14 @@ size_t spell_check(win_T *wp, char_u *ptr, hlf_T *attrp, int *capcol, bool docou // Check for end of sentence. regmatch.regprog = wp->w_s->b_cap_prog; regmatch.rm_ic = false; - int r = vim_regexec(®match, ptr, 0); + int r = vim_regexec(®match, (char *)ptr, 0); wp->w_s->b_cap_prog = regmatch.regprog; if (r) { *capcol = (int)(regmatch.endp[0] - ptr); } } - return (size_t)(utfc_ptr2len(ptr)); + return (size_t)(utfc_ptr2len((char *)ptr)); } else if (mi.mi_end == ptr) { // Always include at least one character. Required for when there // is a mixup in "midword". @@ -1086,7 +1085,7 @@ static bool can_compound(slang_T *slang, const char_u *word, const char_u *flags // Need to convert the single byte flags to utf8 characters. char_u *p = uflags; for (int i = 0; flags[i] != NUL; i++) { - p += utf_char2bytes(flags[i], p); + p += utf_char2bytes(flags[i], (char *)p); } *p = NUL; p = uflags; @@ -1173,7 +1172,7 @@ static bool match_compoundrule(slang_T *slang, char_u *compflags) } // Skip to the next "/", where the next pattern starts. - p = vim_strchr(p, '/'); + p = (char_u *)vim_strchr((char *)p, '/'); if (p == NULL) { break; } @@ -1303,7 +1302,6 @@ static void find_prefix(matchinf_T *mip, int mode) mip->mi_word); find_word(mip, FIND_PREFIX); - if (len == 0) { break; // no children, word must end here } @@ -1471,7 +1469,9 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att } // Copy the line into "buf" and append the start of the next line if - // possible. + // possible. Note: this ml_get_buf() may make "line" invalid, check + // for empty line first. + bool empty_line = *skipwhite((const char *)line) == NUL; STRCPY(buf, line); if (lnum < wp->w_buffer->b_ml.ml_line_count) { spell_cat_line(buf + STRLEN(buf), @@ -1578,7 +1578,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att lnum = wp->w_buffer->b_ml.ml_line_count; wrapped = true; if (!shortmess(SHM_SEARCH)) { - give_warning((char_u *)_(top_bot_msg), true); + give_warning(_(top_bot_msg), true); } } capcol = -1; @@ -1593,7 +1593,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att lnum = 1; wrapped = true; if (!shortmess(SHM_SEARCH)) { - give_warning((char_u *)_(bot_top_msg), true); + give_warning(_(bot_top_msg), true); } } @@ -1615,7 +1615,7 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att --capcol; // But after empty line check first word in next line - if (*skipwhite(line) == NUL) { + if (empty_line) { capcol = 0; } } @@ -1636,9 +1636,9 @@ void spell_cat_line(char_u *buf, char_u *line, int maxlen) char_u *p; int n; - p = skipwhite(line); - while (vim_strchr((char_u *)"*#/\"\t", *p) != NULL) { - p = skipwhite(p + 1); + p = (char_u *)skipwhite((char *)line); + while (vim_strchr("*#/\"\t", *p) != NULL) { + p = (char_u *)skipwhite((char *)p + 1); } if (*p != NUL) { @@ -1647,7 +1647,7 @@ void spell_cat_line(char_u *buf, char_u *line, int maxlen) n = (int)(p - line) + 1; if (n < maxlen - 1) { memset(buf, ' ', n); - STRLCPY(buf + n, p, maxlen - n); + STRLCPY(buf + n, p, maxlen - n); } } } @@ -1656,7 +1656,7 @@ void spell_cat_line(char_u *buf, char_u *line, int maxlen) // "lang" must be the language without the region: e.g., "en". static void spell_load_lang(char_u *lang) { - char_u fname_enc[85]; + char fname_enc[85]; int r; spelload_T sl; int round; @@ -1673,17 +1673,17 @@ static void spell_load_lang(char_u *lang) // Find the first spell file for "lang" in 'runtimepath' and load it. vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5, "spell/%s.%s.spl", lang, spell_enc()); - r = do_in_runtimepath(fname_enc, 0, spell_load_cb, &sl); + r = do_in_runtimepath((char *)fname_enc, 0, spell_load_cb, &sl); if (r == FAIL && *sl.sl_lang != NUL) { // Try loading the ASCII version. vim_snprintf((char *)fname_enc, sizeof(fname_enc) - 5, "spell/%s.ascii.spl", lang); - r = do_in_runtimepath(fname_enc, 0, spell_load_cb, &sl); + r = do_in_runtimepath((char *)fname_enc, 0, spell_load_cb, &sl); if (r == FAIL && *sl.sl_lang != NUL && round == 1 - && apply_autocmds(EVENT_SPELLFILEMISSING, lang, - curbuf->b_fname, FALSE, curbuf)) { + && apply_autocmds(EVENT_SPELLFILEMISSING, (char *)lang, + curbuf->b_fname, false, curbuf)) { continue; } break; @@ -1707,7 +1707,7 @@ static void spell_load_lang(char_u *lang) } else if (sl.sl_slang != NULL) { // At least one file was loaded, now load ALL the additions. STRCPY(fname_enc + STRLEN(fname_enc) - 3, "add.spl"); - do_in_runtimepath(fname_enc, DIP_ALL, spell_load_cb, &sl); + do_in_runtimepath((char *)fname_enc, DIP_ALL, spell_load_cb, &sl); } } @@ -1846,12 +1846,12 @@ void slang_clear_sug(slang_T *lp) // Load one spell file and store the info into a slang_T. // Invoked through do_in_runtimepath(). -static void spell_load_cb(char_u *fname, void *cookie) +static void spell_load_cb(char *fname, void *cookie) { spelload_T *slp = (spelload_T *)cookie; slang_T *slang; - slang = spell_load_file(fname, slp->sl_lang, NULL, false); + slang = spell_load_file((char_u *)fname, slp->sl_lang, NULL, false); if (slang != NULL) { // When a previously loaded file has NOBREAK also use it for the // ".add" files. @@ -1910,12 +1910,11 @@ void count_common_word(slang_T *lp, char_u *word, int len, int count) /// @param split word was split, less bonus static int score_wordcount_adj(slang_T *slang, int score, char_u *word, bool split) { - hashitem_T *hi; wordcount_T *wc; int bonus; int newscore; - hi = hash_find(&slang->sl_wordcount, word); + hashitem_T *hi = hash_find(&slang->sl_wordcount, (char *)word); if (!HASHITEM_EMPTY(hi)) { wc = HI2WC(hi); if (wc->wc_count < SCORE_THRES2) { @@ -1961,14 +1960,14 @@ int init_syl_tab(slang_T *slang) int l; ga_init(&slang->sl_syl_items, sizeof(syl_item_T), 4); - p = vim_strchr(slang->sl_syllable, '/'); + p = (char_u *)vim_strchr((char *)slang->sl_syllable, '/'); while (p != NULL) { *p++ = NUL; if (*p == NUL) { // trailing slash break; } s = p; - p = vim_strchr(p, '/'); + p = (char_u *)vim_strchr((char *)p, '/'); if (p == NULL) { l = (int)STRLEN(s); } else { @@ -2023,9 +2022,9 @@ static int count_syllables(slang_T *slang, const char_u *word) skip = false; } else { // No recognized syllable item, at least a syllable char then? - c = utf_ptr2char(p); - len = utfc_ptr2len(p); - if (vim_strchr(slang->sl_syllable, c) == NULL) { + c = utf_ptr2char((char *)p); + len = utfc_ptr2len((char *)p); + if (vim_strchr((char *)slang->sl_syllable, c) == NULL) { skip = false; // No, search for next syllable } else if (!skip) { ++cnt; // Yes, count it @@ -2085,7 +2084,7 @@ char *did_set_spelllang(win_T *wp) // Loop over comma separated language names. for (splp = spl_copy; *splp != NUL;) { // Get one language name. - copy_option_part(&splp, lang, MAXWLEN, ","); + copy_option_part((char **)&splp, (char *)lang, MAXWLEN, ","); region = NULL; len = (int)STRLEN(lang); @@ -2101,11 +2100,11 @@ char *did_set_spelllang(win_T *wp) // If the name ends in ".spl" use it as the name of the spell file. // If there is a region name let "region" point to it and remove it // from the name. - if (len > 4 && fnamecmp(lang + len - 4, ".spl") == 0) { + if (len > 4 && FNAMECMP(lang + len - 4, ".spl") == 0) { filename = true; // Locate a region and remove it from the file name. - p = vim_strchr(path_tail(lang), '_'); + p = (char_u *)vim_strchr(path_tail((char *)lang), '_'); if (p != NULL && ASCII_ISALPHA(p[1]) && ASCII_ISALPHA(p[2]) && !ASCII_ISALPHA(p[3])) { STRLCPY(region_cp, p + 1, 3); @@ -2117,7 +2116,7 @@ char *did_set_spelllang(win_T *wp) // Check if we loaded this language before. for (slang = first_lang; slang != NULL; slang = slang->sl_next) { - if (path_full_compare(lang, slang->sl_fname, false, true) + if (path_full_compare((char *)lang, (char *)slang->sl_fname, false, true) == kEqualFiles) { break; } @@ -2166,7 +2165,7 @@ char *did_set_spelllang(win_T *wp) // Loop over the languages, there can be several files for "lang". for (slang = first_lang; slang != NULL; slang = slang->sl_next) { if (filename - ? path_full_compare(lang, slang->sl_fname, false, true) == kEqualFiles + ? path_full_compare((char *)lang, (char *)slang->sl_fname, false, true) == kEqualFiles : STRICMP(lang, slang->sl_name) == 0) { region_mask = REGION_ALL; if (!filename && region != NULL) { @@ -2217,14 +2216,14 @@ char *did_set_spelllang(win_T *wp) int_wordlist_spl(spf_name); } else { // One entry in 'spellfile'. - copy_option_part(&spf, spf_name, MAXPATHL - 5, ","); + copy_option_part((char **)&spf, (char *)spf_name, MAXPATHL - 5, ","); STRCAT(spf_name, ".spl"); // If it was already found above then skip it. for (c = 0; c < ga.ga_len; ++c) { p = LANGP_ENTRY(ga, c)->lp_slang->sl_fname; if (p != NULL - && path_full_compare(spf_name, p, false, true) == kEqualFiles) { + && path_full_compare((char *)spf_name, (char *)p, false, true) == kEqualFiles) { break; } } @@ -2235,7 +2234,7 @@ char *did_set_spelllang(win_T *wp) // Check if it was loaded already. for (slang = first_lang; slang != NULL; slang = slang->sl_next) { - if (path_full_compare(spf_name, slang->sl_fname, false, true) + if (path_full_compare((char *)spf_name, (char *)slang->sl_fname, false, true) == kEqualFiles) { break; } @@ -2247,8 +2246,8 @@ char *did_set_spelllang(win_T *wp) if (round == 0) { STRCPY(lang, "internal wordlist"); } else { - STRLCPY(lang, path_tail(spf_name), MAXWLEN + 1); - p = vim_strchr(lang, '.'); + STRLCPY(lang, path_tail((char *)spf_name), MAXWLEN + 1); + p = (char_u *)vim_strchr((char *)lang, '.'); if (p != NULL) { *p = NUL; // truncate at ".encoding.add" } @@ -2330,11 +2329,11 @@ char *did_set_spelllang(win_T *wp) } } } + redraw_later(wp, NOT_VALID); theend: xfree(spl_copy); recursive = false; - redraw_later(wp, NOT_VALID); return ret_msg; } @@ -2355,8 +2354,8 @@ static void use_midword(slang_T *lp, win_T *wp) } for (char_u *p = lp->sl_midword; *p != NUL;) { - const int c = utf_ptr2char(p); - const int l = utfc_ptr2len(p); + const int c = utf_ptr2char((char *)p); + const int l = utfc_ptr2len((char *)p); if (c < 256 && l <= 2) { wp->w_s->b_spell_ismw[c] = true; } else if (wp->w_s->b_spell_ismw_mb == NULL) { @@ -2423,7 +2422,7 @@ int captype(char_u *word, char_u *end) // But a word with an upper char only at start is a ONECAP. for (; end == NULL ? *p != NUL : p < end; MB_PTR_ADV(p)) { if (spell_iswordp_nmw(p, curwin)) { - c = utf_ptr2char(p); + c = utf_ptr2char((char *)p); if (!SPELL_ISUPPER(c)) { // UUl -> KEEPCAP if (past_second && allcap) { @@ -2464,7 +2463,7 @@ static int badword_captype(char_u *word, char_u *end) l = u = 0; first = false; for (p = word; p < end; MB_PTR_ADV(p)) { - c = utf_ptr2char(p); + c = utf_ptr2char((char *)p); if (SPELL_ISUPPER(c)) { ++u; if (p == word) { @@ -2550,7 +2549,6 @@ void spell_reload(void) } } - // Opposite of offset2bytes(). // "pp" points to the bytes and is advanced over it. // Returns the offset. @@ -2674,7 +2672,7 @@ static bool spell_iswordp(const char_u *p, const win_T *wp) { int c; - const int l = utfc_ptr2len(p); + const int l = utfc_ptr2len((char *)p); const char_u *s = p; if (l == 1) { // be quick for ASCII @@ -2682,16 +2680,16 @@ static bool spell_iswordp(const char_u *p, const win_T *wp) s = p + 1; // skip a mid-word character } } else { - c = utf_ptr2char(p); + c = utf_ptr2char((char *)p); if (c < 256 ? wp->w_s->b_spell_ismw[c] : (wp->w_s->b_spell_ismw_mb != NULL - && vim_strchr(wp->w_s->b_spell_ismw_mb, c) != NULL)) { + && vim_strchr((char *)wp->w_s->b_spell_ismw_mb, c) != NULL)) { s = p + l; } } - c = utf_ptr2char(s); + c = utf_ptr2char((char *)s); if (c > 255) { return spell_mb_isword_class(mb_get_class(s), wp); } @@ -2702,7 +2700,7 @@ static bool spell_iswordp(const char_u *p, const win_T *wp) // Unlike spell_iswordp() this doesn't check for "midword" characters. bool spell_iswordp_nmw(const char_u *p, win_T *wp) { - int c = utf_ptr2char(p); + int c = utf_ptr2char((char *)p); if (c > 255) { return spell_mb_isword_class(mb_get_class(p), wp); } @@ -2730,9 +2728,10 @@ static bool spell_iswordp_w(const int *p, const win_T *wp) { const int *s; - if (*p < 256 ? wp->w_s->b_spell_ismw[*p] - : (wp->w_s->b_spell_ismw_mb != NULL - && vim_strchr(wp->w_s->b_spell_ismw_mb, *p) != NULL)) { + if (*p < + 256 ? wp->w_s->b_spell_ismw[*p] : (wp->w_s->b_spell_ismw_mb != NULL + && vim_strchr((char *)wp->w_s->b_spell_ismw_mb, + *p) != NULL)) { s = p + 1; } else { s = p; @@ -2779,7 +2778,7 @@ int spell_casefold(const win_T *wp, char_u *str, int len, char_u *buf, int bufle c = SPELL_TOFOLD(c); } - outi += utf_char2bytes(c, buf + outi); + outi += utf_char2bytes(c, (char *)buf + outi); } buf[outi] = NUL; @@ -2807,12 +2806,12 @@ int spell_check_sps(void) sps_limit = 9999; for (p = p_sps; *p != NUL;) { - copy_option_part(&p, buf, MAXPATHL, ","); + copy_option_part((char **)&p, (char *)buf, MAXPATHL, ","); f = 0; if (ascii_isdigit(*buf)) { s = buf; - sps_limit = getdigits_int(&s, true, 0); + sps_limit = getdigits_int((char **)&s, true, 0); if (*s != NUL && !ascii_isdigit(*s)) { f = -1; } @@ -3058,15 +3057,15 @@ void spell_suggest(int count) // For redo we use a change-word command. ResetRedobuff(); AppendToRedobuff("ciw"); - AppendToRedobuffLit(p + c, + AppendToRedobuffLit((char *)p + c, stp->st_wordlen + sug.su_badlen - stp->st_orglen); AppendCharToRedobuff(ESC); // "p" may be freed here - ml_replace(curwin->w_cursor.lnum, p, false); + ml_replace(curwin->w_cursor.lnum, (char *)p, false); curwin->w_cursor.col = c; - changed_bytes(curwin->w_cursor.lnum, c); + inserted_bytes(curwin->w_cursor.lnum, c, stp->st_orglen, stp->st_wordlen); } else { curwin->w_cursor = prev_cursor; } @@ -3100,7 +3099,7 @@ static bool check_need_cap(linenr_T lnum, colnr_T col) need_cap = true; } else { line = ml_get(lnum - 1); - if (*skipwhite(line) == NUL) { + if (*skipwhite((char *)line) == NUL) { need_cap = true; } else { // Append a space in place of the line break. @@ -3123,7 +3122,7 @@ static bool check_need_cap(linenr_T lnum, colnr_T col) if (p == line || spell_iswordp_nmw(p, curwin)) { break; } - if (vim_regexec(®match, p, 0) + if (vim_regexec(®match, (char *)p, 0) && regmatch.endp[0] == line + endcol) { need_cap = true; break; @@ -3137,7 +3136,6 @@ static bool check_need_cap(linenr_T lnum, colnr_T col) return need_cap; } - // ":spellrepall" void ex_spellrepall(exarg_T *eap) { @@ -3177,7 +3175,7 @@ void ex_spellrepall(exarg_T *eap) memmove(p, line, curwin->w_cursor.col); STRCPY(p + curwin->w_cursor.col, repl_to); STRCAT(p, line + curwin->w_cursor.col + STRLEN(repl_from)); - ml_replace(curwin->w_cursor.lnum, p, false); + ml_replace(curwin->w_cursor.lnum, (char *)p, false); changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col); if (curwin->w_cursor.lnum != prev_lnum) { @@ -3314,7 +3312,7 @@ static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int ma // If the word is not capitalised and spell_check() doesn't consider the // word to be bad then it might need to be capitalised. Add a suggestion // for that. - c = utf_ptr2char(su->su_badptr); + c = utf_ptr2char((char *)su->su_badptr); if (!SPELL_ISUPPER(c) && attr == HLF_COUNT) { make_case_word(su->su_badword, buf, WF_ONECAP); add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE, @@ -3331,7 +3329,7 @@ static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int ma // Loop over the items in 'spellsuggest'. for (p = sps_copy; *p != NUL;) { - copy_option_part(&p, buf, MAXPATHL, ","); + copy_option_part((char **)&p, (char *)buf, MAXPATHL, ","); if (STRNCMP(buf, "expr:", 5) == 0) { // Evaluate an expression. Skip this when called recursively, @@ -3372,7 +3370,7 @@ static void spell_suggest_expr(suginfo_T *su, char_u *expr) // The work is split up in a few parts to avoid having to export // suginfo_T. // First evaluate the expression and get the resulting list. - list_T *const list = eval_spell_expr(su->su_badword, expr); + list_T *const list = eval_spell_expr((char *)su->su_badword, (char *)expr); if (list != NULL) { // Loop over the items in the list. TV_LIST_ITER(list, li, { @@ -3413,15 +3411,14 @@ static void spell_suggest_file(suginfo_T *su, char_u *fname) while (!vim_fgets(line, MAXWLEN * 2, fd) && !got_int) { line_breakcheck(); - p = vim_strchr(line, '/'); + p = (char_u *)vim_strchr((char *)line, '/'); if (p == NULL) { continue; // No Tab found, just skip the line. } *p++ = NUL; if (STRICMP(su->su_badword, line) == 0) { // Match! Isolate the good word, until CR or NL. - for (len = 0; p[len] >= ' '; ++len) { - } + for (len = 0; p[len] >= ' '; len++) {} p[len] = NUL; // If the suggestion doesn't have specific case duplicate the case @@ -3523,7 +3520,7 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive) // Free the info put in "*su" by spell_find_suggest(). static void spell_find_cleanup(suginfo_T *su) { -#define FREE_SUG_WORD(sug) xfree(sug->st_word) +#define FREE_SUG_WORD(sug) xfree((sug)->st_word) // Free the suggestions. GA_DEEP_CLEAR(&su->su_ga, suggest_T, FREE_SUG_WORD); GA_DEEP_CLEAR(&su->su_sga, suggest_T, FREE_SUG_WORD); @@ -3548,7 +3545,7 @@ void onecap_copy(char_u *word, char_u *wcopy, bool upper) } else { c = SPELL_TOFOLD(c); } - int l = utf_char2bytes(c, wcopy); + int l = utf_char2bytes(c, (char *)wcopy); STRLCPY(wcopy + l, p, MAXWLEN - l); } @@ -3573,7 +3570,7 @@ static void allcap_copy(char_u *word, char_u *wcopy) if (d - wcopy >= MAXWLEN - MB_MAXBYTES) { break; } - d += utf_char2bytes(c, d); + d += utf_char2bytes(c, (char *)d); } *d = NUL; } @@ -3589,7 +3586,7 @@ static void suggest_try_special(suginfo_T *su) // Recognize a word that is repeated: "the the". p = skiptowhite(su->su_fbadword); len = p - su->su_fbadword; - p = skipwhite(p); + p = (char_u *)skipwhite((char *)p); if (STRLEN(p) == len && STRNCMP(su->su_fbadword, p, len) == 0) { // Include badflags: if the badword is onecap or allcap // use that for the goodword too: "The the" -> "The". @@ -3667,6 +3664,12 @@ static void suggest_try_change(suginfo_T *su) p = su->su_badptr + su->su_badlen; (void)spell_casefold(curwin, p, (int)STRLEN(p), fword + n, MAXWLEN - n); + // Make sure the resulting text is not longer than the original text. + n = (int)STRLEN(su->su_badptr); + if (n < MAXWLEN) { + fword[n] = NUL; + } + for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) { lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); @@ -3690,7 +3693,7 @@ static void suggest_try_change(suginfo_T *su) // Check the maximum score, if we go over it we won't try this change. #define TRY_DEEPER(su, stack, depth, add) \ - (stack[depth].ts_score + (add) < su->su_maxscore) + ((depth) < MAXWLEN - 1 && (stack)[depth].ts_score + (add) < (su)->su_maxscore) // Try finding suggestions by adding/removing/swapping letters. // @@ -3794,6 +3797,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so } } + // The loop may take an indefinite amount of time. Break out after five + // sectonds. TODO(vim): add an option for the time limit. + proftime_T time_limit = profile_setlimit(5000); + // Loop to find all suggestions. At each round we either: // - For the current state try one operation, advance "ts_curi", // increase "depth". @@ -3812,8 +3819,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so if (sp->ts_prefixdepth == PFD_PREFIXTREE) { // Skip over the NUL bytes, we use them later. - for (n = 0; n < len && byts[arridx + n] == 0; ++n) { - } + for (n = 0; n < len && byts[arridx + n] == 0; n++) {} sp->ts_curi += n; // Always past NUL bytes now. @@ -3824,7 +3830,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // At end of a prefix or at start of prefixtree: check for // following word. - if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX) { + if (depth < MAXWLEN - 1 && (byts[arridx] == 0 || n == STATE_NOPREFIX)) { // Set su->su_badflags to the caps type at this position. // Use the caps type until here for the prefix itself. n = nofold_len(fword, sp->ts_fidx, su->su_badptr); @@ -3886,8 +3892,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // none this must be the first try without a prefix. n = stack[sp->ts_prefixdepth].ts_arridx; len = pbyts[n++]; - for (c = 0; c < len && pbyts[n + c] == 0; ++c) { - } + for (c = 0; c < len && pbyts[n + c] == 0; c++) {} if (c > 0) { c = valid_word_prefix(c, n, flags, tword + sp->ts_splitoff, slang, false); @@ -3976,7 +3981,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so if (compound_ok) { p = preword; while (*skiptowhite(p) != NUL) { - p = skipwhite(skiptowhite(p)); + p = (char_u *)skipwhite((char *)skiptowhite(p)); } if (fword_ends && !can_compound(slang, p, compflags + sp->ts_compsplit)) { @@ -4008,7 +4013,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so c = su->su_badflags; if ((c & WF_ALLCAP) && su->su_badlen == - utfc_ptr2len(su->su_badptr)) { + utfc_ptr2len((char *)su->su_badptr)) { c = WF_ONECAP; } c |= flags; @@ -4030,8 +4035,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so break; } if ((sp->ts_complen == sp->ts_compsplit - && WAS_BANNED(su, preword + sp->ts_prewordlen)) - || WAS_BANNED(su, preword)) { + && WAS_BANNED(su, (char *)preword + sp->ts_prewordlen)) + || WAS_BANNED(su, (char *)preword)) { if (slang->sl_compprog == NULL) { break; } @@ -4198,7 +4203,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so } p = preword; while (*skiptowhite(p) != NUL) { - p = skipwhite(skiptowhite(p)); + p = (char_u *)skipwhite((char *)skiptowhite(p)); } if (sp->ts_complen > sp->ts_compsplit && !can_compound(slang, p, @@ -4257,7 +4262,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so && goodword_ends) { int l; - l = utfc_ptr2len(fword + sp->ts_fidx); + l = utfc_ptr2len((char *)fword + sp->ts_fidx); if (fword_ends) { // Copy the skipped character to preword. memmove(preword + sp->ts_prewordlen, @@ -4377,7 +4382,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so #endif ++depth; sp = &stack[depth]; - ++sp->ts_fidx; + if (fword[sp->ts_fidx] != NUL) { + sp->ts_fidx++; + } tword[sp->ts_twordlen++] = c; sp->ts_arridx = idxs[arridx]; if (newscore == SCORE_SUBST) { @@ -4393,7 +4400,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so sp->ts_fcharstart = sp->ts_fidx - 1; sp->ts_isdiff = (newscore != 0) ? DIFF_YES : DIFF_NONE; - } else if (sp->ts_isdiff == DIFF_INSERT) { + } else if (sp->ts_isdiff == DIFF_INSERT && sp->ts_fidx > 0) { // When inserting trail bytes don't advance in the // bad word. sp->ts_fidx--; @@ -4404,22 +4411,22 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // Correct ts_fidx for the byte length of the // character (we didn't check that before). sp->ts_fidx = sp->ts_fcharstart - + utfc_ptr2len(fword + sp->ts_fcharstart); + + utfc_ptr2len((char *)fword + sp->ts_fcharstart); // For changing a composing character adjust // the score from SCORE_SUBST to // SCORE_SUBCOMP. - if (utf_iscomposing(utf_ptr2char(tword + sp->ts_twordlen + if (utf_iscomposing(utf_ptr2char((char *)tword + sp->ts_twordlen - sp->ts_tcharlen)) - && utf_iscomposing(utf_ptr2char(fword + && utf_iscomposing(utf_ptr2char((char *)fword + sp->ts_fcharstart))) { sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP; - } else if ( - !soundfold + } else if (!soundfold && slang->sl_has_map && similar_chars(slang, - utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen), - utf_ptr2char(fword + sp->ts_fcharstart))) { + utf_ptr2char((char *)tword + sp->ts_twordlen - + sp->ts_tcharlen), + utf_ptr2char((char *)fword + sp->ts_fcharstart))) { // For a similar character adjust score from // SCORE_SUBST to SCORE_SIMILAR. sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR; @@ -4427,7 +4434,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so } else if (sp->ts_isdiff == DIFF_INSERT && sp->ts_twordlen > sp->ts_tcharlen) { p = tword + sp->ts_twordlen - sp->ts_tcharlen; - c = utf_ptr2char(p); + c = utf_ptr2char((char *)p); if (utf_iscomposing(c)) { // Inserting a composing char doesn't // count that much. @@ -4439,7 +4446,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // tree (might seem illogical but does // give better scores). MB_PTR_BACK(tword, p); - if (c == utf_ptr2char(p)) { + if (c == utf_ptr2char((char *)p)) { sp->ts_score -= SCORE_INS - SCORE_INSDUP; } } @@ -4490,11 +4497,11 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // score if the same character is following "nn" -> "n". It's // a bit illogical for soundfold tree but it does give better // results. - c = utf_ptr2char(fword + sp->ts_fidx); - stack[depth].ts_fidx += utfc_ptr2len(fword + sp->ts_fidx); + c = utf_ptr2char((char *)fword + sp->ts_fidx); + stack[depth].ts_fidx += utfc_ptr2len((char *)fword + sp->ts_fidx); if (utf_iscomposing(c)) { stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP; - } else if (c == utf_ptr2char(fword + stack[depth].ts_fidx)) { + } else if (c == utf_ptr2char((char *)fword + stack[depth].ts_fidx)) { stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP; } @@ -4609,14 +4616,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so break; } - n = utf_ptr2len(p); - c = utf_ptr2char(p); + n = utf_ptr2len((char *)p); + c = utf_ptr2char((char *)p); if (p[n] == NUL) { c2 = NUL; } else if (!soundfold && !spell_iswordp(p + n, curwin)) { c2 = c; // don't swap non-word char } else { - c2 = utf_ptr2char(p + n); + c2 = utf_ptr2char((char *)p + n); } // When the second character is NUL we can't swap. @@ -4646,7 +4653,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so depth++; fl = utf_char2len(c2); memmove(p, p + n, fl); - utf_char2bytes(c, p + fl); + utf_char2bytes(c, (char *)p + fl); stack[depth].ts_fidxtry = sp->ts_fidx + n + fl; } else { // If this swap doesn't work then SWAP3 won't either. @@ -4658,10 +4665,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so case STATE_UNSWAP: // Undo the STATE_SWAP swap: "21" -> "12". p = fword + sp->ts_fidx; - n = utfc_ptr2len(p); - c = utf_ptr2char(p + n); - memmove(p + utfc_ptr2len(p + n), p, n); - utf_char2bytes(c, p); + n = utfc_ptr2len((char *)p); + c = utf_ptr2char((char *)p + n); + memmove(p + utfc_ptr2len((char *)p + n), p, n); + utf_char2bytes(c, (char *)p); FALLTHROUGH; @@ -4669,14 +4676,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so // Swap two bytes, skipping one: "123" -> "321". We change // "fword" here, it's changed back afterwards at STATE_UNSWAP3. p = fword + sp->ts_fidx; - n = utf_ptr2len(p); - c = utf_ptr2char(p); - fl = utf_ptr2len(p + n); - c2 = utf_ptr2char(p + n); + n = utf_ptr2len((char *)p); + c = utf_ptr2char((char *)p); + fl = utf_ptr2len((char *)p + n); + c2 = utf_ptr2char((char *)p + n); if (!soundfold && !spell_iswordp(p + n + fl, curwin)) { c3 = c; // don't swap non-word char } else { - c3 = utf_ptr2char(p + n + fl); + c3 = utf_ptr2char((char *)p + n + fl); } // When characters are identical: "121" then SWAP3 result is @@ -4702,8 +4709,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so depth++; tl = utf_char2len(c3); memmove(p, p + n + fl, tl); - utf_char2bytes(c2, p + tl); - utf_char2bytes(c, p + fl + tl); + utf_char2bytes(c2, (char *)p + tl); + utf_char2bytes(c, (char *)p + fl + tl); stack[depth].ts_fidxtry = sp->ts_fidx + n + fl + tl; } else { PROF_STORE(sp->ts_state) @@ -4714,14 +4721,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so case STATE_UNSWAP3: // Undo STATE_SWAP3: "321" -> "123" p = fword + sp->ts_fidx; - n = utfc_ptr2len(p); - c2 = utf_ptr2char(p + n); - fl = utfc_ptr2len(p + n); - c = utf_ptr2char(p + n + fl); - tl = utfc_ptr2len(p + n + fl); + n = utfc_ptr2len((char *)p); + c2 = utf_ptr2char((char *)p + n); + fl = utfc_ptr2len((char *)p + n); + c = utf_ptr2char((char *)p + n + fl); + tl = utfc_ptr2len((char *)p + n + fl); memmove(p + fl + tl, p, n); - utf_char2bytes(c, p); - utf_char2bytes(c2, p + tl); + utf_char2bytes(c, (char *)p); + utf_char2bytes(c2, (char *)p + tl); p = p + tl; if (!soundfold && !spell_iswordp(p, curwin)) { @@ -4746,12 +4753,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so sp->ts_state = STATE_UNROT3L; ++depth; p = fword + sp->ts_fidx; - n = utf_ptr2len(p); - c = utf_ptr2char(p); - fl = utf_ptr2len(p + n); - fl += utf_ptr2len(p + n + fl); + n = utf_ptr2len((char *)p); + c = utf_ptr2char((char *)p); + fl = utf_ptr2len((char *)p + n); + fl += utf_ptr2len((char *)p + n + fl); memmove(p, p + n, fl); - utf_char2bytes(c, p + fl); + utf_char2bytes(c, (char *)p + fl); stack[depth].ts_fidxtry = sp->ts_fidx + n + fl; } else { PROF_STORE(sp->ts_state) @@ -4762,12 +4769,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so case STATE_UNROT3L: // Undo ROT3L: "231" -> "123" p = fword + sp->ts_fidx; - n = utfc_ptr2len(p); - n += utfc_ptr2len(p + n); - c = utf_ptr2char(p + n); - tl = utfc_ptr2len(p + n); + n = utfc_ptr2len((char *)p); + n += utfc_ptr2len((char *)p + n); + c = utf_ptr2char((char *)p + n); + tl = utfc_ptr2len((char *)p + n); memmove(p + tl, p, n); - utf_char2bytes(c, p); + utf_char2bytes(c, (char *)p); // Rotate three bytes right: "123" -> "312". We change "fword" // here, it's changed back afterwards at STATE_UNROT3R. @@ -4783,12 +4790,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so sp->ts_state = STATE_UNROT3R; ++depth; p = fword + sp->ts_fidx; - n = utf_ptr2len(p); - n += utf_ptr2len(p + n); - c = utf_ptr2char(p + n); - tl = utf_ptr2len(p + n); + n = utf_ptr2len((char *)p); + n += utf_ptr2len((char *)p + n); + c = utf_ptr2char((char *)p + n); + tl = utf_ptr2len((char *)p + n); memmove(p + tl, p, n); - utf_char2bytes(c, p); + utf_char2bytes(c, (char *)p); stack[depth].ts_fidxtry = sp->ts_fidx + n + tl; } else { PROF_STORE(sp->ts_state) @@ -4799,12 +4806,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so case STATE_UNROT3R: // Undo ROT3R: "312" -> "123" p = fword + sp->ts_fidx; - c = utf_ptr2char(p); - tl = utfc_ptr2len(p); - n = utfc_ptr2len(p + tl); - n += utfc_ptr2len(p + tl + n); + c = utf_ptr2char((char *)p); + tl = utfc_ptr2len((char *)p); + n = utfc_ptr2len((char *)p + tl); + n += utfc_ptr2len((char *)p + tl + n); memmove(p, p + tl, n); - utf_char2bytes(c, p + n); + utf_char2bytes(c, (char *)p + n); FALLTHROUGH; @@ -4927,12 +4934,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so if (--breakcheckcount == 0) { os_breakcheck(); breakcheckcount = 1000; + if (profile_passed_limit(time_limit)) { + got_int = true; + } } } } } - // Go one level deeper in the tree. static void go_deeper(trystate_T *stack, int depth, int score_add) { @@ -5021,8 +5030,8 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword) } else { // round[depth] == 1: Try using the folded-case character. // round[depth] == 2: Try using the upper-case character. - flen = utf_ptr2len(fword + fwordidx[depth]); - ulen = utf_ptr2len(uword + uwordidx[depth]); + flen = utf_ptr2len((char *)fword + fwordidx[depth]); + ulen = utf_ptr2len((char *)uword + uwordidx[depth]); if (round[depth] == 1) { p = fword + fwordidx[depth]; l = flen; @@ -5284,7 +5293,7 @@ static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u * } static sftword_T dumsft; -#define HIKEY2SFT(p) ((sftword_T *)(p - (dumsft.sft_word - (char_u *)&dumsft))) +#define HIKEY2SFT(p) ((sftword_T *)((p) - (dumsft.sft_word - (char_u *)&dumsft))) #define HI2SFT(hi) HIKEY2SFT((hi)->hi_key) // Prepare for calling suggest_try_soundalike(). @@ -5512,9 +5521,9 @@ badword: // lower to upper case. Helps for "tath" -> "Kath", which is // less common than "tath" -> "path". Don't do it when the // letter is the same, that has already been counted. - gc = utf_ptr2char(p); + gc = utf_ptr2char((char *)p); if (SPELL_ISUPPER(gc)) { - bc = utf_ptr2char(su->su_badword); + bc = utf_ptr2char((char *)su->su_badword); if (!SPELL_ISUPPER(bc) && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc)) { goodscore += SCORE_ICASE / 2; @@ -5648,16 +5657,16 @@ static void make_case_word(char_u *fword, char_u *cword, int flags) static bool similar_chars(slang_T *slang, int c1, int c2) { int m1, m2; - char_u buf[MB_MAXBYTES + 1]; + char buf[MB_MAXBYTES + 1]; hashitem_T *hi; if (c1 >= 256) { - buf[utf_char2bytes(c1, buf)] = 0; + buf[utf_char2bytes(c1, (char *)buf)] = 0; hi = hash_find(&slang->sl_map_hash, buf); if (HASHITEM_EMPTY(hi)) { m1 = 0; } else { - m1 = utf_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1); + m1 = utf_ptr2char((char *)hi->hi_key + STRLEN(hi->hi_key) + 1); } } else { m1 = slang->sl_map_array[c1]; @@ -5667,12 +5676,12 @@ static bool similar_chars(slang_T *slang, int c1, int c2) } if (c2 >= 256) { - buf[utf_char2bytes(c2, buf)] = 0; + buf[utf_char2bytes(c2, (char *)buf)] = 0; hi = hash_find(&slang->sl_map_hash, buf); if (HASHITEM_EMPTY(hi)) { m2 = 0; } else { - m2 = utf_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1); + m2 = utf_ptr2char((char *)hi->hi_key + STRLEN(hi->hi_key) + 1); } } else { m2 = slang->sl_map_array[c2]; @@ -5709,7 +5718,7 @@ static void add_suggestion(suginfo_T *su, garray_T *gap, const char_u *goodword, } MB_PTR_BACK(goodword, pgood); MB_PTR_BACK(su->su_badptr, pbad); - if (utf_ptr2char(pgood) != utf_ptr2char(pbad)) { + if (utf_ptr2char((char *)pgood) != utf_ptr2char((char *)pbad)) { break; } } @@ -5829,7 +5838,6 @@ static void check_suggestions(suginfo_T *su, garray_T *gap) } } - // Add a word to be banned. static void add_banned(suginfo_T *su, char_u *word) { @@ -5883,7 +5891,6 @@ static void rescore_one(suginfo_T *su, suggest_T *stp) } } - // Function given to qsort() to sort the suggestions on st_score. // First on "st_score", then "st_altscore" then alphabetically. static int sug_compare(const void *s1, const void *s2) @@ -6030,7 +6037,7 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res) } if (c != NUL && c != prevc) { - ri += utf_char2bytes(c, res + ri); + ri += utf_char2bytes(c, (char *)res + ri); if (ri + MB_MAXBYTES > MAXWLEN) { break; } @@ -6064,7 +6071,6 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) bool did_white = false; int wordlen; - // Convert the multi-byte string to a wide-character string. // Remove accents, if wanted. We actually remove all non-word characters. // But keep white space. @@ -6256,7 +6262,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) // replace string ws = smp[n].sm_to_w; s = smp[n].sm_rules; - p0 = (vim_strchr(s, '<') != NULL) ? 1 : 0; + p0 = (vim_strchr((char *)s, '<') != NULL) ? 1 : 0; if (p0 == 1 && z == 0) { // rule with '<' is used if (reslen > 0 && ws != NULL && *ws != NUL @@ -6335,7 +6341,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res) // Convert wide characters in "wres" to a multi-byte string in "res". l = 0; for (n = 0; n < reslen; n++) { - l += utf_char2bytes(wres[n], res + l); + l += utf_char2bytes(wres[n], (char *)res + l); if (l + MB_MAXBYTES > MAXWLEN) { break; } @@ -6867,7 +6873,7 @@ void ex_spellinfo(exarg_T *eap) // ":spelldump" void ex_spelldump(exarg_T *eap) { - char_u *spl; + char *spl; long dummy; if (no_spell_checking(curwin)) { @@ -6880,7 +6886,7 @@ void ex_spelldump(exarg_T *eap) // enable spelling locally in the new window set_option_value("spell", true, "", OPT_LOCAL); - set_option_value("spl", dummy, (char *)spl, OPT_LOCAL); + set_option_value("spl", dummy, spl, OPT_LOCAL); xfree(spl); if (!buf_is_empty(curbuf)) { @@ -6936,7 +6942,7 @@ void spell_dump_compl(char_u *pat, int ic, Direction *dir, int dumpflags_arg) if (n == WF_ONECAP) { dumpflags |= DUMPFLAG_ONECAP; } else if (n == WF_ALLCAP - && (int)STRLEN(pat) > utfc_ptr2len(pat)) { + && (int)STRLEN(pat) > utfc_ptr2len((char *)pat)) { dumpflags |= DUMPFLAG_ALLCAP; } } @@ -6960,7 +6966,7 @@ void spell_dump_compl(char_u *pat, int ic, Direction *dir, int dumpflags_arg) if (do_region && region_names != NULL) { if (pat == NULL) { vim_snprintf((char *)IObuff, IOSIZE, "/regions=%s", region_names); - ml_append(lnum++, IObuff, (colnr_T)0, false); + ml_append(lnum++, (char *)IObuff, (colnr_T)0, false); } } else { do_region = false; @@ -6976,7 +6982,7 @@ void spell_dump_compl(char_u *pat, int ic, Direction *dir, int dumpflags_arg) if (pat == NULL) { vim_snprintf((char *)IObuff, IOSIZE, "# file: %s", slang->sl_fname); - ml_append(lnum++, IObuff, (colnr_T)0, false); + ml_append(lnum++, (char *)IObuff, (colnr_T)0, false); } // When matching with a pattern and there are no prefixes only use @@ -7017,8 +7023,9 @@ void spell_dump_compl(char_u *pat, int ic, Direction *dir, int dumpflags_arg) n = arridx[depth] + curi[depth]; ++curi[depth]; c = byts[n]; - if (c == 0) { - // End of word, deal with the word. + if (c == 0 || depth >= MAXWLEN - 1) { + // End of word or reached maximum length, deal with the + // word. // Don't use keep-case words in the fold-case tree, // they will appear in the keep-case tree. // Only use the word when the region matches. @@ -7139,7 +7146,7 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat, Direction *dir, hashitem_T *hi; // Include the word count for ":spelldump!". - hi = hash_find(&slang->sl_wordcount, tw); + hi = hash_find(&slang->sl_wordcount, (char *)tw); if (!HASHITEM_EMPTY(hi)) { vim_snprintf((char *)IObuff, IOSIZE, "%s\t%d", tw, HI2WC(hi)->wc_count); @@ -7147,7 +7154,7 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat, Direction *dir, } } - ml_append(lnum, p, (colnr_T)0, false); + ml_append(lnum, (char *)p, (colnr_T)0, false); } else if (((dumpflags & DUMPFLAG_ICASE) ? mb_strnicmp(p, pat, STRLEN(pat)) == 0 : STRNCMP(p, pat, STRLEN(pat)) == 0) @@ -7185,7 +7192,7 @@ static linenr_T dump_prefixes(slang_T *slang, char_u *word, char_u *pat, Directi // If the word starts with a lower-case letter make the word with an // upper-case letter in word_up[]. - c = utf_ptr2char(word); + c = utf_ptr2char((char *)word); if (SPELL_TOUPPER(c) != c) { onecap_copy(word, word_up, true); has_word_up = true; |