diff options
author | Bram Moolenaar <Bram@vim.org> | 2005-04-20 19:37:22 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2005-04-20 19:37:22 +0000 |
commit | 2cf8b301df39f742c07d10dadbbe19218dcc1845 (patch) | |
tree | 21b7335c37fdcde16ea27ee645406fa2548ab5e0 /src | |
parent | 2c5bc17eb722da0257d125fae18e48ab0122f460 (diff) | |
download | vim-2cf8b301df39f742c07d10dadbbe19218dcc1845.zip |
updated for version 7.0069
Diffstat (limited to 'src')
-rw-r--r-- | src/normal.c | 9 | ||||
-rw-r--r-- | src/spell.c | 442 |
2 files changed, 344 insertions, 107 deletions
diff --git a/src/normal.c b/src/normal.c index 85d84c45b..e5404ef53 100644 --- a/src/normal.c +++ b/src/normal.c @@ -6071,9 +6071,14 @@ nv_brackets(cap) */ else if (cap->nchar == 's' || cap->nchar == 'S') { - if (spell_move_to(cap->cmdchar == ']' ? FORWARD : BACKWARD, + setpcmark(); + for (n = 0; n < cap->count1; ++n) + if (spell_move_to(cap->cmdchar == ']' ? FORWARD : BACKWARD, cap->nchar == 's' ? TRUE : FALSE) == FAIL) - clearopbeep(cap->oap); + { + clearopbeep(cap->oap); + break; + } } #endif diff --git a/src/spell.c b/src/spell.c index 618b4d390..cc71b8d7d 100644 --- a/src/spell.c +++ b/src/spell.c @@ -203,6 +203,7 @@ typedef struct langp_S #define BWF_ALLCAP 0x0400 /* all letters must be capital (not used for single-letter words) */ #define BWF_KEEPCAP 0x0800 /* Keep case as-is */ +#define BWF_ADDS_M 0x1000 /* there are more than 255 additions */ #define BWF_ADDHASH 0x8000 /* Internal: use hashtab for additions */ @@ -212,6 +213,8 @@ typedef struct langp_S /* flags used for addition in the spell file */ #define ADD_REGION 0x02 /* region byte follows */ #define ADD_ONECAP 0x04 /* first letter must be capital */ +#define ADD_LEADLEN 0x10 /* there is a leadlen byte */ +#define ADD_COPYLEN 0x20 /* there is a copylen byte */ #define ADD_ALLCAP 0x40 /* all letters must be capital (not used for single-letter words) */ #define ADD_KEEPCAP 0x80 /* fixed case */ @@ -220,7 +223,7 @@ typedef struct langp_S * (Needed to keep ADD_ flags in one byte.) */ #define ADD2BWF(x) (((x) & 0x0f) | (((x) & 0xf0) << 4)) -#define VIMSPELLMAGIC "VIMspell02" /* string at start of Vim spell file */ +#define VIMSPELLMAGIC "VIMspell03" /* string at start of Vim spell file */ #define VIMSPELLMAGICL 10 /* @@ -1164,13 +1167,17 @@ spell_move_to(dir, allwords) int dir; /* FORWARD or BACKWARD */ int allwords; /* TRUE for "[s" and "]s" */ { - pos_T pos; + linenr_T lnum; + pos_T found_pos; char_u *line; char_u *p; int wc; int nwc; int attr = 0; int len; + int has_syntax = syntax_present(curbuf); + int col; + int can_spell; if (!curwin->w_p_spell || *curwin->w_buffer->b_p_spl == NUL) { @@ -1178,37 +1185,81 @@ spell_move_to(dir, allwords) return FAIL; } - /* TODO: moving backwards */ - - /* Start looking for bad word at the start of the line, because we can't - * start halfway a word and know where it ends. */ - pos = curwin->w_cursor; - pos.col = 0; - wc = FALSE; + /* + * Start looking for bad word at the start of the line, because we can't + * start halfway a word, we don't know where it starts or ends. + * + * When searching backwards, we continue in the line to find the last + * bad word (in the cursor line: before the cursor). + */ + lnum = curwin->w_cursor.lnum; + found_pos.lnum = 0; while (!got_int) { - line = ml_get(pos.lnum); - p = line + pos.col; + line = ml_get(lnum); + p = line; + wc = FALSE; + while (*p != NUL) { nwc = spell_iswordc(p); if (!wc && nwc) { + /* When searching backward don't search after the cursor. */ + if (dir == BACKWARD + && lnum == curwin->w_cursor.lnum + && (colnr_T)(p - line) >= curwin->w_cursor.col) + break; + /* start of word */ - /* TODO: check for bad word attr */ len = spell_check(curwin, line, p, &attr); + if (attr != 0) { - if (curwin->w_cursor.lnum < pos.lnum - || (curwin->w_cursor.lnum == pos.lnum - && curwin->w_cursor.col < (colnr_T)(p - line))) + /* We found a bad word. Check the attribute. */ + /* TODO: check for syntax @Spell cluster. */ + if (allwords || attr == highlight_attr[HLF_SPB]) { - curwin->w_cursor.lnum = pos.lnum; - curwin->w_cursor.col = p - line; - return OK; + /* When searching forward only accept a bad word after + * the cursor. */ + if (dir == BACKWARD + || lnum > curwin->w_cursor.lnum + || (lnum == curwin->w_cursor.lnum + && (colnr_T)(p - line) + > curwin->w_cursor.col)) + { + if (has_syntax) + { + col = p - line; + (void)syn_get_id(lnum, (colnr_T)col, + FALSE, &can_spell); + + /* have to get the line again, a multi-line + * regexp may make it invalid */ + line = ml_get(lnum); + p = line + col; + } + else + can_spell = TRUE; + + if (can_spell) + { + found_pos.lnum = lnum; + found_pos.col = p - line; +#ifdef FEAT_VIRTUALEDIT + found_pos.coladd = 0; +#endif + if (dir == FORWARD) + { + /* No need to search further. */ + curwin->w_cursor = found_pos; + return OK; + } + } + } } - attr = 0; /* bad word is before or at cursor */ + attr = 0; } p += len; if (*p == NUL) @@ -1222,11 +1273,24 @@ spell_move_to(dir, allwords) } /* Advance to next line. */ - if (pos.lnum == curbuf->b_ml.ml_line_count) - return FAIL; - ++pos.lnum; - pos.col = 0; - wc = FALSE; + if (dir == BACKWARD) + { + if (found_pos.lnum != 0) + { + /* Use the last match in the line. */ + curwin->w_cursor = found_pos; + return OK; + } + if (lnum == 1) + return FAIL; + --lnum; + } + else + { + if (lnum == curbuf->b_ml.ml_line_count) + return FAIL; + ++lnum; + } line_breakcheck(); } @@ -1773,7 +1837,10 @@ formerr: fw->fw_adds = NULL; if (flags & BWF_ADDS) { - adds = (getc(fd) << 8) + getc(fd); /* <addcnt> */ + if (flags & BWF_ADDS_M) + adds = (getc(fd) << 8) + getc(fd); /* <addcnt> */ + else + adds = getc(fd); /* <addcnt> */ if (adds > 30) { @@ -1795,8 +1862,8 @@ formerr: while (--adds >= 0) { - /* <add>: <addflags> <addlen> [<leadlen> <addstring>] - * [<region>] */ + /* <add>: <addflags> <addlen> [<leadlen>] [<copylen>] + * [<addstring>] [<region>] */ flags = getc(fd); /* <addflags> */ addlen = getc(fd); /* <addlen> */ if (addlen == EOF) @@ -1804,15 +1871,21 @@ formerr: if (addlen >= MAXWLEN) goto formerr; + if (flags & ADD_LEADLEN) + leadlen = getc(fd); /* <leadlen> */ + else + leadlen = 0; + if (addlen > 0) { - leadlen = getc(fd); /* <leadlen> */ - for (i = 0; i < addlen; ++i) /* <addstring> */ + if (flags & ADD_COPYLEN) + i = getc(fd); /* <copylen> */ + else + i = 0; + for ( ; i < addlen; ++i) /* <addstring> */ cbuf[i] = getc(fd); cbuf[i] = NUL; } - else - leadlen = 0; if (flags & ADD_KEEPCAP) { @@ -2292,6 +2365,20 @@ typedef struct affhash_S static affhash_T dumas; #define HI2AS(hi) ((affhash_T *)((hi)->hi_key - (dumas.as_word - (char_u *)&dumas))) +/* info for writing the spell file */ +typedef struct winfo_S +{ + FILE *wif_fd; + basicword_T *wif_prevbw; /* last written basic word */ + int wif_regionmask; /* regions supported */ + int wif_prefm; /* 1 or 2 bytes used for prefix NR */ + int wif_suffm; /* 1 or 2 bytes used for suffix NR */ + long wif_wcount; /* written word count */ + long wif_acount; /* written addition count */ + long wif_addmax; /* max number of additions on one word */ + char_u *wif_addmaxw; /* word with max additions */ +} winfo_T; + static afffile_T *spell_read_aff __ARGS((char_u *fname, vimconv_T *conv, int ascii)); static void spell_free_aff __ARGS((afffile_T *aff)); @@ -2313,7 +2400,7 @@ static void put_bytes __ARGS((FILE *fd, long_u nr, int len)); static void write_affix __ARGS((FILE *fd, affheader_T *ah)); static void write_affixlist __ARGS((FILE *fd, garray_T *aff, int bytes)); static void write_vim_spell __ARGS((char_u *fname, garray_T *prefga, garray_T *suffga, hashtab_T *newwords, int regcount, char_u *regchars)); -static void write_bword __ARGS((FILE *fd, basicword_T *bw, int lowcap, basicword_T **prevbw, int regionmask, int prefm, int suffm)); +static void write_bword __ARGS((winfo_T *wif, basicword_T *bw, int lowcap)); static void free_wordtable __ARGS((hashtab_T *ht)); static void free_basicword __ARGS((basicword_T *bw)); static void free_affixentries __ARGS((affentry_T *first)); @@ -4019,7 +4106,7 @@ write_affixlist(fd, aff, bytes) * * <HEADER>: <fileID> <regioncnt> <regionname> ... * - * <fileID> 10 bytes "VIMspell02" + * <fileID> 10 bytes "VIMspell03" * <regioncnt> 1 byte number of regions following (8 supported) * <regionname> 2 bytes Region name: ca, au, etc. * First <regionname> is region 1. @@ -4085,6 +4172,8 @@ write_affixlist(fd, aff, bytes) * BWF_PREFIX * 0x04: all letters must be upper-case, BWF_ALLCAP * 0x08: case must match, BWF_KEEPCAP + * 0x10: has more than 255 additions, <addcnt> is two + * bytes, BWF_ADDS_M * 0x10-0x80: unset * <caselen> 1 byte Length of <caseword>. * <caseword> N bytes Word with matching case. @@ -4094,20 +4183,23 @@ write_affixlist(fd, aff, bytes) * <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. - * <addcnt> 2 bytes Number of <add> items following. + * <addcnt> 1 or 2 byte Number of <add> items following. * - * <add>: <addflags> <addlen> [<leadlen> <addstring>] [<region>] + * <add>: <addflags> <addlen> [<leadlen>] [<copylen>] [<addstring>] [<region>] * * <addflags> 1 byte 0x01: unset * 0x02: has region byte, ADD_REGION * 0x04: first letter must be upper-case, ADD_ONECAP - * 0x08-0x20: unset + * 0x08: unset + * 0x10: has a <leadlen>, ADD_LEADLEN + * 0x20: has a <copylen>, ADD_COPYLEN * 0x40: all letters must be upper-case, ADD_ALLCAP * 0x80: fixed case, <addstring> is the whole word * with matching case, ADD_KEEPCAP. * <addlen> 1 byte Length of <addstring> in bytes. * <leadlen> 1 byte Number of bytes at start of <addstring> that must * come before the start of the basic word. + * <copylen> 1 byte Number of bytes copied from previous <addstring>. * <addstring> N bytes Word characters, before/in/after the word. * * All text characters are in 'encoding': <affchop>, <affadd>, <string>, @@ -4128,48 +4220,48 @@ write_vim_spell(fname, prefga, suffga, newwords, regcount, regchars) int regcount; /* number of regions */ char_u *regchars; /* region names */ { - FILE *fd; + winfo_T wif; garray_T *gap; hashitem_T *hi; char_u **wtab; int todo; int flags, aflags; - basicword_T *bw, *bwf, *bw2 = NULL, *prevbw = NULL; - int regionmask; /* mask for all relevant region bits */ + basicword_T *bw, *bwf, *bw2 = NULL; int i; int cnt; affentry_T *ae; int round; - int prefm, suffm; garray_T bwga; - fd = fopen((char *)fname, "w"); - if (fd == NULL) + vim_memset(&wif, 0, sizeof(winfo_T)); + + wif.wif_fd = fopen((char *)fname, "w"); + if (wif.wif_fd == NULL) { EMSG2(_(e_notopen), fname); return; } - fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd); + fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, wif.wif_fd); /* write the region names if there is more than one */ if (regcount > 1) { - putc(regcount, fd); - fwrite(regchars, (size_t)(regcount * 2), (size_t)1, fd); - regionmask = (1 << regcount) - 1; + putc(regcount, wif.wif_fd); + fwrite(regchars, (size_t)(regcount * 2), (size_t)1, wif.wif_fd); + wif.wif_regionmask = (1 << regcount) - 1; } else { - putc(0, fd); - regionmask = 0; + putc(0, wif.wif_fd); + wif.wif_regionmask = 0; } /* Write the prefix and suffix lists. */ for (round = 1; round <= 2; ++round) { gap = round == 1 ? prefga : suffga; - put_bytes(fd, (long_u)gap->ga_len, 2); /* <affcount> */ + put_bytes(wif.wif_fd, (long_u)gap->ga_len, 2); /* <affcount> */ /* Count the total number of affix items. */ cnt = 0; @@ -4177,27 +4269,28 @@ write_vim_spell(fname, prefga, suffga, newwords, regcount, regchars) for (ae = ((affheader_T *)gap->ga_data + i)->ah_first; ae != NULL; ae = ae->ae_next) ++cnt; - put_bytes(fd, (long_u)cnt, 2); /* <afftotcnt> */ + put_bytes(wif.wif_fd, (long_u)cnt, 2); /* <afftotcnt> */ for (i = 0; i < gap->ga_len; ++i) - write_affix(fd, (affheader_T *)gap->ga_data + i); + write_affix(wif.wif_fd, (affheader_T *)gap->ga_data + i); } /* Number of bytes used for affix NR depends on affix count. */ - prefm = (prefga->ga_len > 256) ? 2 : 1; - suffm = (suffga->ga_len > 256) ? 2 : 1; + wif.wif_prefm = (prefga->ga_len > 256) ? 2 : 1; + wif.wif_suffm = (suffga->ga_len > 256) ? 2 : 1; /* Write the suggest info. TODO */ - put_bytes(fd, 0L, 4); + put_bytes(wif.wif_fd, 0L, 4); /* * Write the word list. <wordcount> <worditem> ... */ /* number of basic words in 4 bytes */ - put_bytes(fd, newwords->ht_used, 4); /* <wordcount> */ + put_bytes(wif.wif_fd, newwords->ht_used, 4); /* <wordcount> */ /* - * Sort the word list, so that we can reuse as many bytes as possible. + * Sort the word list, so that we can copy as many bytes as possible from + * the previous word. */ wtab = (char_u **)alloc((unsigned)(sizeof(char_u *) * newwords->ht_used)); if (wtab != NULL) @@ -4279,23 +4372,78 @@ write_vim_spell(fname, prefga, suffga, newwords, regcount, regchars) * without VALID flag first (makes it easier to read the list back * in). */ if (bw->bw_flags & BWF_KEEPCAP) - write_bword(fd, bw, TRUE, &prevbw, regionmask, prefm, suffm); - write_bword(fd, bw, FALSE, &prevbw, regionmask, prefm, suffm); + write_bword(&wif, bw, TRUE); + write_bword(&wif, bw, FALSE); /* Write other basic words, with different caps. */ for (i = 0; i < bwga.ga_len; ++i) { bw2 = ((basicword_T **)bwga.ga_data)[i]; if (bw2 != bw) - write_bword(fd, bw2, FALSE, &prevbw, regionmask, - prefm, suffm); + write_bword(&wif, bw2, FALSE); } } ga_clear(&bwga); } - fclose(fd); + fclose(wif.wif_fd); + + /* Print a few statistics. */ + if (wif.wif_addmaxw == NULL) + wif.wif_addmaxw = (char_u *)""; + smsg((char_u *)_("Maximum number of adds on a word: %ld (%s)"), + wif.wif_addmax, wif.wif_addmaxw); + smsg((char_u *)_("Average number of adds on a word: %f"), + (float)wif.wif_acount / (float)wif.wif_wcount); +} + +/* + * Compare two basic words for their <addstring>. + */ +static int +#ifdef __BORLANDC__ +_RTLENTRYF +#endif +bw_compare __ARGS((const void *s1, const void *s2)); + + static int +#ifdef __BORLANDC__ +_RTLENTRYF +#endif +bw_compare(s1, s2) + const void *s1; + const void *s2; +{ + basicword_T *bw1 = *(basicword_T **)s1; + basicword_T *bw2 = *(basicword_T **)s2; + int i = 0; + + /* compare the leadstrings */ + if (bw1->bw_leadstring == NULL) + { + if (bw2->bw_leadstring != NULL) + return 1; + } + else if (bw2->bw_leadstring == NULL) + return -1; + else + i = STRCMP(bw1->bw_leadstring, bw2->bw_leadstring); + + if (i == 0) + { + /* leadstrings are identical, compare the addstrings */ + if (bw1->bw_addstring == NULL) + { + if (bw2->bw_addstring != NULL) + return 1; + } + else if (bw2->bw_addstring == NULL) + return -1; + else + i = STRCMP(bw1->bw_addstring, bw2->bw_addstring); + } + return i; } /* @@ -4309,34 +4457,36 @@ write_vim_spell(fname, prefga, suffga, newwords, regcount, regchars) * [<addcnt> <add> ...] */ static void -write_bword(fd, bwf, lowcap, prevbw, regionmask, prefm, suffm) - FILE *fd; +write_bword(wif, bwf, lowcap) + winfo_T *wif; /* info for writing */ basicword_T *bwf; int lowcap; /* write KEEPKAP word as not-valid */ - basicword_T **prevbw; /* last written basic word */ - int regionmask; /* mask that includes all possible regions */ - int prefm; - int suffm; { + FILE *fd = wif->wif_fd; int flags; int aflags; int len; int leadlen, addlen; + int copylen; int clen; int adds = 0; int i; + int idx; basicword_T *bw, *bw2; + basicword_T **wtab; + int count; + int l; /* Check how many bytes can be copied from the previous word. */ len = STRLEN(bwf->bw_word); - if (*prevbw == NULL) + if (wif->wif_prevbw == NULL) clen = 0; else for (clen = 0; clen < len - && (*prevbw)->bw_word[clen] == bwf->bw_word[clen]; ++clen) + && wif->wif_prevbw->bw_word[clen] == bwf->bw_word[clen]; ++clen) ; putc(clen, fd); /* <nr> */ - *prevbw = bwf; + wif->wif_prevbw = bwf; /* <string> */ if (len > clen) fwrite(bwf->bw_word + clen, (size_t)(len - clen), (size_t)1, fd); @@ -4360,7 +4510,8 @@ write_bword(fd, bwf, lowcap, prevbw, regionmask, prefm, suffm) /* Flags: add the region byte if the word isn't valid in all * regions. */ - if (regionmask != 0 && (bw->bw_region & regionmask) != regionmask) + if (wif->wif_regionmask != 0 && (bw->bw_region & wif->wif_regionmask) + != wif->wif_regionmask) flags |= BWF_REGION; } /* Add the prefix/suffix list if there are prefixes/suffixes. */ @@ -4371,7 +4522,11 @@ write_bword(fd, bwf, lowcap, prevbw, regionmask, prefm, suffm) /* Flags: may have additions. */ if (adds > 0) + { flags |= BWF_ADDS; + if (adds >= 256) + flags |= BWF_ADDS_M; + } /* The dummy word before a KEEPCAP word doesn't have any flags, they are * in the actual word that follows. */ @@ -4403,56 +4558,133 @@ write_bword(fd, bwf, lowcap, prevbw, regionmask, prefm, suffm) /* write prefix and suffix lists: <affixcnt> <affixNR> ... */ if (flags & BWF_PREFIX) - write_affixlist(fd, &bw->bw_prefix, prefm); + write_affixlist(fd, &bw->bw_prefix, wif->wif_prefm); if (flags & BWF_SUFFIX) - write_affixlist(fd, &bw->bw_suffix, suffm); + write_affixlist(fd, &bw->bw_suffix, wif->wif_suffm); if (flags & BWF_REGION) putc(bw->bw_region, fd); /* <region> */ + ++wif->wif_wcount; + /* * Additions. */ if (adds > 0) { - put_bytes(fd, (long_u)adds, 2); /* <addcnt> */ + if (adds >= 256) + put_bytes(fd, (long_u)adds, 2); /* 2 byte <addcnt> */ + else + putc(adds, fd); /* 1 byte <addcnt> */ + /* statistics */ + wif->wif_acount += adds; + if (wif->wif_addmax < adds) + { + wif->wif_addmax = adds; + wif->wif_addmaxw = bw->bw_word; + } + + /* + * Sort the list of additions, so that we can copy as many bytes as + * possible from the previous addstring. + */ + + /* Make a table with pointers to each basic word that has additions. */ + wtab = (basicword_T **)alloc((unsigned)(sizeof(basicword_T *) * adds)); + if (wtab == NULL) + return; + count = 0; for (bw = bwf; bw != NULL; bw = bw->bw_cnext) if (bw->bw_leadstring != NULL || bw->bw_addstring != NULL) + wtab[count++] = bw; + + /* Sort. */ + qsort((void *)wtab, (size_t)count, sizeof(basicword_T *), bw_compare); + + /* Now write each basic word to the spell file. Copy bytes from the + * previous leadstring/addstring if possible. */ + bw2 = NULL; + for (idx = 0; idx < count; ++idx) + { + bw = wtab[idx]; + + /* <add>: <addflags> <addlen> [<leadlen>] [<copylen>] + * [<addstring>] [<region>] */ + copylen = 0; + if (bw->bw_leadstring == NULL) + leadlen = 0; + else { - /* <add>: <addflags> <addlen> [<leadlen> <addstring>] - * [<region>] */ - aflags = 0; - if (bw->bw_flags & BWF_ONECAP) - aflags |= ADD_ONECAP; - if (bw->bw_flags & BWF_ALLCAP) - aflags |= ADD_ALLCAP; - if (bw->bw_flags & BWF_KEEPCAP) - aflags |= ADD_KEEPCAP; - if (regionmask != 0 - && (bw->bw_region & regionmask) != regionmask) - aflags |= ADD_REGION; - putc(aflags, fd); /* <addflags> */ - - if (bw->bw_leadstring == NULL) - leadlen = 0; - else - leadlen = STRLEN(bw->bw_leadstring); - if (bw->bw_addstring == NULL) - addlen = 0; + leadlen = STRLEN(bw->bw_leadstring); + if (bw2 != NULL && bw2->bw_leadstring != NULL) + for ( ; copylen < leadlen; ++copylen) + if (bw->bw_leadstring[copylen] + != bw2->bw_leadstring[copylen]) + break; + } + if (bw->bw_addstring == NULL) + addlen = 0; + else + { + addlen = STRLEN(bw->bw_addstring); + if (bw2 != NULL && copylen == leadlen + && bw2->bw_addstring != NULL) + { + for (i = 0; i < addlen; ++i) + if (bw->bw_addstring[i] != bw2->bw_addstring[i]) + break; + copylen += i; + } + } + + aflags = 0; + /* Only copy bytes when it's more than one, the length itself + * takes an extra byte. */ + if (copylen > 1) + aflags |= ADD_COPYLEN; + else + copylen = 0; + + if (bw->bw_flags & BWF_ONECAP) + aflags |= ADD_ONECAP; + if (bw->bw_flags & BWF_ALLCAP) + aflags |= ADD_ALLCAP; + if (bw->bw_flags & BWF_KEEPCAP) + aflags |= ADD_KEEPCAP; + if (wif->wif_regionmask != 0 && (bw->bw_region + & wif->wif_regionmask) != wif->wif_regionmask) + aflags |= ADD_REGION; + if (leadlen > 0) + aflags |= ADD_LEADLEN; + putc(aflags, fd); /* <addflags> */ + + putc(leadlen + addlen, fd); /* <addlen> */ + if (aflags & ADD_LEADLEN) + putc(leadlen, fd); /* <leadlen> */ + if (aflags & ADD_COPYLEN) + putc(copylen, fd); /* <copylen> */ + + /* <addstring> */ + if (leadlen > copylen && bw->bw_leadstring != NULL) + fwrite(bw->bw_leadstring + copylen, + (size_t)(leadlen - copylen), (size_t)1, fd); + if (leadlen + addlen > copylen && bw->bw_addstring != NULL) + { + if (copylen >= leadlen) + l = copylen - leadlen; else - addlen = STRLEN(bw->bw_addstring); - putc(leadlen + addlen, fd); /* <addlen> */ - putc(leadlen, fd); /* <leadlen> */ - /* <addstring> */ - if (bw->bw_leadstring != NULL) - fwrite(bw->bw_leadstring, (size_t)leadlen, (size_t)1, fd); - if (bw->bw_addstring != NULL) - fwrite(bw->bw_addstring, (size_t)addlen, (size_t)1, fd); - - if (aflags & ADD_REGION) - putc(bw->bw_region, fd); /* <region> */ + l = 0; + fwrite(bw->bw_addstring + l, + (size_t)(addlen - l), (size_t)1, fd); } + + if (aflags & ADD_REGION) + putc(bw->bw_region, fd); /* <region> */ + + bw2 = bw; + } + vim_free(wtab); } } |