From 8a2a22b8a64f7cb580b45446ee209f8f5d1f1cad Mon Sep 17 00:00:00 2001 From: edyfox Date: Wed, 9 Apr 2008 18:19:24 +0000 Subject: [PATCH] Merged from the latest developing branch. git-svn-id: https://vim.svn.sourceforge.net/svnroot/vim/trunk@998 2a77ed30-b011-0410-a7ad-c7884a0aa172 --- src/regexp.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++------- src/spell.c | 19 +++++++++-- src/version.c | 4 +++ 3 files changed, 110 insertions(+), 15 deletions(-) diff --git a/src/regexp.c b/src/regexp.c index 04e068d3..97181b86 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -3039,6 +3039,15 @@ typedef struct } se_u; } save_se_T; +/* used for BEHIND and NOBEHIND matching */ +typedef struct regbehind_S +{ + regsave_T save_after; + regsave_T save_behind; + save_se_T save_start[NSUBEXP]; + save_se_T save_end[NSUBEXP]; +} regbehind_T; + static char_u *reg_getline __ARGS((linenr_T lnum)); static long vim_regexec_both __ARGS((char_u *line, colnr_T col, proftime_T *tm)); static long regtry __ARGS((regprog_T *prog, colnr_T col)); @@ -3046,6 +3055,8 @@ static void cleanup_subexpr __ARGS((void)); #ifdef FEAT_SYN_HL static void cleanup_zsubexpr __ARGS((void)); #endif +static void save_subexpr __ARGS((regbehind_T *bp)); +static void restore_subexpr __ARGS((regbehind_T *bp)); static void reg_nextline __ARGS((void)); static void reg_save __ARGS((regsave_T *save, garray_T *gap)); static void reg_restore __ARGS((regsave_T *save, garray_T *gap)); @@ -3166,19 +3177,12 @@ typedef struct regitem_S save_se_T sesave; regsave_T regsave; } rs_un; /* room for saving reginput */ - short rs_no; /* submatch nr */ + short rs_no; /* submatch nr or BEHIND/NOBEHIND */ } regitem_T; static regitem_T *regstack_push __ARGS((regstate_T state, char_u *scan)); static void regstack_pop __ARGS((char_u **scan)); -/* used for BEHIND and NOBEHIND matching */ -typedef struct regbehind_S -{ - regsave_T save_after; - regsave_T save_behind; -} regbehind_T; - /* used for STAR, PLUS and BRACE_SIMPLE matching */ typedef struct regstar_S { @@ -4888,6 +4892,10 @@ regmatch(scan) status = RA_FAIL; else { + /* Need to save the subexpr to be able to restore them + * when there is a match but we don't use it. */ + save_subexpr(((regbehind_T *)rp) - 1); + rp->rs_no = op; reg_save(&rp->rs_un.regsave, &backpos); /* First try if what follows matches. If it does then we @@ -5118,15 +5126,20 @@ regmatch(scan) reg_restore(&(((regbehind_T *)rp) - 1)->save_after, &backpos); else - /* But we didn't want a match. */ + { + /* But we didn't want a match. Need to restore the + * subexpr, because what follows matched, so they have + * been set. */ status = RA_NOMATCH; + restore_subexpr(((regbehind_T *)rp) - 1); + } regstack_pop(&scan); regstack.ga_len -= sizeof(regbehind_T); } else { - /* No match: Go back one character. May go to previous - * line once. */ + /* No match or a match that doesn't end where we want it: Go + * back one character. May go to previous line once. */ no = OK; if (REG_MULTI) { @@ -5160,6 +5173,13 @@ regmatch(scan) /* Advanced, prepare for finding match again. */ reg_restore(&rp->rs_un.regsave, &backpos); scan = OPERAND(rp->rs_scan); + if (status == RA_MATCH) + { + /* We did match, so subexpr may have been changed, + * need to restore them for the next try. */ + status = RA_NOMATCH; + restore_subexpr(((regbehind_T *)rp) - 1); + } } else { @@ -5172,7 +5192,16 @@ regmatch(scan) status = RA_MATCH; } else - status = RA_NOMATCH; + { + /* We do want a proper match. Need to restore the + * subexpr if we had a match, because they may have + * been set. */ + if (status == RA_MATCH) + { + status = RA_NOMATCH; + restore_subexpr(((regbehind_T *)rp) - 1); + } + } regstack_pop(&scan); regstack.ga_len -= sizeof(regbehind_T); } @@ -5820,6 +5849,55 @@ cleanup_zsubexpr() #endif /* + * Save the current subexpr to "bp", so that they can be restored + * later by restore_subexpr(). + */ + static void +save_subexpr(bp) + regbehind_T *bp; +{ + int i; + + for (i = 0; i < NSUBEXP; ++i) + { + if (REG_MULTI) + { + bp->save_start[i].se_u.pos = reg_startpos[i]; + bp->save_end[i].se_u.pos = reg_endpos[i]; + } + else + { + bp->save_start[i].se_u.ptr = reg_startp[i]; + bp->save_end[i].se_u.ptr = reg_endp[i]; + } + } +} + +/* + * Restore the subexpr from "bp". + */ + static void +restore_subexpr(bp) + regbehind_T *bp; +{ + int i; + + for (i = 0; i < NSUBEXP; ++i) + { + if (REG_MULTI) + { + reg_startpos[i] = bp->save_start[i].se_u.pos; + reg_endpos[i] = bp->save_end[i].se_u.pos; + } + else + { + reg_startp[i] = bp->save_start[i].se_u.ptr; + reg_endp[i] = bp->save_end[i].se_u.ptr; + } + } +} + +/* * Advance reglnum, regline and reginput to the next line. */ static void diff --git a/src/spell.c b/src/spell.c index 567c6cd3..22630b54 100644 --- a/src/spell.c +++ b/src/spell.c @@ -753,6 +753,7 @@ static int set_spell_finish __ARGS((spelltab_T *new_st)); static int spell_iswordp __ARGS((char_u *p, buf_T *buf)); static int spell_iswordp_nmw __ARGS((char_u *p)); #ifdef FEAT_MBYTE +static int spell_mb_isword_class __ARGS((int cl)); static int spell_iswordp_w __ARGS((int *p, buf_T *buf)); #endif static int write_spell_prefcond __ARGS((FILE *fd, garray_T *gap)); @@ -9789,7 +9790,7 @@ spell_iswordp(p, buf) c = mb_ptr2char(s); if (c > 255) - return mb_get_class(s) >= 2; + return spell_mb_isword_class(mb_get_class(s)); return spelltab.st_isw[c]; } #endif @@ -9812,7 +9813,7 @@ spell_iswordp_nmw(p) { c = mb_ptr2char(p); if (c > 255) - return mb_get_class(p) >= 2; + return spell_mb_isword_class(mb_get_class(p)); return spelltab.st_isw[c]; } #endif @@ -9821,6 +9822,18 @@ spell_iswordp_nmw(p) #ifdef FEAT_MBYTE /* + * Return TRUE if word class indicates a word character. + * Only for characters above 255. + * Unicode subscript and superscript are not considered word characters. + */ + static int +spell_mb_isword_class(cl) + int cl; +{ + return cl >= 2 && cl != 0x2070 && cl != 0x2080; +} + +/* * Return TRUE if "p" points to a word character. * Wide version of spell_iswordp(). */ @@ -9841,7 +9854,7 @@ spell_iswordp_w(p, buf) if (*s > 255) { if (enc_utf8) - return utf_class(*s) >= 2; + return spell_mb_isword_class(utf_class(*s)); if (enc_dbcs) return dbcs_class((unsigned)*s >> 8, *s & 0xff) >= 2; return 0; diff --git a/src/version.c b/src/version.c index ee03f3c8..341d6611 100644 --- a/src/version.c +++ b/src/version.c @@ -667,6 +667,10 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 293, +/**/ + 292, +/**/ 291, /**/ 290, -- 2.11.4.GIT